是什么导致UDP数据包在发送到本地主机时被丢弃?
我正在发送非常大的数据报(64000字节)。我意识到MTU远小于64000字节(根据我的阅读,典型值约为1500字节),但我怀疑会发生以下两种情况之一-
要么没有数据报都能通过(所有大于1500字节)会被静默丢弃或导致引发错误/异常),否则64000字节数据报将被分拆成大约43 1500字节消息并透明地传输。
从长远来看(2000+
64000字节数据报),约有1%的数据报(甚至对于LAN来说似乎都异常高)被丢弃了。我可能希望通过网络进行此操作,在该网络中,数据报可能会乱序到达,被丢弃,被过滤等。但是,在localhost上运行时,我没有想到这一点。
是什么导致无法在本地发送/接收数据?我意识到UDP是不可靠的,但是我没想到UDP在本地主机上是如此不可靠。我想知道这是否只是时间问题,因为发送和接收组件都在同一台机器上。
为了完整起见,我包括了发送/接收数据报的代码。
正在发送:
DatagramSocket socket = new DatagramSocket(senderPort);int valueToSend = 0;
while (valueToSend < valuesToSend || valuesToSend == -1) {
byte[] intBytes = intToBytes(valueToSend);
byte[] buffer = new byte[bufferSize - 4];
//this makes sure that the data is put into an array of the size we want to send
byte[] bytesToSend = concatAll(intBytes, buffer);
System.out.println("Sending " + valueToSend + " as " + bytesToSend.length + " bytes");
DatagramPacket packet = new DatagramPacket(bytesToSend,
bufferSize, receiverAddress, receiverPort);
socket.send(packet);
Thread.sleep(delay);
valueToSend++;
}
接收:
DatagramSocket socket = new DatagramSocket(receiverPort);while (true) {
DatagramPacket packet = new DatagramPacket(
new byte[bufferSize], bufferSize);
System.out.println("Waiting for datagram...");
socket.receive(packet);
int receivedValue = bytesToInt(packet.getData(), 0);
System.out.println("Received: " + receivedValue
+ ". Expected: " + expectedValue);
if (receivedValue == expectedValue) {
receivedDatagrams++;
totalDatagrams++;
}
else {
droppedDatagrams++;
totalDatagrams++;
}
expectedValue = receivedValue + 1;
System.out.println("Expected Datagrams: " + totalDatagrams);
System.out.println("Received Datagrams: " + receivedDatagrams);
System.out.println("Dropped Datagrams: " + droppedDatagrams);
System.out.println("Received: "
+ ((double) receivedDatagrams / totalDatagrams));
System.out.println("Dropped: "
+ ((double) droppedDatagrams / totalDatagrams));
System.out.println();
}
回答:
总览
是什么导致无法在本地发送/接收数据?
主要是缓冲空间。想象一下,发送恒定的10MB /秒,而仅消耗5MB
/秒。操作系统和网络堆栈无法跟上,因此数据包被丢弃。(这不同于TCP,TCP提供了流控制和重新传输来处理这种情况。)
即使在没有溢出缓冲区的情况下使用数据时,也可能会有很小的时间片无法使用数据,因此系统将丢弃数据包。(例如,在垃圾回收期间,或者当OS任务暂时切换到更高优先级的过程时,等等。)
这适用于网络堆栈中的所有设备。当队列已满时,非本地网络,以太网交换机,路由器,集线器和其他硬件也会丢弃数据包。通过100MB / s以太网交换机发送10MB
/ s的流,而其他人试图通过同一物理线路填充100MB / s的流将导致丢包。
增加套接字缓冲区的大小和操作系统的套接字缓冲区的大小。
回答:
默认的套接字缓冲区大小通常128K或更少,这让 非常 小房间暂停数据处理。
系统控制
使用sysctl增加发送(写内存[wmem])和接收(读内存[rmem])缓冲区:
- net.core.wmem_max
- net.core.wmem_default
- net.core.rmem_max
- net.core.rmem_default
例如,将值增加到8 MB:
sysctl -w net.core.rmem_max=8388608
要保持设置不变,请同时进行更新/etc/sysctl.conf
,例如:
net.core.rmem_max=8388608
一个深入的文章有关调整网络堆栈潜入更为细节,触及了如何包从内核的网络驱动程序通过环缓冲区接收和处理在Linux下一路到C的多层次的recv
电话。本文介绍了在诊断网络问题时要监视的其他设置和文件。(见下文。)
在进行以下任何调整之前,请务必了解它们如何影响网络堆栈。 选择适合您的系统,网络配置和预期流量负载的数字:
- net.core.rmem_max = 8388608
- net.core.rmem_default = 8388608
- net.core.wmem_max = 8388608
- net.core.wmem_default = 8388608
- net.ipv4.udp_mem =‘262144 327680 434274’
- net.ipv4.udp_rmem_min = 16384
- net.ipv4.udp_wmem_min = 16384
- net.core.netdev_budget = 600
- net.ipv4.ip_early_demux = 0
- net.core.netdev_max_backlog = 3000
ethtool
此外,ethtool
对于查询或更改网络设置很有用。例如,如果${DEVICE}
为eth0
(使用ip
address或ipconfig
确定您的网络设备名称),则可以使用以下方法增加RX和TX缓冲区:
- ethtool -G $ {DEVICE}接收4096
- ethtool -G $ {DEVICE} TX 4096
iptables
默认情况下,iptables
它将记录有关数据包的信息,尽管这是最少的,但它消耗了CPU时间。例如,您可以使用以下命令禁用端口6004上UDP数据包的日志记录:
iptables -t raw -I PREROUTING 1 -p udp --dport 6004 -j NOTRACKiptables -I INPUT 1 -p udp --dport 6004 -j ACCEPT
您的特定端口和协议将有所不同。
监控方式
几个文件包含有关在发送和接收的各个阶段网络数据包发生了什么的信息。在下面的列表中${IRQ}
是中断请求号,并且${DEVICE}
是网络设备:
/proc/cpuinfo
-显示可用的CPU数量(有助于IRQ平衡)/proc/irq/${IRQ}/smp-affinity
-显示IRQ关联/proc/net/dev
-包含常规数据包统计信息/sys/class/net/${DEVICE}/queues/QUEUE/rps_cpus
-与接收数据包导向(RPS)有关/proc/softirqs
-用于元组过滤/proc/net/softnet_stat
-用于数据包统计信息,例如丢弃,时间压缩,CPU冲突等。/proc/sys/net/core/flow_limit_cpu_bitmap
-显示数据包流量(可以帮助诊断大小流量之间的丢弃)/proc/net/snmp
/proc/net/udp
摘要
缓冲区空间是丢弃数据包的最可能元凶。在整个网络堆栈中散布着许多缓冲区,每个缓冲区对发送和接收数据包都有自己的影响。网络驱动程序,操作系统,内核设置和其他因素可能会影响数据包丢弃。没有银弹。
进一步阅读
- https://github.com/leandromoreira/linux-network-performance-parameters
- http://man7.org/linux/man-pages/man7/udp.7.html
- http://www.ethernetresearch.com/geekzone/linux-networking-commands-to-debug-ipudptcp-packet-loss/
以上是 是什么导致UDP数据包在发送到本地主机时被丢弃? 的全部内容, 来源链接: utcz.com/qa/406717.html