Search code examples
csocketstcpserverclient

Getting no values or garbage values on the client-side (TCP Socket Programming in C)


I am a beginner at socket programming and I am trying to develop a simple program with the client sending a number to the server, the server computing the factorial of the same and sending it back to the client, and the client printing it.

The computation at the server-side works fine but the client-side either displays no result or prints a garbage value.

What could be the reason behind this?

Client Side Code:

#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#define MAXSIZE 50


main()
{
   int sockfd,retval;
   int recedbytes,sentbytes;
   struct sockaddr_in serveraddr;
   char buff[MAXSIZE];
   sockfd=socket(AF_INET,SOCK_STREAM,0);
   if(sockfd==-1)
   {
       printf("\nSocket Creation Error");

   }
//printf("%i",sockfd);
   serveraddr.sin_family=AF_INET;
   serveraddr.sin_port=htons(3388);
   serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
   retval=connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
   if(retval==-1)
   {
       printf("Connection error");

   }
   while(1)
   {
       printf("Enter the Number: \n");

       scanf("%s",buff);

       sentbytes=send(sockfd,buff,sizeof(buff),0);

       if(sentbytes==-1)
       {
           printf("!!");
           close(sockfd);
       }

       int num=atoi(buff);

       if(num==-1 || num==0)
       {
           break;
       }
       strcpy(buff,"");

       recedbytes=recv(sockfd,buff,sizeof(buff),0);
       printf("The factorial is: ");
       puts(buff);
       printf("\n");
   }
   close(sockfd);
}

Server Side Code:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#define MAXSIZE 90

main()
{
    int sockfd,newsockfd,retval;
    socklen_t actuallen;
    int recedbytes,sentbytes;
    struct sockaddr_in serveraddr,clientaddr;

    char buff[MAXSIZE];
    int a=0;
    sockfd=socket(AF_INET,SOCK_STREAM,0);

    if(sockfd==-1)
    {
        printf("\nSocket creation error");
    }

    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(3388);
    serveraddr.sin_addr.s_addr=htons(INADDR_ANY);
    retval=bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
    if(retval==1)
    {
        printf("Binding error");
        close(sockfd);
    }

    retval=listen(sockfd,1);
    if(retval==-1)
    {
        close(sockfd);
    }

    actuallen=sizeof(clientaddr);
    newsockfd=accept(sockfd,(struct sockaddr*)&clientaddr,&actuallen);


    if(newsockfd==-1)
    {
        close(sockfd);
    }

    while(1)
    {
        // printf("comes here");
        strcpy(buff,"");
        recedbytes=recv(newsockfd,buff,sizeof(buff),0);


        if(recedbytes==0)
            { continue;}

        if(recedbytes==-1)
        {
            close(sockfd);
            close(newsockfd);
        }

        int num=atoi(buff);

        if(num==-1)
        {
            break;
        }


        int res=1;
        int i;
        for(i=1;i<=num;i++)
        {
            res=res*i;
        }
        // printf("hello");


        sprintf(buff, "%d", res);
        printf("The factorial of %i = %s\n",num,buff);
        sentbytes=send(newsockfd,buff,sizeof(buff),0);

        if(sentbytes==-1)
        {
            close(sockfd);
            close(newsockfd);
        }


    }
    close(sockfd);
    close(newsockfd);
}

Sample Output:

Client-Side:

Enter the Number: 
6
The factorial is: 720
Enter the Number: 
2
The factorial is: 
Enter the Number: 
4
The factorial is: 2
Enter the Number: 
7
The factorial is: 
Enter the Number: 
2
The factorial is: /V
Enter the Number: 
5
The factorial is: /V
Enter the Number:

Server-Side:

The factorial of 6 = 720
The factorial of 2 = 2
The factorial of 4 = 24
The factorial of 7 = 5040
The factorial of 2 = 2
The factorial of 5 = 120

Solution

  • Your server is sending back a 90 byte buffer while your client is reading into a 50 byte buffer. This means that the client first reads 50 bytes which starts with the expected string. Then on the next call to recv the next 40 bytes from the same message are read which most likely contain garbage. This call probably also contains the first 10 bytes of the next message at the end.

    The simplest fix for this is to change both send calls to send strlen(buf)+1 bytes instead of sizeof(buf) bytes so you're only sending exactly as much data as you need.