AsyncSocket:合并两个数据包而不是单独的两个数据包
Posted
技术标签:
【中文标题】AsyncSocket:合并两个数据包而不是单独的两个数据包【英文标题】:AsyncSocket: getting merged two packets instead of separate two packets 【发布时间】:2012-02-20 10:10:54 【问题描述】:我正在执行 4 个启动命令,并希望收到 4 个响应。服务器已经实现,另一个正在开发 android 的开发人员能够接收这 4 个单独的响应,但是,我得到了 2 个好的响应(单独的),然后第 3 个和第 4 个响应作为一个响应出现。我已将 NSData 结果的 NSLog 放在 completeCurrentRead 中,它输出我合并的数据包“0106000000000b0600000000”,而不是单独的数据包“010600000000”和“0b0600000000”。我还分别测试了第 3 和第 4 个命令(一次只有一个),服务器一切正常,它单独发送它们,但是如果所有四个命令都在一行中执行,则会发生合并(第 3 和第 4 个) .有什么想法吗?
更新:我想我已经找到了问题的根源。 doBytesAvailable 方法中有一个从流中读取数据包数据的调用:
CFIndex result = [self readIntoBuffer:subBuffer maxLength:bytesToRead];
而在 readIntoBuffer:maxLength 中,有一个调用 (length == 256):
return CFReadStreamRead(theReadStream, (UInt8 *)buffer, length);
因此,CFReadStreamRead 返回的数据包长度不正确 - 它返回长度为 12(而不是 6),并且还抓取合并数据。嗯,是什么原因导致 CFReadStreamRead 将两个数据包读取为一个,而不是分别读取它们......
UPDATE2:我正在使用 onSocket:didReadData:withTag: 委托方法并期望接收带有我执行的请求标记的响应数据。我最近意识到,流是流,而不是数据包,但我该如何解决呢?服务器响应在响应的开始和结束时没有终止字符,只有响应大小,即 2 - 5 个字节。我可以剪切响应的第一部分(第一个数据包)并忽略第二部分,但是 AsyncSocket 将如何使用响应的第二部分(第二个数据包)进行另一个回调?如果我只剪掉第一部分而忽略第二部分,那么恕我直言,第二个“数据包”将会丢失......
如何剪切响应的第一部分并告诉 AsyncSocket 使用标签进行另一个回调,并将响应的第二部分作为单独的回调?
UPDATE3:在 onSocket:didReadData:withTag: 中,我手动剪切合并响应,处理第一部分(第一个数据包),然后在最后再次调用 onSocket:didReadData:withTag::
if (isMergedPacket)
...
[self onSocket:sock didReadData:restPartOfTheResponse withTag:myCommandTag];
但是,看起来 AsyncSocket 本身使用标签将每个请求数据包与其响应数据包(通过 AsyncReadPacket 类)配对。所以,我的手动切割工作,但 AsyncSocket 不知道我已经处理了两个数据包,它仍然尝试读取第二个数据包。所以,我得到了 sock:shouldTimeoutReadWithTag:... 回调,当读取操作在未完成的情况下达到超时时调用。
【问题讨论】:
【参考方案1】:找到解决方案。无需更改和深入研究 AsyncSocket。您只需要定义每个响应的长度 - 您对读取和获取回调感兴趣的字节数。更多信息您可以在其他帖子here
【讨论】:
以上是关于AsyncSocket:合并两个数据包而不是单独的两个数据包的主要内容,如果未能解决你的问题,请参考以下文章
为啥 traceroute 发送 UDP 数据包而不是 ICMP 数据包?
iOS AsyncSocket 通知两个 UIViewController