如何最小化UDP数据包丢失 [英] How to minimize UDP Packet Loss

查看:148
本文介绍了如何最小化UDP数据包丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





这是我的问题:

我尝试在2台PC之间发送大量数据(大图像) UDP套接字(UDP是多播的唯一选择)。



我使用类似RUDP(Reliable-UDP)的东西,基本上:

- 服务器发送大量带有id(每个映像一个)和数据包索引的UDP数据包

- 客户端接收数据包并使用数据包索引重建图像

- 如果数据包丢失,客户端向服务器发送UDP消息以请求丢失的数据包

- 服务器发送丢失的数据包

此循环操作完成,直到服务器必须发送下一张图片。



当一切正常时,会丢失一些数据包,网络仅使用5%的带宽。

但有时候,几乎所有的数据包都丢失了,网络使用了超过25%的带宽(限制是由于我的实现超时,这项工作就像我想要的那样)并代表t发送相同图像的5倍!



我试过:

- 停用反病毒,防火墙

- 直接连接



- 检查Windows过滤平台(WFP)是否丢弃了一些数据包,但是当防火墙关闭时,日志中没有任何内容。



- 如果我在服务器和客户端上查看资源监视器,网络使用是相同的。



我知道它应该是可能的,因为我可以连接一个发送两次数据帧速率的设备,我试过没有数据包丢失。



如何调查数据包丢失/丢弃的位置?

Hi,

Here is my problem:
I try to send a lot of data (big images) between 2 PC using UDP socket (UDP is the only choice for Multicast).

I use something like RUDP (Reliable-UDP), basically:
- the Server sends a lot of UDP packet with id (one per image) and packet index
- the Client receives the packets and reconstruct the image using the packet index
- if packets are missing, the client sends an UDP message to server to request the missing packets
- the Server sends the missing packet
this loop of actions is done until the server must send the next image.

When everything works fine, a few number of packets is missing and the network used only 5% of bandwidth.
But sometimes, almost all packets are missing and the network used more than 25% of bandwidth (limitation is due to timeout in my implementation, and this work like I want) and represent sending 5 times the same image!

I tried :
- deactivating anti-virus, firewall
- direct connection

- checking if Windows Filtering Platform (WFP) dropped some packet, but nothing appears in the log when firewall is off.

- If I look the resource monitor on both server and client, network use are identical.

I knows it should be possible because I can connect a device sending twice the data framerate I tried without packet loss.

How can I investigate where the packets are lost/dropped?

推荐答案

解决方案太简单了:



增加Socket Option ReCeiVe BUFfer(也称为SO_RCVBUF)。



默认情况下,此缓冲区为8kb,在我的情况下,它是一个UDP数据包的大小。这意味着,当我的客户端读取数据包时,必须在服务器发送新数据包之前完成,否则新数据包将被IP堆栈丢弃。



我增加了使用 setsockopt 函数将缓冲区设置为更大的值(图像大小的两倍):

The solution was too simple:

increase the Socket Option ReCeiVe BUFfer (also named SO_RCVBUF).

by default, this buffer is 8kb, in my case it is the size of one UDP packet. That's mean, when my client reads the packet it must be done before the server sends a new packet or the new packet will be discarded by the IP stack.

I increased the buffer to a bigger value (twice the size of an image) using the setsockopt function:
int rcvbufsize = myBigImageSize*2;
setsockopt(mySocket,SOL_SOCKET,SO_RCVBUF,(char*)&rcvbufsize,sizeof(rcvbufsize));





我提高了服务器的速度(通过在每个数据包之间等待更少)并且没有数据包丢失!



现在,我需要优化此接收缓冲区的大小。



I increased the speed of my server (by waiting less between each packet) and no packet loss!

Now, I need to optimize the size of this receive buffer.


我有类似的问题,但我可以用数据包撤销图像丢失。

我解决了以下步骤的问题:

1.增加套接字缓冲区大小,如上所述Pascal-78

2.在接收器部分我做了一个单独的线程,只接收数据包

3.每次收到命令时发送回确认命令保持链接实时

4.使用select( )在读取之前寻找数据包的超时介于10到500微秒之间

5.由于我的灵魂也必须在linux中工作我做了以下命令以允许增加套接字尺寸:

I have a similar problem, but I can withdraw images with packets lost.
I solved the problem making following steps:
1. Increasing the socket buffer size as said Pascal-78
2. In the receiver part I made a separate thread that only receives packets
3. Maintain the link live by sending back an acknowledge command every time I receive a command
4. Using select() with a timeout between 10 and 500 microseconds to look for a packet before reading it
5. As my soultion must work also in linux I made following command to allow increase the socket size:
sudo sysctl -w net.core.rmem_max=myMaxImagesize*2



6.我在控制台写道每次数据到达时都会显示一条消息,但不幸的是,Windows会在控制台上发出很大的延迟。我通过在main()的开头写这些代码行来解决这个问题,以增加控制台缓冲区:


6. I wrote at console a message every time data arrives, but unfortunately windows provokes a great delay writting at console. I solved that by writting this code lines at the beginning of the main() to increase console buffer:

#ifndef __linux__   //Introduce this code at the beginning of main() to increase a lot the speed of cout in windows: 
	char buf[4000]; setvbuf(stdout, buf, _IOFBF, sizeof buf);
#endif


这篇关于如何最小化UDP数据包丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆