对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,它可以为您提供正在寻找的数据报语义,如果您可以容忍/从偶尔的数据包丢失中恢复。