对send()的多次调用合并为一次调用recv()

我有一个客户端 – 服务器应用程序。

客户端使用两个不同的send()调用发送一个字符串,后跟一个整数。 这两个数据应该存储在服务器上的两个不同变量中。

问题是发送的两个变量都是在recv()调用时收到的。 因此,由两个不同的send() s send()的两个字符串被链接并存储在第一个recv()的缓冲区中。

server.c:

 printf("Incoming connection from client %s:%i accepted\n",inet_ntoa(clientSocketAddress.sin_addr),ntohs(clientSocketAddress.sin_port)); memset(buffer,0,sizeof(buffer)); int sizeofMessage; if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0)==sizeofMessage)<0) { printf("recv failed."); closesocket(serverSocket); clearWinsock(); return EXIT_FAILURE; } char* Name=buffer; printf("Name: %s\n",Name); if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0))<0) { printf("bind failed."); closesocket(serverSocket); clearWinsock(); return EXIT_FAILURE; } int integer=ntohs(atoi(buffer)); printf("integer: %i\n",intero); 

client.c:

 if (send(clientSocket,Name,strlen(Name),0)!=strlen(Name)) { printf("send failed"); closesocket(clientSocket); clearWinsock(); return EXIT_FAILURE; } printf("client send: %s",Name); int age=35; itoa(htons(age),buffer,10); sizeofBuffer=strlen(buffer); if (send(clientSocket,buffer,sizeofBuffer,0)!=sizeofBuffer) { printf("bind failed."); closesocket(clientSocket); clearWinsock(); return EXIT_FAILURE; } 

我该如何解决? 我究竟做错了什么?

TCP是一种流媒体协议。 它根本不知道任何类型的“消息”边界。 它不会在send()单个调用中添加此类信息。

由于这些事实, send()方的任何数量的send()都可能导致接收方的任意数量的recv() s(最多发送的字节数)。

要解决此问题,请定义并实现应用程序级协议,以区分已发送的不同“消息”。

一个人不能依赖recv() / send()接收/发送那两个函数被告知接收/发送的字节数。 检查它们的返回值以了解这些函数实际接收/发送的字节数并循环它们直到接收/发送了所有要接收/发送的数据是非常必要的。

例如,如何“循环”可以完成

  • 写作你可能想看看这个答案: https : //stackoverflow.com/a/24260280/694576和
  • 阅读这个答案: https : //stackoverflow.com/a/20149925/694576

这就是TCP的工作原理。 将其视为字节流。 在它上面放置一些基本协议 – 用一些已知的字节值分隔应用程序消息,或者在长度字段前添加消息。

或者切换到UDP,它可以为您提供正在寻找的数据报语义,如果您可以容忍/从偶尔的数据包丢失中恢复。