tcp接收数据时遇到的几个问题:
1. 数据一直收不全。
2.从服务器收到的数据为 NSData 协议格式 json+\r\n+二进制数据 , json会提供二进制数据的长度,但Json数据有时候解析不出来。
问题1:
原因:服务器端分次返回数据,需要一直等待。
解决方法:在didReadData 中加入
[sock readDataWithTimeout:-1 tag:0];
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(@"socket didReadData %lu",data.length);
// 数据处理
[sock readDataWithTimeout:-1 tag:0];
}
问题2:
原因:服务器端会随机分几次返回数据,有时候返回的数据刚好是Json+\r\n,这部分NSData可以转成NSDictionary 解析接收后面的数据。没有问题
有时候,返回的数据刚好是 json+\r\n+部分/全部二进制数据,这样NSData不能转NSDictionary,需要先把前面的json分离出来,再转。
解决方法:
根据格式 Json+\r\n+二进制数据,要获取前面部分的json 需要找到NSData中的“}\r\n”的位置,再拿到前面部分的NSData,就可以转了。
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSRange rangeToSearchWithin = NSMakeRange(0, [data length]);
NSRange rang = {0,0};
rang = [data rangeOfData:xmlData options:(NSDataSearchOptions)NULL range:rangeToSearchWithin];
if (0 != rang.location && xmlData.length == rang.length) {
//解析出来有Json数据
NSData *dataJson = [data subdataWithRange:NSMakeRange(0, rang.location + rang.length)];
NSData *dataBinary;
if ( [data length] > (rang.location + rang.length)) {
//解析出二进制
dataBinary = [data subdataWithRange:NSMakeRange(rang.location + rang.length, ([data length] - (rang.location + rang.length)))];
}
NSDictionary *content = [NSJSONSerialization JSONObjectWithData:dataJson options:NSJSONReadingMutableContainers error:nil];
NSLog(@"$$$$$$content ,%@",content);
}
else {
//没有json数据,只有二进制数据
}
[sock readDataWithTimeout:-1 tag:0];