我写了一个server in c
,它从端口UDP
中的客户端接收X
数据。我使用Epoll(non block)
套接字进行UDP
监听,并且只有一个线程作为worker。伪代码如下:
on_data_receive(socket){
process(); //take 2-4 millisecond
send_response(socket);
}
但是当我发送5000 concurrent
(使用线程)请求服务器错过5-10%
请求时。 on_data_receive()从未调用过5-10%的请求。我正在本地网络测试,所以你可以假设没有丢包。我的问题是为什么on_data_receive没有要求一些请求?套接字的连接限制是多少?随着并发请求丢失率的增加也增加。
注意:在将请求发送到服务器之前,我使用了200毫秒的随机休眠。
1 个答案:
答案 0 :(得分:6)
There is no 'connection' for UDP. All packets are just sent between peers, and the OS does some magic buffering to avoid packet loss to some degree.
But when too many packets arrive, or if the receiving application is too slow reading the packets, some packets get dropped without notice. This is not an error.
For example Linux has a UDP receive buffer which is about 128k by default (I think). You can probably change that, but it is unlikely to solve the systematic problem that UDP may expose packet loss.
With UDP there is no congestion control like there is for TCP. The raw artifacts of the underlying transport (Ethernet, local network) are exposed. Your 5000 senders get probably more CPU time in total than your receiver, and so they can send more packets than the receiver can receive. With UDP senders do not get blocked (e.g. in sendto()) when the receiver cannot keep up receiving the packets. With UDP the sender always needs to control and limit the data rate explicitly. There is no back pressure from the network side (*).
(*) Theoretically there is no back pressure in UDP. But on some operating systems (e.g. Linux) you can observe that there is back pressure (at least to some degree) when sending for example over a local Ethernet. The OS blocks in sendto() when the network driver of the physical network interface reports that it is busy (or that its buffer is full). But this back pressure stops working when the local network adapter cannot determine the network 'being busy' for the whole network path. See also "Ethernet flow control (Pause Frames)". Through this the sending side can block the sending application even when the receive-buffer on the receiving side is full. This explains why often there seems to be a UDP back-pressure like a TCP back pressure, although there is nothing in the UDP protocol to support back pressure.