2019-11-19

GCDAsyncSocket解决粘包问题

发送端  

数据源头部添加文字总数

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

    // 获取数据长度

    NSInteger datalength = data.length;

    //  NSInteger长度转 NSData

    NSData *lengthData = [NSData dataWithBytes:&datalength length:sizeof(datalength)];

    // 长度几个字节和服务器协商好。这里我们用的是4个字节存储长度信息

    NSData *newLengthData = [lengthData subdataWithRange:NSMakeRange(0,4)];

    // 拼接长度信息

    [sendData appendData:newLengthData];

    //拼接数据

    [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{

    //将数据存入缓存区

    [readBuf appendData:data];

    NSMutableArray *saveCompleteDataArray = [NSMutableArray array];

    // 如果长度大于4个字节,表示有数据包。4字节为包头,存储包内数据长度

    while(readBuf.length>=4) {

        NSInteger  datalength =0;

        // 获取包头,并获取长度

        [[readBuf subdataWithRange:NSMakeRange(0,4)]getBytes:&datalength length:sizeof(datalength)];

        //  判断缓存区内是否有包

        if(readBuf.length>= (datalength+4)) {

            // 获取去掉包头的数据

            NSData*realData = [[readBuf subdataWithRange:NSMakeRange(4, datalength)] copy];

            // 解析处理

           [saveCompleteDataArray addObject:realData];

            // 移除已经拆过的包

            readBuf = [NSMutableData dataWithData:[readBuf subdataWithRange:NSMakeRange(datalength+4, readBuf.length- (datalength+4))]];

        }else{

            break;

        }

    }

     self.clientReadBuf= readBuf;

    //查看有多少包  saveCompleteDataArray为解析的数据

     NSLog(@"saveCompleteDataArray.count---%ld", saveCompleteDataArray.count);

    [sock readDataWithTimeout:-1 tag:0];

}

你可能感兴趣的:(2019-11-19)