为什么这个Java程序导致UDP数据包丢失?

时间:2011-10-10 05:29:28

标签: java networking ubuntu operating-system udp

我正在我的机器A和B上运行实验,两者都安装了Ubuntu Server 11.04。 A和B连接到相同的1000M / bps开关。

A是发件人:

while(总计<= 10,000) send_udp_datagramPacket(新字节[100])到B

B是接收者:

而(真) 接收()

但最后我在B的时间不到10,000(约9960)。为什么会这样? 丢失的数据包在哪里?他们实际上没有被送到开关的电线吗?或者开关丢失了?或者他们确实到了B,但B的操作系统丢弃了它们?或者他们到达了Java,但是Java因为一个完整的缓冲区而把它们扔掉了?

任何回复都将不胜感激。

3 个答案:

答案 0 :(得分:5)

请记住,UDP不提供可靠的通信,它适用于可接受数据丢失的情况(例如流媒体)。很可能这是一个缓冲区溢出(我的猜测,不要依赖它)但重点是,如果这个数据丢失是不可接受的,请改用TCP。

如果这只是为了实验,请尝试在循环中添加延迟(Thread.sleep())并增加它,直到获得最大接收数据包。

编辑: 正如评论中所提到的,sleep()不是一个修复程序,最终会丢失数据包......这只是UDP。

答案 1 :(得分:2)

  

但最后我在B的时间不到10,000(约9960)。为什么会这样?

UDP是一种有损协议。即使你在这个测试中得到10,000,你仍然需要编码一些数据包丢失的可能性。它们也可能被分段(如果大于532字节)和/或无序到达。

  

丢失的包裹在哪里?

他们被放弃了。

  

他们是不是真的被送到了交换机的电线?

它们可以随处丢弃。我不相信Java有任何丢弃数据包的逻辑(但是在所有实现中都不能保证)它可能被操作系统,网络适配器丢弃,在线路上损坏,被交换机丢弃。

  

或者开关丢失了?

如果数据包以某种方式损坏或填充缓冲区,它将执行此操作。

  

或者他们确实到了B,但B的操作系统丢弃了它们?

是的,或者A的操作系统可以放弃它们。

  

或者他们到达了Java,但Java因为一个完整的缓冲区而把它们扔掉了?

Java没有自己的缓冲区。它使用OS中的底层缓冲区。但是在这个阶段可能会丢失数据包。

注意:无论您减少多少数据包丢失,您都必须承担一定的损失。

答案 2 :(得分:1)

  

为什么这个Java程序会导致UDP数据包丢失?

问题是形象不对称。 Java和您的程序都不会导致UDP数据包丢失。 UDP 导致UDP数据包丢失。无法保证任何UDP数据包都会到达。请参阅RFC 768