粘包问题处理(切片)

本文介绍了一种基于TCP的粘包处理方法,通过自定义的数据包头来解析接收到的数据流,确保数据包的完整性和准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#pragma mark 粘包处理
-(void)stickPackage:(NSData *)recPackage sock:(GCDAsyncSocket *)sock retBlock:(void (^)(NSData *_recData,NSError *err))retBlock{
    int len = 0;
    if(info==NULL ||sizeof(info)==0){
        DLog(@"===============NULL==========");
        unsigned char *pt=(unsigned char *)calloc(1, sizeof(PeerInfo));
        info=(PeerInfo *)pt;
    }
TCPHeader *head = (TCPHeader*)info->pkt;
//unsigned char *pro = info->pkt + kInnerPacketHeadSize;
const char *src = (const char *)[recPackage bytes];
int srclen = [recPackage length];
while(srclen > 0)
{
if(info->writepos < kInnerPacketHeadSize)
{
len = kInnerPacketHeadSize - info->writepos;
if(srclen < len)
len = srclen;
memcpy(info->pkt + info->writepos, src, len);
info->writepos += len;
src += len;
srclen -= len;
}
if(srclen <= 0) //当前调用已经没有足够的数据了
break;
if(info->writepos >= kInnerPacketHeadSize)
{
if(head->dwSignature1 != DWORD_SIGNATURE1 || head->dwSignature2 != DWORD_SIGNATURE2)
{
info->writepos = 0;
DLog(@"签名错误 dwSignature1:%i DWORD_SIGNATURE2:%i 原始签名DWORD_SIGNATURE1:%i 原始签名DWORD_SIGNATURE2:%i",head->dwSignature1,head->dwSignature2,DWORD_SIGNATURE1,DWORD_SIGNATURE2);
return;
}
}
if(info->writepos < kMaxBufferSize) //数据还可以继续拷贝
{
len = kMaxBufferSize - info->writepos;
if(srclen < len)
len = srclen;
if(len + info->writepos > kInnerPacketHeadSize + head->dwLenght)
len = kInnerPacketHeadSize + head->dwLenght - info->writepos;
memcpy(info->pkt + info->writepos, src, len);
info->writepos += len;
src += len;
srclen -= len;
}
if(info->writepos == kInnerPacketHeadSize + head->dwLenght) //数据包已经收齐
{
            HYPacketHead *p=(HYPacketHead *)info->pkt;
            DLog(@"收到命令cmd:%i ",p->cmd);
//AddToProcessList(cc, info);
            if(retBlock){
                if(info==NULL||sizeof(info)==0){
                    DLog(@"info memeroy is null");
                }else{
                    DLog(@"info memeroy is not null");
                }
                
                DLog(@"head->dwlength:%i ",head->dwLenght);
                NSData *pkg=[NSData dataWithBytes:info length:kInnerPacketHeadSize + head->dwLenght];
                NSData *data=[pkg subdataWithRange:NSMakeRange(kInnerPacketHeadSize,head->dwLenght)];
                retBlock(data,nil);
            }
            
info->writepos = 0; //开始处理新的一包数据
}
if(srclen <= 0)
break;
if(info->writepos >= kMaxBufferSize) //缓冲区不够了,不再拷贝
{
len = srclen;
if(len + info->writepos > kInnerPacketHeadSize + head->dwLenght)
len = kInnerPacketHeadSize + head->dwLenght - info->writepos;
info->writepos += len;
src += len;
srclen -= len;
}
if(info->writepos == kInnerPacketHeadSize + head->dwLenght) //数据包已经收齐
{
// AddToProcessList(cc, info);
            HYPacketHead *p=(HYPacketHead *)info->pkt;
            DLog(@"收到命令cmd:%i ",p->cmd);
            if(retBlock){
               NSData *pkg=[NSData dataWithBytes:info length:kInnerPacketHeadSize + head->dwLenght];
                NSData *data=[pkg subdataWithRange:NSMakeRange(kInnerPacketHeadSize,head->dwLenght)];
                retBlock(data,nil);
            }
info->writepos = 0; //开始处理新的一包数据
}
}
if(info->writepos == kInnerPacketHeadSize + head->dwLenght) //数据包已经收齐
{
        HYPacketHead *p=(HYPacketHead *)info->pkt;
        DLog(@"收到命令cmd:%i ",p->cmd);
//AddToProcessList(cc, info);
        if(retBlock){
           NSData *pkg=[NSData dataWithBytes:info length:kInnerPacketHeadSize + head->dwLenght];
            NSData *data=[pkg subdataWithRange:NSMakeRange(kInnerPacketHeadSize,head->dwLenght)];
            retBlock(data,nil);
        }
info->writepos = 0; //开始处理
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值