【问题标题】:C++ udp recvfrom reduce dropsC++ udp recvfrom 减少滴
【发布时间】:2016-11-23 00:57:51
【问题描述】:

我的 udp 接收器套接字的设置非常标准。我的发送器以 36Hz 发送数据,接收器以 72Hz 读取数据。每次发送 12072 字节。

当我执行 cat /proc/net/udp.我经常得到

 sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops 
 7017: 0101007F:0035 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 10636 2 0000000000000000 0         
 7032: 00000000:0044 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 14671 2 0000000000000000 0         
 7595: 00000000:0277 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 11113 2 0000000000000000 0         
 7660: 00000000:22B8 00000000:0000 07 00000000:00004100 00:00000000 00000000  1000        0 251331 3 0000000000000000 352743   

你可以看到 rx_queue 里面有一些值,读取速度不够快?

我的代码

    int recv_len = recvfrom(s, buf, BUFLEN, MSG_TRUNC, (struct sockaddr *) &si_other, &slen); 
   // dont worry buflen is like 64000 no error here

    std::cout <<" recv_len "<<recv_len<<std::endl;

即使队列很大,我总是得到输出为 recv_len 12072 ?为什么是这样 ?有没有办法加快我的阅读速度或阅读队列中的所有消息?即使我的阅读频率更高,我也不明白这是怎么回事。

【问题讨论】:

  • 也许你的代码没有按照你的想法做? (例如,您认为您正在以 72HZ 的频率阅读,但事实并非如此。或者您还没有发现一个简单的错误……等等)

标签: c++ linux sockets


【解决方案1】:

UDP 数据报总是作为一个完整的原子单元传输。如果您发送一个 12072 UDP 数据报,您的接收者将只收到一个 12072 数据报或什么都没有——您将永远不会收到部分消息 (*) 或连接的多个消息。

请注意,对于这种大小的数据报,它们几乎肯定会在 IP 层被分段,因为它们可能大于您网络的 MTU(最大传输单元)。在这种情况下,如果任何一个片段在途中或在接收主机处被丢弃或被发现损坏,则将丢弃整个 UDP 数据报。

(* 如果提供给recvfrom 的缓冲区太小,则消息可能会被截断,但如果整个消息无法在内核中重新组装,它甚至都不会被考虑接收。 )

如果您无法接收到所有正在发送的消息,我会检查您是否需要增加分配给 UDP 的内核缓冲区空间。这是通过sysctl 实用程序完成的。具体来说,您应该检查并可能调整net.core.rmem_maxnet.ipv4.udp_mem 的值。见相应文档:
https://www.kernel.org/doc/Documentation/sysctl/net.txt
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

最后,谈论“读取频率”似乎有点奇怪——我假设这意味着您每秒轮询套接字 72 次?为什么不只使用一个线程来读取套接字。然后线程可以在recvfrom 上阻塞,接收将以尽可能少的延迟完成。 (无论如何,这值得一试,即使只是为了测试——看看轮询是否导致您无法跟上发件人。)

【讨论】:

  • 是的,我也认为内核级别发生了一些事情。专用 1 个线程会减少丢弃次数,但不会显着减少。但更重要的是它还减少了从发送者到我处理消息的点的延迟。我想我会研究 udp_mem 大小并使用这些值。
猜你喜欢
  • 2020-04-01
  • 2016-01-09
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
相关资源
最近更新 更多