C/C++ 中的并发 UDP 连接限制
Concurrent UDP connection limit in C/C++
我写了一个 server in c
,它从 X
端口接收来自客户端的 UDP
数据。我已经使用 Epoll(non block)
套接字进行 UDP
监听,并且只有一个线程作为工作线程。伪代码如下:
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 毫秒的随机休眠。
UDP 没有 'connection'。所有数据包都只是在对等点之间发送,OS 做了一些神奇的缓冲来在某种程度上避免数据包丢失。
但是当太多数据包到达时,或者如果接收应用程序读取数据包的速度太慢,一些数据包会在没有通知的情况下被丢弃。这不是错误。
例如 Linux 有一个 UDP 接收缓冲区,默认情况下约为 128k(我认为)。你可能会改变它,但它不太可能解决 UDP 可能暴露丢包的系统问题。
UDP 没有像 TCP 那样的拥塞控制。底层传输(以太网、本地网络)的原始工件被暴露。您的 5000 个发送者总共获得的时间可能比您的接收者多 CPU,因此他们可以发送比接收者可以接收的更多的数据包。当接收方无法继续接收数据包时,UDP 发送方 not 会被阻塞(例如在 sendto() 中)。使用 UDP,发送方总是需要明确地控制和限制数据速率。没有来自网络侧的背压(*)。
(*)理论上UDP没有背压。但是在某些操作系统上(例如 Linux),您可以观察到 是 背压(至少在某种程度上),例如通过本地以太网发送时。当物理网络接口的网络驱动程序报告它正忙(或其缓冲区已满)时,OS 会在 sendto() 中阻塞。但是当本地网络适配器无法确定整个网络路径的网络 'being busy' 时,此背压停止工作。另见 "Ethernet flow control (Pause Frames)"。通过这种方式,即使接收方的接收缓冲区已满,发送方也可以阻止发送应用程序。这就解释了为什么经常会出现类似TCP背压的UDP背压,虽然UDP协议中并没有支持背压的东西。
我写了一个 server in c
,它从 X
端口接收来自客户端的 UDP
数据。我已经使用 Epoll(non block)
套接字进行 UDP
监听,并且只有一个线程作为工作线程。伪代码如下:
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 毫秒的随机休眠。
UDP 没有 'connection'。所有数据包都只是在对等点之间发送,OS 做了一些神奇的缓冲来在某种程度上避免数据包丢失。
但是当太多数据包到达时,或者如果接收应用程序读取数据包的速度太慢,一些数据包会在没有通知的情况下被丢弃。这不是错误。
例如 Linux 有一个 UDP 接收缓冲区,默认情况下约为 128k(我认为)。你可能会改变它,但它不太可能解决 UDP 可能暴露丢包的系统问题。
UDP 没有像 TCP 那样的拥塞控制。底层传输(以太网、本地网络)的原始工件被暴露。您的 5000 个发送者总共获得的时间可能比您的接收者多 CPU,因此他们可以发送比接收者可以接收的更多的数据包。当接收方无法继续接收数据包时,UDP 发送方 not 会被阻塞(例如在 sendto() 中)。使用 UDP,发送方总是需要明确地控制和限制数据速率。没有来自网络侧的背压(*)。
(*)理论上UDP没有背压。但是在某些操作系统上(例如 Linux),您可以观察到 是 背压(至少在某种程度上),例如通过本地以太网发送时。当物理网络接口的网络驱动程序报告它正忙(或其缓冲区已满)时,OS 会在 sendto() 中阻塞。但是当本地网络适配器无法确定整个网络路径的网络 'being busy' 时,此背压停止工作。另见 "Ethernet flow control (Pause Frames)"。通过这种方式,即使接收方的接收缓冲区已满,发送方也可以阻止发送应用程序。这就解释了为什么经常会出现类似TCP背压的UDP背压,虽然UDP协议中并没有支持背压的东西。