Search code examples
csocketswinsockwinsock2

Server cannot receive the clients message in c winsock programming


Hello Friends I am a newbie to socket programming in c.I read a few tutorials in the net and started working.The programs below are my socket client and server programs using winsock2 library in WINDOWS.

Whenever i run the program, there is no error until the server accepts the clients connection.But after the client sends the message the server cannot receive the message. The WSAGetLastError() function returns the error code as 10038.I tried changing the port, increasing and decreasing the message size. help me friends.

Server code

#include<stdio.h>
#include<conio.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsa;
int r;
char buf[4];
WSAStartup(MAKEWORD(2,2),&wsa);

SOCKET s= socket(AF_INET,SOCK_STREAM,0);

if ( s==INVALID_SOCKET)
{
    printf("\n failed to create socket error code : %d ",WSAGetLastError());
    WSACleanup();
    return 1;
}

sockaddr_in sin,cl;
sin.sin_family=AF_INET;
sin.sin_port=htons(80);
sin.sin_addr.s_addr=INADDR_ANY;

if(bind (s,(sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)
{
    printf("\nSocket not Bound\n");
    WSACleanup(); 
    return 1;
}

r=listen(s,2);
if(r==SOCKET_ERROR)
{
    printf("\nListening Failed\n");
    WSACleanup();
    return 1;
}
printf("\n Listening\n");

SOCKET client;
r= sizeof(sockaddr_in);
printf("\n Ready to accept");
while (client=accept(s,(sockaddr *)&cl,&r)!= INVALID_SOCKET)
{
printf("\nNew client found\n\n");
if(client == SOCKET_ERROR)
{
    printf("\nError connecting client error code : %d ",WSAGetLastError());
    WSACleanup();
    return 1;
}

r=recv(client,buf,4,0);
if(r==SOCKET_ERROR)
{
    printf("\nSocket not connected error code : %d",WSAGetLastError());
    WSACleanup();
    return 1;
}

printf("%s\n",buf);
}
getchar();
return 0;
}

Client code

#include <stdio.h>
#include <conio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{

WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
int r;
char *buf="data";

SOCKET t=socket(AF_INET,SOCK_STREAM,0);
if(t==SOCKET_ERROR)
{
    printf("\nFailed socket error code : %d ",WSAGetLastError());
    WSACleanup();
    return 1;
}

sockaddr_in server;
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr("192.168.0.142");
server.sin_port=htons(80);

printf("\nConnecting\n");
r=connect(t,(sockaddr *)&server,sizeof(server));
if(r==SOCKET_ERROR)
{
    printf("\nFailed to connect error code : %d ",WSAGetLastError());
    WSACleanup();
    return 1;
}
printf("\n connected\n");
 
 printf("\nSending data\n");
 r=send(t,buf,strlen(buf),0);
 if (r==SOCKET_ERROR)
 {
     printf("\nFailed to connect error code : %d ",WSAGetLastError());
     WSACleanup();
     return 1;
 }
 printf("\n Data sent\n");
return 0;
}

Solution

  • First we look up what 10038 means.

    SAENOTSOCK
    10038 (0x2736)
    An operation was attempted on something that is not a socket.
    

    OK, so you think you have a socket, but you really don't in one of your calls. You weren't very specific on which WSAGetLastError() function was returning 10038, but I'm going to guess the call after this one:

    while (client=accept(s,(sockaddr *)&cl,&r)!= INVALID_SOCKET)
    

    In C, the != is handled first, and then the assignment. So you end up with the socket returned by accept being compared to INVALID_SOCKET, and then that boolean value being assigned to client. You want the socket to be assigned and then compared, so you should use parentheses around the assignment:

    while ((client = accept(s,(sockaddr *)&cl,&r)) != INVALID_SOCKET)
    

    Also, socket() returns INVALID_SOCKET and not SOCKET_ERROR, although confusing the two won't cause a problem by coincidence.

    Further, you need to null-terminate the string on the receiver side if you are going to print it.

    char buf[5];  /* 4 characters + 1 null-terminator */
    ...
    buf[sizeof(buf) - 1] = '\0';    /* enforce that the buffer is always null terminated regardless of what the sender sends. */