随机和偶尔出现的网络错误(NSURLErrorDomain Code=-1001和NSURLErrorDomain Code=-1005)

14
最近几天,我一直在尝试调试d00m的网络错误。我的想法已经用尽了,希望其他SO用户有宝贵的经验可以提供帮助。我希望能够提供所有相关信息,但我个人无法控制服务器环境。
整个问题始于用户注意到我们的应用程序中出现了几个"网络错误"。该错误似乎是随机发生的,与互联网连接、iOS版本或后端更新没有明显的相关模式。两个发生在幕后的错误是: Error Domain=NSURLErrorDomain Code=-1001 "请求超时。" 和更频繁的: Error Domain=kCFErrorDomainCFNetwork Code=-1005 "网络连接丢失。 经过几天的调试,我设法通过向我们的后端发送大约10个随机(GET和POST)请求,并在每个请求之间设置1-20秒的随机睡眠计时器来复制这些错误(随机发生)。然而,它只发生在一段时间内。我最近几天的经历是,当“错误周期”开始时,每次运行代码时我都会得到两种错误中的一种(意味着每10或20个请求中有1个错误率)。这种错误率会持续几个小时,然后错误会消失几个小时,然后重新开始。
关于设置的一些快速事实:
- 在设备和模拟器上发生 - 发生在iOS 8.4和iOS 7.1上 - 尽管v.8.4是我用于测试的主要版本。 - 我们使用NSURLSession进行网络请求。我们还包括了AFNetworking(更新到最新版本),但我们仅使用安全部分进行SSL固定。即使完全关闭SSL固定,错误仍会发生。
我在过去几天中写下的一些发现:
  • 似乎只发生在我们的生产环境中,该环境与我们的演示环境有一些不同的配置。这使我认为它可能与 这里这里 讨论的 keep-alive bug 有关。然而,我们的运维部门设置了一个新的演示环境,发送与生产环境相同的 keep-alive 头信息,但这并没有在演示环境中出现错误。
  • 我们的 Android 应用程序版本使用相同的请求设置无法复现错误。此外,在 Android 应用程序中,我们没有收到任何有关“网络错误”的客户问题。

我的直觉告诉我这与服务器环境和 iOS 中的 HTTP 实现有关。然而,我无法找到一个令人信服的模式来证明任何事情。我已经使用一个简单的 Rails 脚本进行了相同的设置,当下一个“错误周期”发生时,我将准备在 iOS 环境之外尝试复制它。当这发生时,我会更新问题。

我不希望使用重置wifi设置、关闭模拟器或类似的解决方案,因为我认为这在生产环境中不可行。我也考虑过在GitHub问题中提到的重试循环修复,但我认为这是最后的手段。
如果您需要更多信息,请告诉我。

你正在使用WebSocket吗? - Ducky
没有基本的NSURLSessionNSURLSessionDataTask - Steffen D. Sommer
嗨,Steffen,你解决了这个问题吗? - Nada Gamal
@NadaGamal 不好意思,不是的。 - Steffen D. Sommer
2个回答

2
根据我的经验,这种问题通常指的是大量数据包丢失,尤其是在使用蜂窝网络时。即使是微小的多径干扰和其他问题也可能导致数据传输的可靠性出现差异。
我想到的另一个可能性是低质量的NAT实现,如果您的服务器超时时间足够长,会导致NAT放弃TCP连接,但这种情况不太可能发生。
无论哪种情况,唯一确定发生了什么的方法是进行数据包跟踪。为此,请将Mac通过有线连接连接到Internet,启用Wi-Fi上的网络共享,并将iOS设备连接到该Wi-Fi网络。然后运行Wireshark并告诉它监视桥接接口。具体操作请参考此处的说明:

http://www.howtogeek.com/104278/how-to-use-wireshark-to-capture-filter-and-inspect-packets/

从那里,你应该能够看到正在发送什么以及何时发送。这很可能有助于理解为什么它失败了。

谢谢建议 - 我一定会研究这个并回复您,如果它最终解决了谜团。 - Steffen D. Sommer

0

好的,我花了很多时间调查类似的问题。

1005可能是由已知的iOS bug引起的,有几个解决方法。例如添加头部"Connection",值为"close"。 更多信息

1001是另一回事。在我的情况下,问题是服务器上奇怪(坏?)的防火墙。当短时间内有许多(不是很多)请求时,它会禁止设备。

我相信如果你遇到类似的问题,你可以进行简单的测试。

  1. 发送大量请求(取决于防火墙设置)循环执行(假设每秒50次)。
  2. 关闭/杀死应用程序(这将关闭与服务器的连接)
  3. (可选)等待一段时间(假设60秒)
  4. 重新启动应用程序并尝试发送请求

如果您现在对所有后续请求都超时,那么您可能有相同的问题,您应该与服务器人员交谈。

注意:如果您无法访问服务器,则可以向用户提供信息,要求他重新启动设备上的 WiFi 以退出超时循环。在某些情况下,这可能是最后的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接