0%

如何解决TCP粘包问题

[TOC]

TCP粘包问题

  • TCP数据粘包是指发送方连续发送多个数据包时,接收方在接收时会将多个数据包粘成一个大的数据包,造成数据处理上的困难。
  • 首先回忆一下,TCP的三大特点:面向连接、可靠的、基于字节流的。
  • 显然,问题出在TCP是基于字节流的,所以并不会明确TCP包的边界。而UDP是基于包的,所以不会出现这个问题。

解决的方法

总的原则:既然没有边界,那么加上边界识别的机制那就完活了。

  1. 设置消息边界:在消息的末尾添加特殊字符或者标志符号,在接收方收到消息时根据特殊字符或标志符号来分隔消息。

  2. 消息长度:在消息的开头添加消息长度信息,在接收方接收到消息时先读取消息长度,再读取对应长度的消息内容。

  3. 延迟发送:发送方在发送数据时,可以采用延迟发送的方式,即等待一段时间再发送,以此避免多个数据包同时发送造成粘包。

  4. 使用固定长度的数据包:发送方发送固定长度的数据包,接收方按照固定长度来接收数据包,以此避免粘包问题。

    举例:在Qt中,可以通过设置socket的读取缓存区大小、设置消息边界符号、消息长度信息等方式来防止TCP数据粘包。例如,可以使用以下代码设置消息边界符号:

    1
    2
    3
    4
    QTcpSocket *socket = new QTcpSocket(this);
    socket->setReadBufferSize(1024); //设置读取缓存区大小为1024字节
    socket->write("message1\n"); //发送消息1
    socket->write("message2\n"); //发送消息2

    在接收方,可以使用以下代码来接收数据并根据消息边界符号分隔消息:

    1
    2
    3
    4
    5
    while (socket->bytesAvailable() > 0) {
    QByteArray data = socket->readLine(); //读取一行数据
    QString message = QString(data).trimmed(); //去除换行符
    //处理接收到的消息
    }

参考资料

[1]:https://blog.csdn.net/future_ai/article/details/130192182 “参考链接1”