trying to talk to email server via SMTP with c program - c

I'm trying to create a little C program that allow me to talk to mail server via smtp, I created this little program:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "25"
#define DEFAULT_ADDRESS "smtp.live.com"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char messaggio[100];
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
while(1){// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(DEFAULT_ADDRESS, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
printf("messaggio: ");
gets(messaggio);
fflush(stdin);
printf("%s\n", messaggio);
// Send an initial buffer
iResult = send( ConnectSocket, messaggio, (int)strlen(messaggio), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
// do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 ){
printf("Bytes received: %d\n", iResult);
printf("messaggio: %s\n", recvbuf);}
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
// } while( iResult > 0 );
// cleanu
closesocket(ConnectSocket);
WSACleanup();
}
system("PAUSE");
return 0;
}
When I launch it, it does connect to the smtp server, then send the message (for example Hello message) and receive 220 reply code meaning that the services is ready. When I continue typing command it does continue to send me 220 code without going forward, and when I miss type a command it just crush.
may any of you please help me?
p.s. I take no credit for code, I just modified some socket client documentation of microsoft to talk to smtp.live.com and apparently it does work...
[EDIT] x2:
ok, thanks to Remy Lebeau i apparently managed to resolve those problem, hope this is the last one.
edited code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "25"
#define DEFAULT_ADDRESS "smtp.live.com"
int __cdecl main(int argc, char **argv){
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char messaggio[100];
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
int success = 1;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); // Initialize Winsock
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(DEFAULT_ADDRESS, DEFAULT_PORT, &hints, &result); // Resolve the server address and port
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { // Attempt to connect to an address until one succeeds
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); //Connect to server.
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
while(success){
printf("messaggio: ");
scanf(" %[^\n]", messaggio);
printf("%s\n", messaggio);
iResult = send( ConnectSocket, strcat(messaggio,"\r\n"), (int)strlen(messaggio)+2, 0 ); //Send an initial buffer
if (iResult < 0 || iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
system("PAUSE");
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
do{ //riceve tutto il possibile dal server
iResult = recv(ConnectSocket, recvbuf, recvbuflen-1, 0);
recvbuf[iResult]='\0';
if ( iResult > 0 ){
printf("Bytes received: %d\n", iResult);
printf("messaggio: %s\n", recvbuf);
}
else{
printf("recv failed with error: %d\n", WSAGetLastError());
success=0;
}
}while(recvbuf[iResult-3]=='\r'&& recvbuf[iResult-2]=='\n');
printf("stop receive\n");
}
iResult = shutdown(ConnectSocket, SD_SEND);
closesocket(ConnectSocket);
WSACleanup();
system("PAUSE");
return 0;
}
Now it does take my command and it does respond, i do helo, mail from: <mail> and to: <mail> and at this point it says: "530 (code for auth problem) Must issue a STARTTLS command first.
Is there a way to resolve this? i've to encode my sended command, is there a way to do this with winsock?
Did i almost got the point of the problem or it isn't this the problem?

Your code logic is incomplete for an SMTP client.
TCP is a byte stream. There is no guarantee that you will be able to send an entire command in a single send() call, or that you will be able to receive an entire response in a single recv() call. You have to keep sending until you have nothing left to send, and you have to keep reading until there is nothing more to read. Which, in the case of SMTP, means when you encounter the \r\n that terminates each line.
Once you have your underlying socket I/O working, you are still not implementing the actual SMTP protocol. You are just throwing arbitrary data at the server and reading whatever arbitrary data it returns. SMTP has rules that you need to take into account. For example, an SMTP server sends a greeting before accepting commands. You are not reading that greeting. Also, an SMTP response may have 1 or more lines, so you have to parse each line individually (the format is outlined in RFC 5321) to discover how many lines need to be read. Keep reading until you encounter the last line of a response. Don't send the next command until the previous response has been fully read (unless you want to implement SMTP pipelining, which I won't get into here).
As for the "Must issue a STARTTLS command first" error, that is pretty self-explanatory. You sent an SMTP command over an unsecure connection, but the server wants that command to be sent over a secure connection instead (such as when sending an AUTH command containing authentication credentials in plain text). The STARTTLS command is used to activate a new SSL/TLS session to secure a connection that is currently unsecure.
You can use libraries like OpenSSL, or APIs like Microsoft's SChannel, to implement the actual SSL/TLS on top of your socket. That is outside the scope of this question. If you want help with implementing SSL/TLS, there are plenty of books and tutorials on that subject.
With all of that said, try something more like this instead:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#pragma command(lib, "mswsock.lib")
//#pragma command(lib, "advapi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "25"
#define DEFAULT_ADDRESS "smtp.live.com"
char *recvbuf = NULL;
int recvbuflen = 0;
int recvbufused = 0;
int sendData(SOCKET s, char *buffer, int buflen)
{
int iResult;
while (buflen > 0)
{
// TODO: if the connection is secure, encrypt the data being sent...
iResult = send(s, buffer, buflen, 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
return -1;
}
buffer += iResult;
buflen -= iResult;
}
return 0;
}
int sendLine(SOCKET s, char *line)
{
int iResult = sendData(s, line, strlen(line));
if (iResult == 0)
iResult = sendData(s, "\r\n", 2);
return iResult;
}
int readLine(SOCKET s, char **line)
{
char buf[DEFAULT_BUFLEN];
int iResult;
int offset = 0, len, total;
char *p;
*line = NULL;
do
{
// check if the line terminator is already in the buffer
p = memchr(recvbuf+offset, '\n', recvbufused-offset);
if (p != NULL)
{
++p;
total = (p - recvbuf);
// check if the line terminator is actually "\r\n"
len = total - 1;
if ((len > 0) && (recvbuf[len-1] == '\r'))
--len;
// extract the line and remove it from the buffer
*line = malloc(len+1);
if (*line == NULL)
{
printf("Unable to allocate memory! Bytes: %d\n", len+1);
return -1;
}
memcpy(*line, recvbuf, len);
(*line)[len] = 0;
memmove(recvbuf, recvbuf+total, recvbufused-total);
recvbufused -= total;
printf("%s\n", *line);
return len;
}
// line terminator is not in the buffer, keep reading
// do not search the buffer that was already searched
offset = recvbufused;
// read more data from the socket
iResult = recv(s, buf, sizeof(buf), 0);
if (iResult <= 0)
{
if (iResult == 0)
printf("server closed the connection\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
break;
}
// TODO: if the connection is secure, decrypt the data that was received...
// if the buffer is too small for the new data, grow it
if ((recvbufused+iResult) > recvbuflen)
{
len = (recvbufused+iResult) + DEFAULT_BUFLEN;
p = realloc(recvbuf, len);
if (p == NULL)
{
printf("Unable to allocate memory! Bytes: %d\n", len);
break;
}
recvbuf = p;
recvbuflen = len;
}
// now add the data to the buffer
memcpy(recvbuf+recvbufused, buf, iResult);
recvbufused += iResult;
}
while (1);
return -1;
}
int readResponse(SOCKET s)
{
char *line, term[5];
int len, code = 0;
// read the first line
len = readLine(s, &line);
if (len == -1)
return -1;
// check if the response has multiple lines
if ((len > 3) && (line[3] == '-'))
{
// keep reading until the last line is received
memcpy(term, line, 3);
term[3] = ' ';
term[4] = '\0';
do
{
free(line);
len = readLine(s, &line);
if (len == -1)
return -1;
}
while ((len > 3) && (strncmp(line, term, 4) != 0));
}
// now extract the response code and return it
if (len > 3) line[3] = '\0';
code = strtol(line, NULL, 10);
free(line);
if (code == 0)
return -1;
return code;
}
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo hints, *result, *ptr;
char messaggio[100];
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(DEFAULT_ADDRESS, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL; ptr=ptr->ai_next)
{
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
break;
}
//Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, ptr->ai_addrlen);
if (iResult == 0)
break;
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
printf("Connected to server\n");
// read the greeting
iResult = readResponse(ConnectSocket);
if (iResult == 220)
{
do
{
// ask the user for a command
printf("messaggio: ");
if (!fgets(messaggio, sizeof(messaggio), stdin))
break;
// remove the line terminator if present
iResult = strlen(messaggio);
if ((iResult > 0) && (messaggio[iResult-1] == '\n'))
messaggio[iResult-1] = '\0';
// send the command
iResult = sendLine(ConnectSocket, messaggio);
if (iResult == -1)
break;
// read the response
iResult = readResponse(ConnectSocket);
if (iResult == -1)
break;
// need to stop now?
if (strcmp(messaggio, "QUIT") == 0)
break;
// need to turn on SSL/TLS now?
if ((strcmp(messaggio, "STARTTLS") == 0) && (iResult == 220))
{
// TODO: activate SSL/TLS, stop if failed...
}
}
while(1);
}
shutdown(ConnectSocket, SD_SEND);
do
{
iResult = recv(ConnectSocket, messaggio, sizeof(messaggio), 0);
}
while (iResult > 0);
closesocket(ConnectSocket);
WSACleanup();
free(recvbuf);
system("PAUSE");
return 0;
}

Related

How to send something to the server?

I was given this code and my task is to send something to the server using the console and read it in it.
Maybe someone knows how to do it for me or maybe give me a hint where to start.
Because we were given the source code but how to work with it and what to do next, we were not told anything
Maybe someone already has experience in this and can help
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <conio.h>
#include <string.h>
#pragma comment (lib, "Ws2_32.lib")
int main() {
WSADATA wsaData;
int iResult;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL, *ptr = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo("147.175.115.34", "777", &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
} else
printf("getaddrinfo did not fail...\n");
SOCKET ConnectSocket = INVALID_SOCKET;
ptr = result;
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
} else
printf("Any error occured...\n");
iResult = connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
printf("Not connected to server...\n");
else
printf("Connected to server!\n");
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
WSACleanup();
return 1;
}
Sleep(250);
char sendbuf[4096];
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
#define DEFAULT_BUFLEN 4096
int recvbuflen = DEFAULT_BUFLEN;
char recvbuf[DEFAULT_BUFLEN];
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
}
well you need to put something in 'sendbuf' before the send call.
like say
strcpy(sndbuf, "Hello Server");
BTW the receive code is totally wrong. You must loop on the receive until you have received all the data

winsock client repeatedly try to connect to server

I'm learning winsock programming. I have a question about the code provided in msdn: https://learn.microsoft.com/en-us/windows/desktop/winsock/complete-client-code
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Why the client have to use a loop with socket() and connect(), the Linux version of the program doesn't need it. Can I remove it? or is it implementation-dependency ?
Such a loop is common when using getaddrinfo (even on Linux).
The getaddrinfo function can return a list with multiple possible remote addresses, or multiple address families, or multiple protocols. The loop tries all of the addresses in the list until it successfully connects.

Winsock recv() blocks but exits after an interval

This question has been asked before here
Winsock recv() does not block and
here C++ Winsock recv not blocking and I have gone through the solutions but of no avail.
My scenario is as follows:
I have setup a LWIP server in VC707 FPGA kit and windows client on my PC. Client sends some data to the server and then goes into an infinite while loop where it waits to recv() data from the server.
The server on the other hand, receives data from the client, calls a data processing operation and then sends back the data.
The issue I am facing here is that after the server receives the data, it takes about 1 minute for the process to be complete and post that it will send the data. However, the recv() function on the client side, waits for the data for about 30-35s (clocked by watch) and then returns -1 and socket error 10057 and in earlier case 10060, which means that the connection has been terminated.
Please let me know where and what I am doing wrong.
client.c:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib")
#define DEFAULT_PORT "9881"
#define DEFAULT_BUFLEN 1460
//#define DEFAULT_BUFLEN 2048
#define DEFAULT_RECV_LEN 2048
#define server_addr "192.168.1.10"
FILE *fid, *fdr;
int main(int argc, char *argv[]) {
int iResult, recvbuflen = DEFAULT_RECV_LEN, file_pos = 0;
int bytesRead=0, i=0;
unsigned char sendbuf[DEFAULT_BUFLEN]={NULL}, recvbuf[DEFAULT_RECV_LEN]={NULL};
char filename[256];
WSADATA wsaData;
struct addrinfo *result = NULL,*ptr = NULL,hints;
SOCKET ConnectSocket = INVALID_SOCKET;
int j, iter=0;
unsigned total_bytes_rx = 0,data_tx_cnt = 0,data_tx_pack_cnt=0;
unsigned uiNoBytes2Send = 1024;
unsigned uiNoPackets2Send = 10;
printf("enter file to transfer: \n");
scanf("%s", filename);
printf("Enter number of packets to send (packet size : 1460):");
scanf("%u",&uiNoPackets2Send);
fid=fopen(filename,"rb");
fdr=fopen("D:\\Saravana\\UMA\\DataFiles\\recvfile.bin","wb");
//fclose(fdr);
//fdr=fopen("recvfile.txt","w");
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
getch();return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(server_addr, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
getch();return 1;
}
ptr=result;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
getch();return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
getch();return 1;
}
//bytesRead=fread(&sendbuf[4],1,DEFAULT_BUFLEN,fid);
printf("****** Data Sending Initiated ******\n");
printf("\n **** Sending control packet ****");
sendbuf[0]='c'; sendbuf[1]='t'; sendbuf[2]='r'; sendbuf[3]='l'; //Control string
sendbuf[4] = 0xC2; sendbuf[5] = 0x00; sendbuf[6] = 0x00; sendbuf[7] = 0x00; //SDRAM Address
//#Bytes to transfer
sendbuf[8] = (uiNoPackets2Send&0xFF000000)>>24;
sendbuf[9] = (uiNoPackets2Send&0x00FF0000)>>16;
sendbuf[10] = (uiNoPackets2Send&0x0000FF00)>>8;
sendbuf[11] = (uiNoPackets2Send&0x000000FF);
printf("\n Send buf[11] : %u",sendbuf[11]);
//iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}
else
{
printf("\n Control packet sent successfully");
}
printf("\n Starting Data packet transfer ..");
printf("\n");
while(data_tx_pack_cnt<uiNoPackets2Send)
{
bytesRead=fread(&sendbuf[0],1,DEFAULT_BUFLEN,fid);
if(bytesRead<DEFAULT_BUFLEN)
break;
//iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}
data_tx_cnt += iResult;
data_tx_pack_cnt++;
printf("\r Current Bytes sent : %u \t Current packet cnt : %u ",iResult,data_tx_pack_cnt);
}
printf("\n Total bytes transferred: %u\n",data_tx_cnt);
strcpy(sendbuf,"term");
iResult = send(ConnectSocket, sendbuf, 1460, 0) ;
if(iResult <0)
{
puts("Send failed\n");
return 1;
}else
printf("\n Control Packet sent to indicate data transfer is complete\n");
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}*/
printf("****** Switching to data receive mode ******\n");
//Receive until the server closes the connection
while(1) {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
printf("iResult: %d\n",iResult);
if ( iResult > 0 )
{
if ( recvbuf[iResult-5]=='m' && recvbuf[iResult-4]=='s' && recvbuf[iResult-3]=='d' &&
recvbuf[iResult-2]=='p' && recvbuf[iResult-1]=='d')
{
//fwrite(recvbuf,sizeof(char),iResult-5,fdr);
printf("Connection terminated\n");
break;
}
fwrite(recvbuf,sizeof(char),iResult,fdr);
//if(total_bytes_rx%(1024*1024)== 0)
total_bytes_rx +=iResult;
printf("\rBytes received: Global %u \t Local : %u", total_bytes_rx,iResult);
//printf("Bytes received: Local : %u\n",iResult);
//fclose(fdr);
}else{
printf("recv failed: %d\n Closing all Open Sockets\n", WSAGetLastError());
break;
}
} //while( iResult > 0 );
end_pgm:
fclose(fid);
fclose(fdr);
closesocket(ConnectSocket);
WSACleanup();
printf("Total Bytes received: %d\n", total_bytes_rx);
getch();
}

pass a value from char array to BoS function in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm still struggling with my program that should print out characters in board of symbols.
The compiler says:
char parameter is not compatible with type char*
Here is my code:
char characters[12] = {"ABCDEFGHIJ\0"};
char numbers[12] = {"0123456789\0"};
for (int vertical = 2; vertical<12; vertical++) {
for (int horizontal = 1; horizontal<2; horizontal++) {
text2(horizontal, vertical, numbers[horizontal]);
color2(horizontal, vertical, BLUE);
}
}
for (int abc = 170; abc < 180; abc++) {
color(abc, BLUE);
text(abc, characters[abc]);
}
It should actually print out only one character per pass.
here are both functions
void color2(int i, int j, int f) {
sprintf_s(nachricht, ">># %d %d 0x%x\n", i, j, f);
sendMessage( nachricht );
void text2(int i, int j, char* f) {
sprintf_s(nachricht, ">>#T %d %d %s\n", i, j, f);
sendMessage( nachricht );
}
color2 colors the fields and text2 shows charachters on fields
and here is the code of function sendMessage which is included in both mentioned functions
int sendMessage(char *sendbuf ) {
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
char recvbuf[DEFAULT_BUFLEN];
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
if( verbose ) printf("socket connected\n");
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
terminate("Unable to connect to server!\n");
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
if( verbose ) printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
answer[0] = '\0';
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 ) {
recvbuf[iResult] = '\0';
if( verbose ) printf("Bytes received: %d %s\n", iResult, recvbuf);
strcat_s( answer, recvbuf );
//printf(">>>%s<<<\n", answer );
} else if ( iResult == 0 ) {
if( verbose ) printf("Connection closed\n");
} else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
You need to dereference your pointer. Presumably in one of the functions you are calling, probably in text2() or text(). Can't tell you more without knowing more about the specifications of the functions.

recv() - Working with HTTP headers

Below is the code, I took from MSDN's tutorial examples for Winsock server programming. The code seems to be working fine. When I type http://localhost:27015 in my browser, the code responds appropriately. However, I am unable to work with the string sent by the browser as request and stored here as character array in recvbuf. For example, I am not able to printf the buffer or use fwrite either. The program terminates immediately. Please help.
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(void)
{
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET,
ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
hints;
char recvbuf[DEFAULT_BUFLEN];
char *sendbuf = "HTTP/1.1 200 OK \r\n Date: Fri, 31 Dec 1999 23:59:59 GMT \r\n Content- Type: text/html\r\n";
int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
else
printf("\nInitialising winsock...done");
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
else
printf("\nResolving server address...done");
//localhost:27015/
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
else
printf("\nCreating connection socket...done");
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
printf("\nCreating listening socket...done");
printf("\nWaiting for connection... ");
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do
{
iResult = recv(ClientSocket, recvbuf, recvbuflen,0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket,sendbuf,(int)strlen(sendbuf), 0 );
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}while(iResult>0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
//Appended later
printf("\n");
int i =0;
while(i<120)
{
printf("%c",recvbuf[i]);
++i;
}
return 0;
}
Thanks!
iResult = recv(ClientSocket, recvbuf, recvbuflen,0);
In the above, the data received through recv() is not zero-terminated. iResult is the length of the data, to output it as text:
printf("%.*s", iResult, recvbuf);
Adding the following function helped. The hint was already provided by Maxim when he said
data received through recv() is not
zero-terminated.
void handleBuffer()
{
recvbuf[DEFAULT_BUFLEN-1]='\0';
printf("*********************\n");
printf("%s",recvbuf);
}
I also increased my DEFAULT_BUFLEN to 4096. Call the function to print the output anytime.

Resources