您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页iOS 智能家居 TCP连接 粘包与断包处理

iOS 智能家居 TCP连接 粘包与断包处理

来源:二三四教育网

在tcp连接中 难免会出现粘包和断包的现象,这样我们就无法获取到正确的信息,所以在开发过程中我们要对数据粘包和断包进行处理,拿到我们想要的数据

数据包格式.png

示例:FC 000C 0001 112233445566 01 0010 FF 94
假如这就是我们想要拿到的正确数据

LEN0和LEN1是数据长度
首先我们要先打拿到整个数据的长度 000C是一个16进制数,转换成十进制就是12。
这里的12指的是数据本身的长度,不是转换成字符串的长度,字符串的长度是24。
所以内容数据就是 0001 112233445566 01 0010 FF
最后的94是校验码

所以我们需要根据内容数据的长度12去拿取正确的数据

代码如下

//存储TCP连接接收的数据 用于解决粘包、断包问题
@property (strong, nonatomic) NSMutableData *readBuf;

在接收到数据方法里进行处理

FC 000C 0001 112233445566 01 0010 FF 94

//处理粘包与断包
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    
    _readBuf = [NSMutableData dataWithData:data];
    
//    NSLog(@"直接得到的数据%@",_readBuf);
    while (_readBuf.length >= 3) {
        //长度数据 000C
        NSData *lengthData = [_readBuf subdataWithRange:NSMakeRange(1, 2)];
        //内容长度 12
        NSInteger length = [[self toHexstring:[self dataToString:lengthData]] integerValue];
        //一个包的完整长度 加上开头的FC000C和最后的校验码94
        NSInteger complateDataLength = length + 4;
        if (_readBuf.length >= complateDataLength) {//够一个整包长度
            //截取一个包的长度(解决粘包)
            NSData *complateData = [_readBuf subdataWithRange:NSMakeRange(0, complateDataLength)];
            //处理数据
            [self handleTcpResponseData:complateData];
            //从缓存中截掉处理完的数据,继续循环
            _readBuf = [NSMutableData dataWithData:[_readBuf subdataWithRange:NSMakeRange(complateDataLength, _readBuf.length - complateDataLength)]];
        } else {//如果缓存中的数据长度不够一个包的长度,则包不完整(处理半包,继续读取)
            [sock readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
            return;
        }
        //缓存中数据都处理完了,继续读取新数据
        [sock readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
    }
}

handleTcpResponseData方法是自己写的处理数据方法。

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务