2012-09-13 26 views
3

考虑通过套接字发送的100个字节。对于TCP套接字,如果我调用recv()长度为50,我会得到前50个字节,如果我再次调用它,我会得到第二个50字节。使用UDP套接字,如果我调用长度为50的recvfrom(),我会得到前50个字节,但是无法检索第二个50 - 随后调用recvfrom()块,直到收到下一个数据报。接收整个UDP数据报,不管大小如何?

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

回答

2

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

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