java - DatagramChannel 发送线路上丢失

标签 java udp arp

我在我正在开发的工具中发现数据报 channel 偶尔会丢失一些数据。 UDP 是这里要求的一部分,所以我主要只是尝试解决我所看到的行为。该工具是使用 Java 7 开发的(另一个要求),但我看到发生该行为的计算机正在 Java 8 JRE 上运行。

我有一个装饰器类,它使用一些附加行为来装饰对 DatagramChannel.send 的调用,但该调用实际上可以归结为:

public int send( ByteBuffer buffer, SocketAddress target ) throws 
{
    // some additional decorating code that can't be shared follows

    int bytesToWrite = buffer.remaining();
    int bytesWritten = decoratedChannel.send(buffer, target);

    if (bytesWritten != bytesToWrite) {
        // log the occurrence
        return bytesWritten;
    }
}

上面还有一个额外的装饰,用于执行我们自己的碎片(作为远程主机要求的一部分)。因此,源数据始终保证最多为 1000 字节(完全在以太网帧的限制之内)。修饰 channel 还配置为阻塞 I/O。

我在极少数情况下看到的是,该例程(以及 DatagramChannel 的发送方法)将被调用,但线路上看不到数据(使用 Wireshark 进行监控)。发送例程始终返回在这种情况下也应该写入的字节数(因此 bytesWritten == bytesToWrite)。

我知道 UDP 存在可靠性问题(为此我们有自己的数据可靠性机制来解决数据丢失和其他问题),但我对数据报 channel 的实现行为感到好奇。如果 send 返回写入的字节数,我是否至少应该在 Wireshark 中看到相应的帧?否则,我希望 native 实现可能会抛出异常,或者至少不会返回我期望写入的字节数?

最佳答案

实际上,我通过在 Wireshark 中进行更多的摆弄最终发现了原因。我无意中过滤掉了 ARP 请求,这似乎是问题的原因,如 this answer 中所述。 :

ARP queues only one outbound IP datagram for a specified destination address while that IP address is being resolved to a MAC address. If a UDP-based application sends multiple IP datagrams to a single destination address without any pauses between them, some of the datagrams may be dropped if there is no ARP cache entry already present. An application can compensate for this by calling the Iphlpapi.dll routine SendArp() to establish an ARP cache entry, before sending the stream of packets.

看来 ARP 条目很快就会过时,偶尔的 ARP 请求会导致数据包丢失。我增加了 PC 上接口(interface)的 ARP 超时,现在丢包发生的频率大大降低了。

关于java - DatagramChannel 发送线路上丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28569408/

相关文章:

java - 编译 Java 程序时遇到问题,我对它很陌生。无法弄清楚如何处理目录

java - Apache Camel XmlJsonDataFormat XML 到 JSON

ios - 是否有用于测试 ObjC 代码的公共(public) UDP 站点?

java - UDP - 无法从 DatagramPacket 获取数据

linux - 套接字和 ARP(IP 邻居)表条目

objective-c - 在 iPhone/iPad 上获取 ARP 表

java - 数据结构的这些属性称为什么?

java - IntelliJ IDEA : Tomcat 8. 5.13 和 9.0.0.M19 — 工件部署期间出错。有关详细信息,请参阅服务器日志

udp - 使用tcpdump监视流量时缺少UDP片段

Linux arp -a 输出表列定义