解决TCP粘包问题

简介: 解决TCP粘包问题

粘包问题已经在上一篇博客中写到具体可以看-----------


以下是利用分包解决粘包问题的步骤:


消息长度前缀: 在每个数据包前加入消息长度信息。


定义协议格式: 明确定义通信协议的格式,包括消息头和消息体。


封包: 将数据按照协议格式封装成完整的数据包。


解包: 根据协议格式从接收到的字节流中解析出完整的数据包。


处理残余数据: 保留可能存在的残余数据,并在下一次接收到数据时继续解析。


错误处理: 考虑数据包丢失、损坏或乱序等特殊情况,实现相应的错误处理机制。


测试和优化: 进行测试以确保系统在不同条件下正常运行,优化协议和分包处理性能


怎么解决粘包问题呢,其实借鉴一下tcp报文段的组成(分成TCP数据部分和TCP首部),我们也可以把发送的数据分为两个部分,一个是data,一个是data_len,这样有了data_len之后可以保证接收到完整的data数据后不再接受数据,这样就解决了粘包的问题。

看见如下图,client端发送的hi 和 jack没有粘在一块成hijack:

server:

int total_len=0;
    int len=0;  
    char buffer[1024];
 
    while ((len=read(client_sock,buffer+total_len,sizeof(buffer)-total_len))>0)
    {
        total_len+=len;
        while (total_len>=sizeof(int))
        {
            int data_len=*(int *)buffer;
            if(total_len>=sizeof(int)+data_len)
            {
                char data[1024];
                memmove(data,buffer+sizeof(int),data_len);
                data[data_len]='\0';
                std::cout<<"Received msg :"<<data<<std::endl;
                total_len-=sizeof(int)+data_len;
                memmove(buffer,buffer+sizeof(int)+data_len,total_len);
            }
            else{
                break;
            }
        }   
    }

client:

std::string msg1="hi";
    std::string msg2="jack";
 
    char data1[256];
    *(int*)(data1)=msg1.length();
    int len=sizeof(int);
 
    memmove(data1+len,msg1.c_str(),msg1.length());
 
 
    if(write(client_sock,data1,len+msg1.length())==-1){
        std::cerr<<"Faild to write "<<std::endl;
        return -1;
    }
 
    char data2[256];
    *(int*)(data2)=msg2.length();
    int len2=sizeof(int);
 
    memmove(data2+len,msg2.c_str(),msg2.length());
 
 
    if(write(client_sock,data2,len2+msg2.length())==-1){
        std::cerr<<"Faild to write "<<std::endl;
        return -1;
    }
相关文章
|
6月前
|
网络协议
|
7月前
|
网络协议 Linux 网络安全
TCP三次握手的相关问题及解答
TCP三次握手的相关问题及解答
62 0
|
网络协议 安全
基于TCP和UDP的Socket通信
TCP是面向连接的,安全的协议,它是一对一的关系 udp是面向无连接的,不安全,不可靠的,但是效率很高,支持一对一,一对多,多对多发送,udp传输的格式为数据报,要将其封装为数据报才能发送,
83 1
|
存储 缓存 网络协议
TCP三次握手详解
TCP是面向连接的协议,它基于运输连接来传送TCP报文段,TCP运输连接的建立和释放,是每一次面向连接的通信中必不可少的过程。
208 0
|
网络协议
TCP三次握手
TCP三次握手
100 0
|
存储 消息中间件 缓存
计网 - TCP 的封包格式:TCP 为什么要粘包和拆包?
计网 - TCP 的封包格式:TCP 为什么要粘包和拆包?
144 0
|
移动开发 网络协议 Java
TCP 粘包/拆包问题
《基础系列》
166 0
TCP 粘包/拆包问题
|
存储 网络协议 算法
|
网络协议 Linux
tcp的三次握手
tcp的三次握手。
183 0
tcp的三次握手
|
网络协议 Linux
tcp的三次握手。
tcp的三次握手。
135 0