我正在我的机器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因为一个完整的缓冲区而把它们扔掉了?
任何回复都将不胜感激。
答案 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。