接收整个 UDP 数据报,无论大小?

Mat*_*ude 5 sockets posix udp

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

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

Nik*_*sov 2

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

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