【问题标题】:Getting no values or garbage values on the client-side (TCP Socket Programming in C)在客户端不获取任何值或垃圾值(C 中的 TCP 套接字编程)
【发布时间】:2020-04-30 13:21:36
【问题描述】:

我是套接字编程的初学者,我正在尝试开发一个简单的程序,客户端向服务器发送一个数字,服务器计算相同的阶乘并将其发送回客户端,客户端打印它.

服务器端的计算工作正常,但客户端要么不显示结果,要么打印一个垃圾值。

这背后的原因是什么?

客户端代码:

#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

【问题讨论】:

  • 首先,在客户端检查recv 的返回值。 TCP 是一种流协议。无法保证任何给定的recv 呼叫都会收到发件人发送的所有内容。需要循环直到收到所有“预期”数据。在这种情况下,直到收到完整的字符串(即 NUL 终止符)。可能无法解决您的问题,但值得一试的正确做法。

标签: c sockets tcp server client


【解决方案1】:

您的服务器正在发送回一个 90 字节的缓冲区,而您的客户端正在读取一个 50 字节的缓冲区。这意味着客户端首先读取以预期字符串开头的 50 个字节。然后在下一次调用recv 时读取来自同一消息的接下来的 40 个字节,其中很可能包含垃圾。此调用可能还包含末尾 next 消息的前 10 个字节。

对此最简单的解决方法是将两个 send 调用更改为发送strlen(buf)+1 字节而不是sizeof(buf) 字节,这样您就可以发送所需的数据。

【讨论】:

  • 这解决了问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2012-03-29
  • 2013-10-24
  • 2021-08-05
相关资源
最近更新 更多