Tho*_*ens 21 java udp network-programming
我正在发送非常大(64000字节)的数据报.我意识到MTU远小于64000字节(典型值大约是1500字节,来自我的阅读),但我怀疑会发生两件事之一 - 要么没有数据报就能通过(所有大于1500字节)会被静默删除或导致抛出错误/异常)或64000字节数据报将被分成大约43个1500字节的消息并透明地传输.
从长远来看(2000 + 64000字节数据报),数据报的大约1%(即使是LAN似乎异常高)也会被丢弃.我可能期望通过网络,数据报可能无序到达,被丢弃,过滤等等.但是,在localhost上运行时我没想到这一点.
是什么导致无法在本地发送/接收数据?我意识到UDP是不可靠的,但我没想到它在localhost上如此不可靠.我想知道它是否只是一个时间问题,因为发送和接收组件都在同一台机器上.
为了完整起见,我已经包含了发送/接收数据报的代码.
发送:
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++;
}
Run Code Online (Sandbox Code Playgroud)
接收:
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();
}
Run Code Online (Sandbox Code Playgroud)
nos*_*nos 27
是什么导致无法在本地发送/接收数据?
主要是缓冲空间.假设您正在发送一个10MB /秒的恒定速度,并且您只能消耗5MB /秒,操作系统和网络堆栈无法跟上,因此它会丢弃数据包 - 这应该是相当明显的.(这自然不同于提供流控制和重传以处理这种情况的TCP).
即使您通常不断使用数据,也可能会有很少的时间片.例如,垃圾收集器启动,操作系统决定安排另一个进程而不是消费者0.5秒等等 - 系统将丢弃数据包.
这可以扩展到其间的任何网络设备.如果您在网络上运行而不是仅在本地运行,则以太网交换机,路由器等也会在其队列已满时丢弃数据包(例如,您通过100MB/s以太网交换机发送10MB/s的流,并且在半夜的几秒钟,其他人试图通过相同的路径填充100MB /秒,一些数据包将丢失.)
尝试增加套接字缓冲区大小,通常你也必须在操作系统级别上增加它.
(例如,在Linux上,缺省套接字缓冲区大小往往只有128K或更少,这让非常小房间暂停数据处理,你可以尝试通过设置来提高他们的sysctl net.core.wmem_max,net.core.wmem_default, net.core.rmem_max,net.core.rmem_default)