考虑通过套接字发送的100个字节。使用TCP套接字,如果我调用recv()
长度为50,我得到前50个字节,如果我再次调用它,我得到第二个50字节。使用UDP套接字,如果我调用长度为50的recvfrom()
,我得到前50个字节,但是无法检索第二个50后续调用recvfrom()
阻塞,直到下一个数据报收到了。
这是否意味着,如果我想要接收整个UDP数据报,无论大小,我必须分配64k缓冲区(UDP允许的最大值)?如果我connect()
我的UDP套接字,这会改变行为吗?或者,通过UDP运行的协议通常需要一个应该用于缓冲区的已知最大数据包大小?
答案 0 :(得分:2)
大多数理智的基于UDP的协议不会超过MTU IP和UDP标头以避免IP fragmentation。例如。对于大于512字节的消息,DNS切换到TCP。所以你可能安全地使用1472字节的缓冲区(1500以太网MTU - 20用于没有选项的IP报头--8个UDP报头),除非你的网络使用巨型帧。这当然取决于UDP之上的应用程序协议。
如果您真的偏执(或使用未知协议),您可以使用MSG_PEEK
和MSG_TRUNC
标志来首先计算出大小,然后分配足够大的缓冲区(请参阅recv(2)
)。