我有一部 Android 智能手机,通过 WIFI 连接到嵌入式 AP。我正在使用 Linux 上运行 Tshark 的笔记本电脑嗅探 WIFI 流量。我每 100 毫秒传输小(234 字节)TCP 数据包 5 次,然后是 500 毫秒,没有数据。数据包将定期被忽略,从而强制重新传输。通过 TCP 套接字传输数据时,预计会出现一定程度的数据包重传,但这已经过多了。特别是因为嗅探器毫无问题地接收了数据包(即,没有“飞行中”损坏),并且后续重新传输的数据包也会被 android 忽略(丢弃)。
请注意:当我说“忽略”时,我的意思是我没有看到any来自接收无线电 (802.11 ACK) 或来自 Wireshark 跟踪中的接收 TCP 堆栈 (TCP ACK) 的确认。下图中,数据包599
立即被确认,而下一个数据包(606)被忽略,接下来的四次重传(607-610)也是如此。
Wireshark日志 https://i.stack.imgur.com/ElUCh.png
在 Android v4.x(已测试 4.0.4 和 4.2.2)上运行的相同 APK 以及在 iOS 上运行的类似应用程序上都不会发生这种情况。在这两种情况下,都会出现预期丢弃的 TCP 数据包,然后重传,但几乎总是立即得到确认。
由于我正在传输的数据包没有什么特别之处,并且 TCP 数据包的无缝重传有望在某种程度上解决数据包丢失问题,因此我怀疑许多应用程序都遇到了同样的问题,但只是接受总体传输速率的降低,归因于传输速度较慢为“WIFI拥塞”。
就我而言,WIFI 硬件/固件解决方案(由第三方提供)因 TCP 积压过多而堵塞。他们有一个带有创可贴修复的新解决方案,似乎有助于恢复,但这并不能解决现场已有硬件的问题。
我相信在 android 5.x 下发生了一些变化,例如无线电会定期关闭或移出频道。由于它似乎定期发生,我认为这可能是由于信道扫描造成的(期望在扫描间隔期间丢失的任何数据包都将在无线电返回时通过重传来恢复)。我无法找到 Android 通道扫描行为的明确定义(我有一篇单独的文章对此进行了阐述)。
当失败时,将以 4 或 5 个数据包的突发形式重传,中间间隔几毫秒,然后 1 秒内没有任何内容,然后是另一个突发。通常,重传的数据包会被忽略一段时间(可能是几秒)。最终,重传数据包得到确认,并继续传输下一个数据包。
我注意到还发生了定期的 DNS 探测(下面是通过 DNS 查询定期探测的 URL 列表)。有些可能是已安装的应用程序,而另一些可能是操作系统(例如,“connectivitycheck.android.com”可能会用于验证 AP 是否确实提供互联网连接,但在我的情况下则不提供)。
android.clients.google.com
android.googleapis.com
clients3.google.com
cmdts.ksmobile.com
connectivitycheck.android.com
graph.facebook.com
mtalk.google.com
px.demdex.net
weather.ksmobile.com
px.demdex.net 条目引起了我的注意,因为我不知道它代表谁。原来是Adobe。由于明显有一些我不知道的代码在主动探测,并且为了确保我的问题纯粹是 Android 问题,我将 Nexus 4 智能手机恢复出厂设置,并拒绝任何可能与 WIFI 通信问题有关的初始化选项(例如例如 Google 位置服务,即使关闭时也允许使用 WIFI 等)。 TCP 数据包仍然被丢弃。
在android方面,我有:
- 将位置设置为“仅限设备”(GPS)
- 禁用 WIFI“扫描始终可用”
- 每当套接字打开时,就在应用程序内获取“WIFI_MODE_FULL_HIGH_PERF”锁。
- 当应用程序开始通信时套接字打开,并保持打开状态直到应用程序关闭。如果一段时间内没有数据包出现(当前为 3 秒),应用程序将关闭套接字并打开一个新套接字,以尝试强制重新建立通信。
我发现了 IWifiManager 的“setAllowScansWithTraffic()”函数,听起来它会给我扫描的明确控制(从列表中删除这种可能性),但似乎实现这个会很困难,并且不能成为我的一部分应用程序 (?)。我相信 IWifiManager 为 android 实现者提供了一个存根来构建他们自己的 WIFI 管理器(操作系统)服务,并且它不打算在应用程序级别使用。
我将不胜感激任何意见/建议。
UPDATE
在寻找“通道扫描”可能性时,我用数据包嗅探器在 WIFI 通道 3 上记录了 ACK 数据包,而被测硬件在 WIFI 通道 8 上运行。这可以解释丢失的 ACK - 它们是在错误的 WIFI 通道上发送的。我已经开了一个安卓错误 https://code.google.com/p/android/issues/detail?id=189016