CocoaAsyncSocket和从套接字读取数据

在我基于TCP套接字的服务器上,我发送了一个数据包,数据包由一个指定数据包中的字节数的头部组成,然后是这个字节数。 对于那些熟悉Erlang的人,我只是设置{packet,4}选项。 在iOS端,我看起来像这样的代码,假设我想知道这个消息的stream的大小:

[asyncSocket readDataToLength:4 withTimeout:-1 tag:HEADER_TAG]; 

这工作正常,并调用下面的委托方法callback:

 onSocket:didReadData:withTag: 

我想下一个合乎逻辑的步骤是计算出stream的大小,我这样做:

  UInt32 readLength; [data getBytes:&readLength length:4]; readLength = ntohl(readLength); 

在服务器端对12个字节的string进行硬编码之后,readLength确实也在客户端读取了12个字节,所以目前为止都是很好的。 我继续以下内容:

  [sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG]; 

此时尽pipeonSocket:didReadData:withTag:的callback不再被调用。 读取时发生超时,可能是因为我没有正确处理读取操作,这个委托方法被调用:

 - (NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length 

所以服务器总共发送了16个字节,一个4字节的标题和一个12字节的二进制stream。

我相信,错误是我如何使用CocoaAsyncSocket。 在了解其尺寸之后,阅读其余部分stream程的正确方法是什么?

**更新**

我改变了我的客户,似乎现在正在工作。 问题是,我不明白新解决scheme的readDataToLength点。 这是我改变我的初步阅读:

 [socket readDataWithTimeout:-1 tag:HEADER_TAG]; 

现在在我的callback中,我只是做了以下几点:

 - (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]; } } 

因此,所有的东西都是primefaces有效载荷。 也许这是因为Erlang {packet,4}的工作原理。 我希望是的。 否则,readDataToLength有什么意义? 在客户端上没有办法知道消息的长度,那么使用这个方法的好用例是什么?

这取决于你如何从Erlang方面,我想。 选项{packet, 4}将发送每个数据包的前缀长度为4个字节。 Erlang中的每个发送操作都将导致发送一个长度为前缀的数据包(最大长度为4 ,例如2 Gb)。 Erlang文档的相关部分是使用inet:setopts/2设置套接字选项 。

我猜测数据是迄今从套接字读取的总累计数据。 如果这些数据包含您的整个数据包,那就没问题了。 但是,如果没有,您可能希望继续使用readDataToLength和其余数据从套接字进行阻塞式读取。