如何找出响应“sendto”系统调用丢失数据包的原因?

如何找出响应“sendto”系统调用丢失数据包的原因?

strace ... -e sendto显示尝试在某处发送 UDP 数据报的成功(即正返回值)结果,但tcpdump -i any在该网络命名空间中没有显示任何相关的响应。

如何调试为什么sendto没有导致传出数据包?是否有一个工具可以跟踪所有层(路由、流量控制、nftables 等)的请求,并在数据报内的信息从内核中消失时输出?或者是否有一些带有清单的指南/文件详尽的发生这种情况的原因清单?

答案1

  1. 无法保证机器可以听到自己的数据包,尤其是 UDP 数据包。因此,如果您在与 sendto() 相同的计算机上运行 tcpdump,那么即使 sendto 有效,您也会发现预期的行为。

  2. 如果源和目标之间的任何路由器(或其他网络设备)因任何原因(内存、带宽、电源故障、宇宙射线、路由环路等)而无法发送数据包,则 UDP 数据包将被丢弃(或重复或乱序接收),恕不另行通知。

  3. 根本无法保证 UDP 数据包一定会被传送。如果内核内存不足,它可能会被删除。如果您尝试发送邮件时网络已满,则邮件可能会被丢弃。如果接收机器当时太忙,它可能会被丢弃。因此,即使 sendto 工作并且您在单独的计算机上运行 tcpdump,tcpdump 仍然可能看不到数据包。

发送者可以获得的数据包未传递的唯一通知是目标主动拒绝接受数据包,或者中间的路由器确定没有可能的路由来传递数据包。并且这些通知也不能保证针对任何特定数据包,并且可能只会针对整个数据包组发送一次。

如果您不喜欢这些条件,请不要使用 UDP。出于任意原因,它没有被命名为“不可靠的数据报协议”。 UDP的要点是延迟的数据包是无用的数据包。 UDP 优化的是速度,而不是可靠性。 TCP 中确保数据包可靠传输且有序的协议也可能导致数据包延迟、节流、保留、缓冲、拆卸、重新组装、整理和批处理。从技术上讲,tcp 甚至不提供数据包,它提供的数据流只是巧合地具有任何数据包边界,并且这些“边界”在发送方和接收方上不保证相同。

相关内容