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

标签 c sockets tcp send 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 是一种流式传输协议(protocol)。它根本不知道任何类型的“消息”边界。它不会添加依赖于对 send() 的单次调用的此类信息。

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

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

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

例如这个“循环”是如何完成的

关于c - 对 send() 的多次调用合并为对 recv() 的一次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24536471/

相关文章:

java - JNI native 函数内的自定义内存分配

c - C语言中一个数组变量存放在哪里?

c++ - 套接字TCP服务器程序问题

java - Java 中的事件传递库?

c - 如何获取连续写入自然数的数字中的x(未知)数字:123456789101112

c - 链接器错误 - typedef 结构

python - 具有阻塞请求的 Gevent 异步服务器

network-programming - Linux 网络堆栈是否在多核机器上并行运行?

python - TypeError : a bytes-like object is required, 不是 'str'

java - 通过套接字发送字符串在 catch 语句中出现 null 错误