UDP套接字缓冲区溢出检测

Posted

技术标签:

【中文标题】UDP套接字缓冲区溢出检测【英文标题】:UDP socket buffer overflow detection 【发布时间】:2011-11-06 14:40:56 【问题描述】:

我正在开发跨平台工具,可以捕获具有不同比特率的多个 udp 流。 boost::asio 用于网络。当 udp 缓冲区已满并且套接字上可能发生数据丢失时,有什么方法可以检测到这种情况?我现在能看到的唯一方法是读取 /proc/%pid%/net/udp,但它不适用于您所知道的 Windows :)。如果可能的话,我也想使用增强功能。

【问题讨论】:

那不会让你买太多。您的本地缓冲区只是沿途可能丢弃这些 UDP 数据包的众多地方之一。 谢谢,我知道 udp 是什么。但是流很大(数十/数百 mbps)并且处​​理很复杂。所以当没有足够的资源来处理这么多的数据时,检测这种情况也不错。 【参考方案1】:

如果您需要此功能,则必须将其编码到您使用的协议中。 UDP 本身无法做到这一点。例如,您可以在每个数据报中放置一个序列号。丢失的数据报将对应于丢失的序列号。

【讨论】:

哦,使用这个解决方案会很好,但我无法对协议进行更改。 检查协议是否提供了其他方式。很难想象如果一个协议无法评估数据是否被丢弃,它会有什么用处。【参考方案2】:

我刚刚遇到了同样的问题(尽管对我来说是 Linux 特有的),尽管这个问题很老,但不妨记录下我的发现供其他人使用。

据我所知,没有便携方法可以做到这一点,Boost 也没有直接支持。

也就是说,有一些特定于平台的方法可以做到这一点。在 Linux 中,可以通过设置 SO_RXQ_OVFL 套接字选项来完成,然后使用 recvmsg() 获取回复。虽然它的记录很差,但http://lists.openwall.net/netdev/2009/10/09/75 可能会帮助您。

首先避免它的一种方法是增加接收缓冲区(我假设您已经对其进行了调查,但为了完整性而将其包括在内)。 SO_RCVBUF 选项似乎得到了很好的跨平台支持。 http://pubs.opengroup.org/onlinepubs/7908799/xns/setsockopt.html http://msdn.microsoft.com/en-us/library/windows/hardware/ff570832(v=vs.85).aspx OS:es 对此设置了上限,管理员可能必须这样做增加。在 Linux 上,I.E.可以使用 /proc/sys/net/core/rmem_max 增加。

最后,让您的应用程序评估其“负载”的一种方法可能是在异步操作之前和之后引入时间戳,该方法具有较大的输入缓冲区可能用于早期检测过载。在伪代码中(不是 boost::async-adapted):

work_time = 0
idle_time = 0

b = clock.now()
while running:
  a = clock.now()
  work_time += a-b
  data = wait_for_input()
  b = clock.now()
  idle_time += b-a
  process(data)

然后每隔一秒左右,您可以检查并重置work_time / (work_time+idle_time)。如果它接近 1,您就知道自己遇到了麻烦,可以发出警报或采取其他措施。

【讨论】:

感谢您提及 SO_RXQ_OVFL。补充一下,这里有一个有用的例子:github.com/linux-can/can-utils/blob/master/candump.c

以上是关于UDP套接字缓冲区溢出检测的主要内容,如果未能解决你的问题,请参考以下文章

等待 UDP 接收时我的计时器缓冲区会溢出吗?

缓冲区溢出漏洞

系统在此应用程序中检测到基于堆栈的缓冲区溢出。溢出...

在 Windows 下更改默认套接字缓冲区大小 [关闭]

速率高时检测到 httperf 缓冲区溢出

是否有任何工具可以检测 Visual C++ 6.0 上的缓冲区溢出? [关闭]