我有一个客户端 - 服务器应用程序。
客户端使用两个不同的send()
调用发送一个字符串后跟一个整数。这两个数据应该存储在服务器上的两个不同变量中。
问题是发送的两个变量都是在recv()
电话上收到的。因此,由两个不同的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;
}
我该如何解决?我究竟做错了什么?
答案 0 :(得分:10)
TCP是一种流媒体协议。它根本不知道任何类型的“消息”边界。它不会根据对send()
的单次调用添加此类信息。
由于这些事实,发送方的任何数量的send()
s都可能导致接收方的任意数量的recv()
s(最多发送的字节数)。
要解决此问题,请定义并实施应用程序级协议,以区分已发送的不同“消息”。
一个人不能依赖recv()
/ send()
接收/发送那两个函数被告知接收/发送的字节数。必须检查它们的返回值,以了解这些函数实际接收/发送的字节数,并循环它们,直到收到/发送了所有要接收/发送的数据。
例如如何完成“循环”
答案 1 :(得分:1)
这就是TCP的工作原理。将其视为字节流。 在它上面放置一些基本协议 - 用一些已知的字节值分隔你的应用程序消息,或者用长度字段添加你的消息。
或者切换到UDP,它可以为您提供正在寻找的数据报语义,如果您能够容忍/从偶尔的数据包丢失中恢复。
答案 2 :(得分:0)
如果时间在您的应用程序中关系不大,则可以在两条消息之间添加一个短的时间间隔,例如sleep(5)。