9

我正在开发一个 Android 应用程序,它通过 WLAN 向 Windows 端点发送/接收大量 UDP 流量(不,我不能使用 TCP)。

问题是当我增加流量时,我开始看到在我调用 sendto(应用程序是用 NDK 编写的)和我看到数据包到达 Windows 端点之间存在巨大的延迟。在10 秒左右!反过来也会发生同样的事情:我看到 Windows 端点发送的数据包和 recvfrom() 接收的数据包之间存在巨大延迟。

  • 更改 SO_SNDBUF 没有任何效果,所以我认为这不是应用程序级缓冲控制的问题。
  • 我已经验证了该问题存在于各种 Android 设备上,因此我认为这不是硬件/无线驱动程序的问题
  • 使用嗅探器并关联时间戳,我确认在调用 sendto() 和从 Android 设备发送的数据包之间发生延迟,因此在 AP 或 Windows 端点中没有发生缓冲

所以在这一点上,我几乎没有想法。事实会让我相信缓冲发生在 Android OS 层上,但是10 秒的 10Mbps 流量?对于内存占用如此大的问题的操作系统来说,这似乎太高了,不可行。

另外,如果问题是我发送数据的速度太快并且压倒了操作系统,那么我希望 sendto() 返回 ENOMEM 或 ENOBUFS ......但没有迹象表明 Android 应用程序级别有任何问题。

所以我的问题是:是什么导致了这种延迟?有没有办法减轻它,或者我是否需要改变我的应用程序以有更长的超时时间,或者在它变坏之前检测到这种情况?

4

3 回答 3

3

你发送太多了..你发送了多少?10Mbps绝对是太高了。记住:

  1. 您发送的每个 UDP 数据报都有一个额外的 28 字节标头(UDP + IP over IPv4)
  2. 连接链接速度是您永远无法达到的理论上的最大限制
  3. Phone OS 可能会限制您,Phone OS 需要节省电池并尝试最小化套接字通信来做到这一点。

或者

你说你的 CPU 是 20%,你有多少个核心 - 你可能会最大化正在发送的核心,即处理速度是瓶颈。

于 2013-11-01T00:41:16.347 回答
1

对于有同样问题的人:

尝试重用 DatagramSocket。这为我解决了它。

于 2014-02-21T22:33:08.543 回答
0

我最近在 linux-rt 列表上看到了非常相似的行为的报告,这可能是相关的。

http://comments.gmane.org/gmane.linux.rt.user/10163

几个月来,我一直被虚假的抖动所困扰,在

UDP 消息 - 多播 UDP 消息在原始节点上接收,没有任何延迟,但在其他节点上检测到 10 毫秒范围内的延迟。简而言之,它看起来就像一条消息在最终被传输之前卡在了内核中。最后,感谢 LTTng 工具,我能够将问题归结为 net/sched/sch_generic.c 中的代码和平:

传输上似乎存在导致 tx 停顿的锁定问题。

于 2013-11-07T08:42:14.723 回答