我正在处理正在建立的tcp连接上的问题。当从客户端向服务器发送数据时,服务器似乎在“等待”(对我而言并不那么明显)另一个“ recv()”,并且客户端从不退出,因为它已经完成了发送部分并等待到“ recv( )”来自服务器的答案。这就陷入了僵局。

我认为以下代码是问题所在。

服务器代码:

  #define BUFFSIZE 1024;
  char buffer[BUFFSIZE];
  /*...*/
  bzero(buffer,BUFFSIZE);
  while(received > 0) {     /* indicates end of connection */

      /* recv: Check for more data coming from client*/
          printf("before recv\n");
      if( (received = recv(sock,buffer,BUFFSIZE-1,0) ) < 0){
        perror("Failed to recv bytes from client");
        exit(1);
      }
      printf("received %d bytes \n", received);
      sum_bytes += received;

      printf("after recv\n");
      if( strstr(buffer,"End")) {
        printf("strstr: %s\n",buffer);
        break;
      }
      bzero(buffer,BUFFSIZE);
}
printf("\ntotal bytes received are %d \n", sum_bytes);


客户代码:

for(i=0; i<num_packets; i++){

          /* Send the packet to the server */
          char packet[packet_size];
          bzero(packet,packet_size);
          if( (sent = send(sockfd,packet,packet_size,0)) != packet_size){
              perror("Client: send() sent a diff num of bytes than expected");
              exit(1);
          }
          bytes += sent;
    }
    /* send another final packet("End")in order to inform server that sending is over */
    if( (sent = send(sockfd,"End",3, 0)) != 3) {
          perror("Client:send() sent a diff num of bytes than expected");
    }
    bytes += sent;
    printf("total bytes sent are %d \n", bytes);


}

如您所见,我不介意发送数据,而只关心数据包的大小。
此代码非常适合发送1个数据包...但不适用于更多! :/
如果要发送的数据包多于一个,则客户端“阻塞”(需要^ C退出),并且服务器在收到所有数据后在循环开始时停止(他又进行了一个循环!) 。

我还有一个查询,就是如果我使用'sizeof(BUFFSIZE)'而不是'BUFFSIZE',则相同的精确代码也可以正常工作。我想知道为什么...:/有任何想法吗?

例如./client:


END
total bytes sent are 1034
/* press ^C */



。/服务器:


  接收前
  收到358个字节
  接收后
  接收前
  收到676个字节
   接收后
  bef recv / *卡在这里* /
  
  (...当我在客户端上按ctr-c时出现以下情况...)
  收到0个字节
  接收后
  
  接收到的总字节数为1034 / **接收到的正确字节数! ** /

最佳答案

如果使用的是TCP,则不能保证一侧的send字节数等于另一侧的recv字节数。它们可以拆分,也可以合并在一起。
例如,如果先发送“ ab”然后发送“ cd”,则可能会收到“ ab”然后“ cd”,或者“ a”然后“ bcd”,或者“ abcd”,或者“ abc”然后“ d”,依此类推向前。

由于strstr在找到NUL字节时停止搜索其第一个参数,并且您正在与客户端发送NUL字节,因此最后一个recv可能在缓冲区中放入了类似“ \ 0 \ 0 \ 0End”的字样,因此strstr认为它是长度为零的字符串,但未找到“ End”子字符串。

关于c - TCPconnection:服务器不“了解”接收已结束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8794975/

10-16 18:38