DatagramSocket:如何处理数据包的分片问题

4
我从我的教授那里得知,使用UDP套接字发送的数据报包在较低层被分段,并且可能作为多个数据包到达接收端。例如,如果我将1000字节数据发送到数据报包中,在接收端,它可能会像这样以2字节、500字节、12字节等形式到达。因此,他建议执行多次receive(...)来接收发送方发送的完整1000字节数据包。
后来,当我查阅Java文档中有关datagram socket receive(...)的内容时,有一行文字如下所述:“此方法阻塞,直到接收到数据报。”这是否意味着完整的数据报包已经接收到了,不需要执行多次接收(即使在理论上是这种情况)在我们使用Java时?
请澄清。如果每个数据包都需要执行多次receive(...)才能解决这个问题,请提供如何执行此操作的建议。
1个回答

4
任何对 receive() 的调用都会给你一个完整的数据包 - 片段处理发生在套接字下面的两个层级。分片和重组发生在网络/互联网层(IP),因此套接字将永远看不到片段,只接收完整的UDP/TCP数据包(只有完整的数据包才会发送到监听端口)。
所以,不,你不需要多个 receive() 来获取单个数据包,但是你应该意识到UDP不可靠,如果在网络层中丢失了一个片段(在某些情况下,如果它按顺序到达),你将无法获取数据包。

如果您在接收数据包时遇到问题,可能需要检查getReceiveBufferSize()setReceiveBufferSize()方法 - 如果缓冲区大小小于数据包大小,则不能保证可以接收数据包。


另外,我了解到如果我们在UDP套接字中使用消息队列的概念,而不是字节数组,它可以保留分段数据包的顺序。但是我不知道在创建UDP套接字或数据包时如何表达这一点。你有什么想法吗? - arun
@arun 请看我的编辑。我相当确定你想要的在标准Java库中是不可能实现的,因为我从未听说过它,而且搜索也没有返回任何结果。你需要去操作系统/驱动程序级别才能实现那个功能。 - ddmps
@arun,在UDP中没有“消息队列概念”。数据报是一组八位字节。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接