Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何监控Linux UDP缓冲区的可用空间?_Linux_Networking_Udp - Fatal编程技术网

如何监控Linux UDP缓冲区的可用空间?

如何监控Linux UDP缓冲区的可用空间?,linux,networking,udp,Linux,Networking,Udp,我在linux上有一个java应用程序,它打开UDP套接字并等待消息 在重载情况下几个小时后,数据包丢失,即数据包由内核接收,但不是由我的应用程序接收。我们在sniffer中看到丢失的数据包,在netstat中看到丢失的UDP数据包,在我们的应用程序日志中看不到这些数据包 我们尝试扩大套接字缓冲区,但这没有帮助-我们开始丢失数据包后,然后之前,但就是这样 对于调试,我想知道在任何给定时刻操作系统udp缓冲区有多满。谷歌搜索了一下,但什么也没找到。你能帮我吗 伙计们,我知道UDP是不可靠的。但是-

我在linux上有一个java应用程序,它打开UDP套接字并等待消息

在重载情况下几个小时后,数据包丢失,即数据包由内核接收,但不是由我的应用程序接收。我们在sniffer中看到丢失的数据包,在netstat中看到丢失的UDP数据包,在我们的应用程序日志中看不到这些数据包

我们尝试扩大套接字缓冲区,但这没有帮助-我们开始丢失数据包后,然后之前,但就是这样

对于调试,我想知道在任何给定时刻操作系统udp缓冲区有多满。谷歌搜索了一下,但什么也没找到。你能帮我吗

伙计们,我知道UDP是不可靠的。但是-我的计算机接收所有UDP消息,而我的应用程序无法使用其中的一些消息。我想最大限度地优化我的应用程序,这就是问题的原因。谢谢

Linux提供了文件/proc/net/udp和/proc/net/udp6,分别列出了IPv4和IPv6的所有打开的udp套接字。在这两个队列中,tx_queue和rx_queue列以字节为单位显示传出队列和传入队列

如果一切正常,您通常不会在这两列中看到任何不同于零的值:一旦应用程序生成数据包,它们就会通过网络发送,一旦这些数据包从网络到达,您的应用程序就会唤醒并接收到它们,recv调用会立即返回。如果您的应用程序打开了套接字,但没有调用recv来接收数据,或者没有足够快地处理这些数据,您可能会看到rx_队列上升。

该过程很简单:

如果需要,暂停应用程序进程

打开UDP套接字。如有必要,可以使用/proc//fd将其从正在运行的进程中挂起。或者您可以将此代码添加到应用程序本身并向其发送一个信号——当然,它已经打开了套接字

尽快在紧密循环中调用recvmsg

计算得到的数据包/字节数


这将丢弃当前缓冲的任何数据报,但如果这破坏了您的应用程序,则您的应用程序已被破坏。

rx\u队列将告诉您任何给定时刻的队列长度,但不会告诉您队列已满的程度,即高水位线。无法持续监视此值,也无法通过编程方式获取它


我可以想象监视队列长度的唯一方法是将队列移动到您自己的程序中。换句话说,启动两个线程——一个是尽可能快地读取套接字并将数据报转储到队列中;另一个是你的程序从这个队列中取出并处理数据包。当然,这假设您可以确保每个线程都位于单独的CPU上。现在,您可以监视自己队列的长度并跟踪最高水位线。

UDP是一种完全可行的协议。对于正确的工作,使用正确的工具也是一样的

如果您有一个等待UDP数据报的程序,然后在返回等待另一个数据报之前对其进行处理,那么您经过的处理时间需要始终快于数据报的最坏到达率。如果不是,则UDP套接字接收队列将开始填充

这对于短时间的爆发是可以容忍的。队列完全执行它应该执行的操作—将数据报排队,直到您准备就绪。但是,如果平均到达率经常导致队列积压,那么是时候重新设计您的程序了。这里有两个主要的选择:通过巧妙的编程技术减少所用的处理时间,和/或多线程程序。也可以跨程序的多个实例进行负载平衡

如前所述,在Linux上,您可以检查proc文件系统,以了解UDP的运行状态。例如,如果我对/proc/net/udp节点进行cat,会得到如下结果:

$ cat /proc/net/udp   
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops             
  40: 00000000:0202 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 3466 2 ffff88013abc8340 0           
  67: 00000000:231D 00000000:0000 07 00000000:0001E4C8 00:00000000 00000000  1006        0 16940862 2 ffff88013abc9040 2237    
 122: 00000000:30D4 00000000:0000 07 00000000:00000000 00:00000000 00000000  1006        0 912865 2 ffff88013abc8d00 0         
从这里,我可以看到用户id 1006拥有的套接字正在侦听端口0x231D 8989,并且接收队列大约为128KB。由于128KB是我的系统上的最大大小,这告诉我我的程序在跟上到达的数据报方面非常弱。到目前为止已经有2237次丢弃,这意味着UDP层无法将更多数据报放入套接字队列,必须丢弃它们

您可以随时观察程序的行为,例如使用:

watch -d 'cat /proc/net/udp|grep 00000000:231D'
还要注意,netstat命令做的事情是相同的:netstat-c-udp-an

我的weenie程序的解决方案是多线程


干杯

@Juliano谁说他可以选择要使用的协议?也许他正在实现一个基于udp的协议来服务现有的客户端。Poster想知道监控udp统计信息,而不是对使用哪个协议的意见。通过首先确定层中发生丢失的位置,可以进行修复。您如何知道您的系统的最大udp队列大小为128KB?@Chinaxing cat/proc/sys/net/core/rmem_maxI即将否决此答案,但在 我觉得很好笑。我只希望没有人试图实施这一点: