繁体   English   中英

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

[英]Multiple calls to send() are merged into one call to recv()

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

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

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

服务器.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);

客户端.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() (最多发送的字节数)。

为了避免这种行为,定义并实现一个应用程序级协议来区分已发送的不同“消息”。

不能依赖recv() / send()接收/发送与这两个函数被告知接收/发送一样多的字节。 检查它们的返回值以了解这些函数实际接收/发送的字节数并循环它们直到所有打算接收/发送的数据都被接收/发送是必不可少的。

例如,如何完成这种“循环”

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

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

如果时间在您的应用程序中无关紧要,您可以在两条消息之间添加一个像 sleep(5) 这样的短时间间隔。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM