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

ger*_*nte 8 c sockets tcp send recv

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

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

问题是发送的两个变量都是在recv()通话中接收的.因此,由两个不同的send()s 发送的两个字符串被链接并存储在第一个的缓冲区中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);
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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

alk*_*alk 10

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

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

为了解决这种行为,定义并实现一个应用程序级协议,以区分已发送的不同"消息".

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

例如,如何"循环"可以完成