gpt4 book ai didi

c++ - 从套接字 C++ 部分接收数据包

转载 作者:行者123 更新时间:2023-11-30 00:38:29 35 4
gpt4 key购买 nike

我遇到了麻烦,我的服务器应用程序发送了 8 字节长度的数据包 - AABBCC1122334455 但我的应用程序接收到这个数据包分为两部分 AABBCC1122334455,通过“recv”功能,我该如何解决?

谢谢!

最佳答案

总结一下:

  1. TCP 连接不在应用层处理数据包或消息,您处理的是字节流。从这个角度来看,它类似于写入和读取文件。
  2. sendrecv 都可以发送和接收比参数中提供的数据更少的数据。您必须正确处理它(通常通过在调用周围应用适当的循环)。
  3. 在处理流时,您必须找到将其转换为应用程序中有意义的数据的方法。换句话说,您必须设计序列化协议(protocol)

从您已经提到的情况来看,您很可能想发送某种消息(好吧,这通常是人们所做的)。关键是要正确发现消息的边界。如果您的消息是固定大小的,您只需从流中获取相同数量的数据并将其转换为您的消息;否则,您需要一种不同的方法:

  • 如果您能想出一个在您的消息中不存在的字符,它可能是您的分隔符。然后你可以阅读流直到你到达角色,这将是你的信息。如果您传输 ASCII 字符(字符串),您可以使用零作为分隔符。

  • 如果您传输二进制数据(原始整数等),所有字符都可以出现在您的消息中,因此没有任何字符可以作为分隔符。在这种情况下,最常见的方法可能是使用包含消息大小的固定大小前缀。这个额外字段的大小取决于消息的最大大小(4 个字节可能是安全的,但如果知道最大大小是多少,则可以使用较小的值)。然后你的数据包看起来像 SSSS|PPPPPPPPP...(字节流),其中 S 是额外的大小字段,P 是你的有效负载(应用程序中的真实消息,P 字节数由 S 的值决定)。您知道每个数据包都以 4 个特殊字节(S 字节)开头,因此您可以将它们读取为 32 位整数。一旦知道封装消息的大小,就可以读取所有 P 字节。完成一个数据包后,您就可以从套接字读取另一个数据包了。

好消息是,您可以想出一些完全不同的东西。您只需要知道如何从字节流中反序列化消息以及 send/recv 的行为方式。祝你好运!

编辑:

接收任意字节数到数组中的函数示例:

bool recv_full(int sock, char *buffer, size_t size)
{
size_t received = 0;
while (received < size)
{
ssize_t r = recv(sock, buffer + received, size - received, 0);
if (r <= 0) break;
received += r;
}

return received == size;
}

以及接收带有 2 字节前缀定义有效载荷大小的数据包的示例(有效载荷的大小随后被限制为 65kB):

uint16_t msgSize = 0;
char msg[0xffff];

if (recv_full(sock, reinterpret_cast<char *>(&msgSize), sizeof(msgSize)) &&
recv_full(sock, msg, msgSize))
{
// Got the message in msg array
}
else
{
// Something bad happened to the connection
}

关于c++ - 从套接字 C++ 部分接收数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10758547/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com