缺少 UDP 发送的数据包

Posted

技术标签:

【中文标题】缺少 UDP 发送的数据包【英文标题】:Missing UDP sent packets 【发布时间】:2015-04-21 06:50:42 【问题描述】:

我是 Winsock 编程的新手,所以如果这是一个“愚蠢”的问题,请提前道歉。

我编写了一个 Windows 应用程序,它通过 UDP 将数据发送到外部设备。由于 UDP 是外部设备支持的唯一协议,因此我无法使用更强大的协议,例如 TCP。

现在,如果我的程序快速连续调用 6 次 WSASentTo,则会发生以下两种情况之一:

    如果上一条消息是最近发送的,而目标设备仍在 Windows 的 ARP 缓存中,则所有 6 条消息都会发送到外部设备。

    但是,如果设备不再位于 Windows 的 ARP 缓存中,则只会发送一两条消息。其他人似乎消失在某个地方。

我的应用每次调用 WSASendTo 时都使用不同的缓冲区,因此我的应用不应该覆盖它自己的数据。我也认为我已经为重叠 I/O 正确设置了 WSASendTo。这些消息非常小(每个只有大约 50 个数据字节),所以我无法想象我会在任何地方溢出缓冲区。 “网络”仅由 PC 和目标设备组成,通过一根 cat5 电缆将两者连接起来。

虽然我可以添加一个常规的“心跳”以将设备保存在 Windows 的 ARP 缓存中(并且可能会),但我仍然担心某些事情没有按应有的方式工作。

有什么想法吗?

【问题讨论】:

【参考方案1】:

不幸的是,由于 UDP 不保证传送,网络堆栈可以随时出于任何原因丢弃您发送的数据包,因此无法将此类问题归类为不正常工作。

对于您的特定情况,Microsoft 过去已在 ARP 解析期间解决了此类 UDP 丢弃问题。该行为有可能/很可能保留在当前的实现中。

来自ARP and UDP Messages

ARP 只为给定的目标地址排队一个出站 IP 数据报,而该 IP 地址被解析为 MAC 地址。如果基于 UDP 的应用程序将多个 IP 数据报发送到单个目标地址而在它们之间没有任何暂停,则如果不存在 ARP 缓存条目,则可能会丢弃一些数据报。应用程序可以通过在发送数据包流之前调用 Iphlpapi.dll 例程 SendArp() 来建立 arp 缓存条目来弥补这一点。有关更多信息,请参阅平台软件开发工具包 (SDK)。

【讨论】:

谢谢。这与我的观察一致。目前我已经通过 arp 命令添加了一个静态 ARP 表条目。在适当的时候,我会找到更好的方法。

以上是关于缺少 UDP 发送的数据包的主要内容,如果未能解决你的问题,请参考以下文章

为啥 traceroute 发送 UDP 数据包而不是 ICMP 数据包?

收发UDP数据包

Linux内核网络UDP数据包发送——Linux netdevice 子系统

Linux内核网络UDP数据包发送——Linux netdevice 子系统

为啥 Java DatagramSocket 没有收到客户端发送的所有 udp 数据包?

套接字编程:在 UDP 上发送数据包(C++)