GCDAsyncSocket接收数据连包无法解析的问题
2014-07-26 11:06
519 查看
最近在使用GCDAsyncSocket进行socket通信的工作,调试发现总是莫名的出现数据成功接收但是解析不成的情况,经分析发现一个可能性:
socket发送数据的时候会自动分包处理的,导致数据完整性验证失败。
未修复代码如下:
备注:
接收到的数据头4个字节表示实体数据的长度
这样写的问题明显问题是,缓存数据_responseData中可能存在一个完整的数据包和半个数据包,这样完整性验证肯定是失败,导致解析失败
修复后的代码如下:
socket发送数据的时候会自动分包处理的,导致数据完整性验证失败。
未修复代码如下:
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { ITTDINFO(@"didReadData tag %ld", tag); [_responseData appendData:data]; if ([_responseData length] > 4 && [_responseParser validateData:_responseData]) { NSData *data = [_responseData copy]; [self parseData:data]; _responseData = [NSMutableData data]; [_asyncSocket readDataWithTimeout:READ_TIME_OUT tag:READ_TAG]; } else { [_asyncSocket readDataWithTimeout:READ_TIME_OUT tag:READ_TAG]; } }
备注:
接收到的数据头4个字节表示实体数据的长度
- (BOOL)validateData:(NSData*)responseData 验证接收到数据的完整性
这样写的问题明显问题是,缓存数据_responseData中可能存在一个完整的数据包和半个数据包,这样完整性验证肯定是失败,导致解析失败
修复后的代码如下:
- (NSData*)hasCompleteData { NSData *completeData = nil; if ([_responseData length] > 4) { NSInteger lengthBytes = 4; NSInteger headLength = [_responseParser headLength:_responseData]; NSInteger leftLength = [_responseData length] - lengthBytes; if (leftLength >= headLength) { completeData = [_responseData subdataWithRange:NSMakeRange(0, headLength + lengthBytes)]; NSData *leftData = [_responseData subdataWithRange:NSMakeRange(headLength + lengthBytes, leftLength - headLength)]; _responseData = [[NSMutableData alloc] initWithData:leftData]; } } return completeData; } - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { ITTDINFO(@"didReadData tag %ld", tag); [_responseData appendData:data]; @synchronized(_responseData) { NSData *completeData = nil; while ((completeData = [self hasCompleteData])) { //一直从缓冲区里读获取完整的数据包,进行解析 [self parseData:data]; } [_asyncSocket readDataWithTimeout:READ_TIME_OUT tag:READ_TAG]; } }
相关文章推荐
- 同一个Socket实例第二次无法接收服务端数据!! (暂时占用一下首页,请多包涵,该问题困扰我两天了)
- GCDAsyncUdpSocket 组播监听端口接收数据
- GCDAsyncSocket接受数据丢包的问题
- GCDAsyncSocket 接收不到数据
- iOS学习笔记4-GCDAsyncUdpSocket的使用(实现异步发送接收数据)
- PHP接收IOS post过来的json数据无法解析的问题
- ViewPager+Fragment切换时无法更新数据问题解析(源代码分享)
- android平台通过socket向C++服务器端发送数据和接收数据的相关问题
- 异步Socket接收数据后缓存处理问题
- GCDAsyncUdpSocket添加数据发送超时时间
- android平台通过socket向C++服务器端发送数据和接收数据的相关问题
- Socket Receive数据一次性接收不全的问题
- socket 网络接收数据问题(0X00问题)
- IE6中运行EXTJS中某些组件无法解析DOMINO产生的JSON数据问题的解决办法
- .net C# 异步socket ,监听和接收数据时可能会引起的 无法访问已释放的对像异常.捕捉处理.
- Python中使用socket发送HTTP请求数据接收不完整问题解决方法
- 解决VS2010使用mscomm控件无法接收数据的问题
- 通过socket接收数据并进行解析内存数据
- 使用DefaultHandler无法完全解析XML的CDATA数据的问题
- 关于无法解析的外部符号 的错误问题 socket