在我的基于TCP套接字的服务器上,我通过流发送数据包,其中数据包由一个标头指定数据包中的字节数,然后是该字节数。对于那些熟悉Erlang的人,我只需设置{packet,4}选项。在iOS方面,我有一些代码看起来是这样的,假设我想找出流的大小此消息:CocoaAsyncSocket和从套接字读取数据
[asyncSocket readDataToLength:4 withTimeout:-1 tag:HEADER_TAG];
这工作正常及以下的委托方法调用回调函数:
onSocket:didReadData:withTag:
我图下一逻辑步骤是找出流的大小,以及我做到这一点与:
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
后硬编码的在服务器侧12个字节的串,读数长度确实我ndeed在客户端也读了12,所以迄今为止都是很好的。我继续执行以下:
[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
此时虽然回调onSocket:didReadData:withTag:
不再调用。相反超时在读正在发生,可能是因为我没有处理的正确读取,此委托方法被调用:
- (NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
所以在总体上,服务器发送16个字节,4字节的报头和12字节二进制流。
我相信这个错误是关于我如何使用CocoaAsyncSocket。在了解其尺寸后,阅读其余部分流程的正确方法是什么?
**更新**
我改变了我的客户,它似乎现在工作。问题是,我不明白新解决方案的readDataToLength的意义。这是我改变了我最初的念想:
[socket readDataWithTimeout:-1 tag:HEADER_TAG];
现在,在我的回调,我只是做到以下几点:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
if (tag == HEADER_TAG) {
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
int offset = 4;
NSRange range = NSMakeRange(offset, readLength);
char buffer[readLength];
[data getBytes:&buffer range:range];
NSLog(@"buffer %s", buffer);
//[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
} else if (tag == MESSAGE_TAG) {
//[sock readDataToLength:4 withTimeout:1 tag:HEADER_TAG];
}
}
所以一切都进来为一体,有效载荷原子。也许这是因为Erlang {packet,4}的工作原理。我希望是。否则,readDataToLength有什么意义?没有办法在客户端事先知道消息的长度,那么使用该方法的好用例是什么?