Linux限制我的应用程序的UDP传输,我怎么能看到它?

我目前正在开发两个应用程序来处理自定义videostream“协议”。 基本上:

  • 服务器从networking摄像头捕捉video帧,将它们分成几部分,然后通过UDP将这些部分发送给客户端。
  • 客户端接收所有的框架部分,并处理所有的“重新sorting”:按照正确的顺序放置这些部分,在旧的框架上存储新的框架,等等……这就是实现“协议”的地方:客户端需要了解他们收到的video数据,这样他们才能正确地重新sorting,并显示一个合适的帧

这个机制本身工作得很好(经过相当多的斗争,我会承认)。 但是,现在我的应用程序正在运行,我发现我的客户正在努力接收一些帧部分。 客户端将成功检索第一部分,让我们说n帧,然后只是…挂在recvfrom 。 我不打扰所有的应用程序的细节,但这里有一些统计:

  • 服务器每40,000微秒(25fps)捕获一帧(38,016字节)。
  • 每个帧被分成24个部分(每个部分38,016 / 24 = 1584字节)。

假设我们只有一个客户端。 在networking方面,这意味着:

  • 每40,000微秒,服务器向客户端发送24个缓冲区( sendto )。 每个缓冲区的长度是1584个字节。 另一方面,客户调用recvfrom 24次。
  • 在一秒钟内,服务器可以捕获25帧。 这意味着在1秒内,它会发送25 * 24帧的部分给客户端。 这表示每秒25 * 24 * 1584 = 950,400字节)。

我们还假设客户端总是在服务器发送时进行监听。 现在,用这些费率,客户将能够保持1或2秒。 当应用程序冻结时,客户端最终会挂起recvfrom ,就好像服务器已经停止了广播。

我添加了一些冗长的服务器,以确保它保持广播,它确实。 几秒钟后,似乎服务器的sendto调用不再达到客户端的recvfrom调用。 我检查了所有与networking有关的代码,因为它非常简单,所以没有太多错误:服务器build立一个缓冲区,调用sendto ,并开始准备下一个缓冲区…客户端只是等待缓冲区。

由于我在编程中找不到解释,所以我开始相信某些东西是卡在networking上的。 在某些地方,似乎有些东西阻止了我的UDP数据包在一段时间后到达客户端。 现在,由于UDP是完全无控制的,所以我找不到从我的程序中检查缓冲区传输的方法。

但是,有没有办法让我看看系统是否传输我的数据包,或者如果它最终达到其中一个极限,并开始丢弃它们? 如果是的话,这个限制机制是什么,有没有一种方法可以configuration我的系统,这样我的应用程序就可以按照我编程的速度工作了?

由于我的应用程序通过回送接口(127.0.0.1:n上的服务器)进行通信,因此我认为添加有关此接口的信息是一个好主意。 我正在运行一个GNU / Linux(内核3.13.0)系统。

 $ ifconfig lo lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:98821 errors:0 dropped:0 overruns:0 frame:0 TX packets:98821 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:202639359 (202.6 MB) TX bytes:202639359 (202.6 MB) 

您可以使用tcpdump来监视任何一端的数据包。 该工具可以用来捕获标题或完整的数据包。 手册页包括如何过滤数据包的示例,以便您只捕获您感兴趣的stream量。

你的包大小似乎有点奇怪。 如果您不使用巨型帧,则您的数据包可能会在networking上进行分段传输。 这可能是你的问题的原因。

将帧分成1472个字节或更less的部分将更适合于以太网连接。 Internet连接的MTU可能会更小,1464字节或更less的部分可能会更合适。

您可能希望在连接上执行MTU发现以防止碎片。 这将允许您避免或限制数据包碎片。