6

考虑通过套接字发送的 100 个字节。对于 TCP 套接字,如果我recv()以 50 的长度调用,我会得到前 50 个字节,如果我再次调用它,我会得到第二个 50 个字节。使用 UDP 套接字,如果我recvfrom()以 50 的长度调用,我会得到前 50 个字节,但无法检索第二个 50 个字节——后续调用recvfrom()阻塞,直到收到下一个数据报。

这是否意味着,如果我想接收整个 UDP 数据报,无论大小,我都必须分配一个 64k 的缓冲区(UDP 允许的最大值)?如果我connect()的 UDP 套接字,这会改变行为吗?或者在 UDP 上运行的协议通常需要一个已知的最大数据包大小,应该用于缓冲区?

4

1 回答 1

2

大多数理智的基于 UDP 的协议不会通过MTU较少的 IP 和 UDP 标头来避免IP 碎片。例如,对于大于 512 字节的消息,DNS 切换到 TCP。因此,除非您的网络使用巨型帧,否则使用 1472 字节的缓冲区(1500 以太网 MTU - 20 用于不带选项的 IP 标头 - 8 UDP 标头)可能是安全的。这当然取决于 UDP 之上的应用程序协议。

如果您真的很偏执(或使用未知协议),您可以使用MSG_PEEKMSG_TRUNC标志来首先计算大小,然后分配足够大的缓冲区(请参阅 参考资料recv(2))。

于 2012-09-13T17:34:39.947 回答