tcp-数据包

我们往往使用tcp协议传输数据,都会自定义一个包裹,本次分享下对包的理解,其基本结构如下:

在发送端,我们只需要将完整的包裹一次发送出去即可,eg

    // 字节
    QByteArray bytes;    
    
    PackageInfo info;
    info.exUse_int = 1000;
    info.exUse_char = '1';
    // bodyLen 非定长
    info.dataSize = buffer.size();

    QDataStream stream(&bytes,QIODevice::WriteOnly);
    // head
    stream << info.exUse_int << info.exUse_char << info.dataSize;
    // body
    bytes.append(buffer.data());
 
    socket->write(bytes);

接受时,由于发送端告知发送的数据总字节数,以及body字节数,所以我们可以在接受端判断接收,直到完整接收。

    if(bytesAvailable() <= 0)
    {
        return;
    }
    // 总缓存,每次不满就存入,清空问题待处理
    static QByteArray bytes; 

    // head,定长
    const static int headLen = sizeof(unsigned int) + sizeof(unsigned char) + sizeof(qint64);

    QByteArray t_bytes = readAll();
    bytes.append(t_bytes);
    if(bytes.size() < headLen)
    {
        // 继续缓存
        return;
    }

    // head已经完整get,获取真实数据长度
    PackageInfo info;
    QDataStream stream(&bytes, QIODevice::ReadOnly);
    stream >> info.exUse_int >> info.exUse_char >> info.dataSize;

    // 读满
    if(bytes.size() < info.dataSize + headLen)
    {
        // 继续缓存
        return;
    }

    // bodyData
    QByteArray dataBytes = bytes.right(bytes.size() - headLen);
    
    // to do

我们一次发送很大的包裹,接收时是多次的,因为,像tcp这种水龙头流水,你用杯子接水,至于你接了多少水不可控。因此我们使用静态变量存储,或者成员变量,每次填充到缓存中并比较要接收的大小,直到完整get即可。这里就是告诉客户端,你需要接收多大,一个完整的包裹。

关于Tcp协议,粘包问题,等仍需要处理。至于涉及的高并发等深入问题仍需要学习。

猜你喜欢

转载自blog.csdn.net/qq_39175540/article/details/85698856
今日推荐