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:合并两个数据包而不是单独的两个数据包的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个单独的 javascript 合并为一个?

视图被合并而不是单独显示

为啥 traceroute 发送 UDP 数据包而不是 ICMP 数据包?

iOS AsyncSocket 通知两个 UIViewController

如何将两个jrxml jasper报告合并为一个单独的pdf输出文件

AsyncSocket 连接仅适用于家庭网络