ios - GCDAsyncSocket readDataWithTimeout 和 didReadData 正在截断大于 1460 字节(1 个数据包)的传入数据字符串

标签 ios gcdasyncsocket

我的 iOS 应用正在使用 GCDAsyncSocket 从服务器接收数据。服务器每分钟收集一次外部数据。该应用程序定期连接到服务器,并接收此数据。服务器会跟踪已发送的内容,因此每分钟的数据只会发送一次。服务器只保留最后一小时的数据。每分钟的数据是一个大约 100 字节(+/- 20 字节)的字符串。

接收字符串,分分钟,每分钟分到每分钟数据中的各种数量。

如果应用超过一小时未连接到服务器,应用将下载 60 分钟的数据。发生这种情况时,我只能获得大约 15 分钟的数据。我追踪到这个事实,即方法 readDataWithTimeout 只在 readQueue 上加载一个数据包,这将我限制为 1460 字节。我发现当我向队列中添加第二个数据包时,我又得到了 1460 字节的数据。如果字符串是它们的最大长度,并且我正在下载 60 个字符串,那么 5 个数据包就足以捕获所有内容。

  1. 如果我向读取队列中添加的数据包比需要的多,而且大多数读取只使用一个数据包,我最终会溢出数据包队列吗?我可以应用某种超时来清除未使用的数据包吗?应用无法预测任何给定读取事件需要多少数据包。

另一个问题是一个数据包的最后一分钟的数据字符串将不可避免地分成两个数据包。我想做的是收集所有数据包的 NSData 实例,将它们连接成一个大的 NSData 实例,将其转换为字符串,然后正常解析该字符串。

  1. 我如何知道何时接收到给定读取请求的最后一个数据包,以便我可以组合 NSData 并解析结果字符串? 每分钟的字符串都以感叹号“!”结尾,但没有唯一的符号来表示传输结束。我假设解决问题 1 的相同超时将解决问题 2。

此应用已针对 Android 发布。因此,如果可能的话,我想避免更改服务器和 Android 代码以适应 iOS 版本。

最佳答案

我最终每次请求读取时只向 readQueue 添加 5 个数据包,并为读取添加附加超时,这样队列就不会溢出。我还设置了一个 NSTimer 在 didReadData 回调结束后 2 秒后触发。当计时器超时时,假设所有可用数据都已读取,并且字符串已处理。每个计时器都使用相同的 NSTimer 实例,因此如果计时器处于事件状态,并且发生另一个 didReadData 事件,则会启动一个新计时器,清除旧计时器。

关于ios - GCDAsyncSocket readDataWithTimeout 和 didReadData 正在截断大于 1460 字节(1 个数据包)的传入数据字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10439730/

相关文章:

ios - GCDAsyncUdpSocket 无法在 iOS 模拟器上绑定(bind)端口

java - GCDAsyncsocket广播到所有IP

ios - UICollectionView 中的单元格重叠

ios - 如何为 UITableView 标题设置颜色文本颜色

ios - 无法构建模块基础

ios - GCDAsyncSocket 委托(delegate)调用不起作用

ios - 无法使用 GCDAsyncSocket 接收已发送 UDP 数据包的响应

ios - 谷歌通讯录 OAUTH2

ios - 禁用 UIButton 的高亮 UIControl 状态

objective-c - 为什么GCDAsyncSocket readData设计成只读一次?