GCDAsyncSocket解決粘包問題
發(fā)送端??
數(shù)據(jù)源頭部添加文字總數(shù)
- (void)sendMessage:(NSString *)message{
?NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
?data = [self addTotalLengthToData:data];
?[socket writeData:data withTimeout:-1 tag:0];
?[socket readDataWithTimeout:-1 tag:0];?
}
- (NSData *)addTotalLengthToData:(NSData *)data{
? ? NSMutableData *sendData = [NSMutableData data];
? ? // 獲取數(shù)據(jù)長度
? ? NSInteger datalength = data.length;
? ? //? NSInteger長度轉(zhuǎn) NSData
? ? NSData *lengthData = [NSData dataWithBytes:&datalength length:sizeof(datalength)];
? ? // 長度幾個字節(jié)和服務(wù)器協(xié)商好诺凡。這里我們用的是4個字節(jié)存儲長度信息
? ? NSData *newLengthData = [lengthData subdataWithRange:NSMakeRange(0,4)];
? ? // 拼接長度信息
? ? [sendData appendData:newLengthData];
? ? //拼接數(shù)據(jù)
? ? [sendData appendData:data];
? ? return sendData;
}
接收端
- (void)socket:(GCDAsyncSocket*)sockdidReadData:(NSData*)datawithTag:(long)tag{
? ? ? ? [_locklock];
? ? ? ? ? ? NSMutableData *readBuf = self.clientReadBuf;
? ? ? ? ? ? [self LYHandleDidReadData:data socket:sock readBuf:readBuf];
? ? ? ? [_lockunlock];
}
- (void)LYHandleDidReadData:(NSData*)data socket:(GCDAsyncSocket*)sock readBuf:(NSMutableData*)readBuf{
? ? //將數(shù)據(jù)存入緩存區(qū)
? ? [readBuf appendData:data];
? ? NSMutableArray *saveCompleteDataArray = [NSMutableArray array];
? ? // 如果長度大于4個字節(jié)蝇刀,表示有數(shù)據(jù)包珊佣。4字節(jié)為包頭,存儲包內(nèi)數(shù)據(jù)長度
? ? while(readBuf.length>=4) {
? ? ? ? NSInteger? datalength =0;
? ? ? ? // 獲取包頭,并獲取長度
? ? ? ? [[readBuf subdataWithRange:NSMakeRange(0,4)]getBytes:&datalength length:sizeof(datalength)];
? ? ? ? //? 判斷緩存區(qū)內(nèi)是否有包
? ? ? ? if(readBuf.length>= (datalength+4)) {
? ? ? ? ? ? // 獲取去掉包頭的數(shù)據(jù)
? ? ? ? ? ? NSData*realData = [[readBuf subdataWithRange:NSMakeRange(4, datalength)] copy];
? ? ? ? ? ? // 解析處理
? ? ? ? ? ?[saveCompleteDataArray addObject:realData];
? ? ? ? ? ? // 移除已經(jīng)拆過的包
? ? ? ? ? ? readBuf = [NSMutableData dataWithData:[readBuf subdataWithRange:NSMakeRange(datalength+4, readBuf.length- (datalength+4))]];
? ? ? ? }else{
? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? ?self.clientReadBuf= readBuf;
? ? //查看有多少包? saveCompleteDataArray為解析的數(shù)據(jù)
?????NSLog(@"saveCompleteDataArray.count---%ld", saveCompleteDataArray.count);
? ? [sock readDataWithTimeout:-1 tag:0];
}