Получение значений или мусора на стороне клиента (программирование сокетов TCP в C) - PullRequest
0 голосов
/ 13 января 2020

Я новичок в программировании сокетов и пытаюсь разработать простую программу, в которой клиент отправляет число на сервер, сервер вычисляет факториал и отправляет его обратно клиенту, а клиент печатает его .

Вычисления на стороне сервера работают нормально, но на стороне клиента либо не отображаются результаты, либо выводится мусорное значение.

В чем может быть причина этого?

Код на стороне клиента:

#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);
}

Код на стороне сервера:


#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);
}

Пример вывода:

На стороне клиента:

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:

На стороне сервера:

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

1 Ответ

2 голосов
/ 13 января 2020

Ваш сервер отправляет обратно 90-байтовый буфер, пока ваш клиент читает в 50-байтовый буфер. Это означает, что клиент сначала читает 50 байтов, которые начинаются с ожидаемой строки. Затем при следующем вызове recv считываются следующие 40 байтов из того же сообщения, которые, скорее всего, содержат мусор. Этот вызов, вероятно, также содержит первые 10 байтов сообщения next в конце.

Самое простое решение для этого заключается в изменении обоих send вызовов для отправки strlen(buf)+1 байтов вместо sizeof(buf) байтов, поэтому вы отправляете столько данных, сколько вам нужно.

...