【问题标题】:Tcp packets using QTcpSocket使用 QTcpSocket 的 Tcp 数据包
【发布时间】:2015-01-10 15:29:46
【问题描述】:

我知道 TCP 保证所有数据包都会到达。但是一个数据包可以分成2个或更多吗?我正在使用带有类 QTcpSocket 的 Qt,我想知道只有当完整数据包到达时才会发出 ReadyRead() 信号。或者换句话说,以第一个字节发送数据包大小然后在循环中等待直到所有字节都到达是否有任何意义?或者我可以打电话给socket->readAll(),我必须得到一整包?

【问题讨论】:

  • TCP 通信是基于流的。在用户模式程序中,您无权访问物理数据包。您需要实现流解析逻辑。例如,如果发送方发送 12 和 34,接收方可能会将它们读取为 12 34 或 1234 或 1 2 3 4 或 123 4 等。您的程序必须正确处理所有这些情况。

标签: qt tcp


【解决方案1】:

如果发送大量数据,数据包可能会分批到达。或者,可以在一个 readyRead 槽中接收多条消息。

最好通过将第一个字节设置为将要发送的字节数来控制这一点。然后,在 readyRead 中,您读取第一个字节并将数据附加到缓冲区,直到收到预期的数据量。

在接收数据时,这也意味着如果在一次调用readyRead()中接收到多条消息,你可以知道第一条消息在哪里结束,下一条从哪里开始。

这是一个在 readyRead function() 中接收数据的客户端示例

void MyClass::readyRead()
{
    // m_pConnection is a QTcpSocket

    while(m_pConnection->bytesAvailable())
    {
        QByteArray buffer;

        int dataSize;
        m_pConnection->read((char*)&dataSize, sizeof(int));
        buffer = m_pConnection->read(dataSize);

        while(buffer.size() < dataSize) // only part of the message has been received
        {
            m_pConnection->waitForReadyRead(); // alternatively, store the buffer and wait for the next readyRead()
            buffer.append(m_pConnection->read(dataSize - buffer.size())); // append the remaining bytes of the message
        }

        QString msg(buffer); // data in this case is JSON, so we can use a QString
        emit Log(QString("\tMessage Received: %1").arg(msg));

        // Do something with the message
        ProcessMessage(msg);
    }
}

【讨论】:

  • 只有一个字节可能有点小(只有 255 大小)一个 int 有更多的空间
  • @ratchetfreak,说得好,当然这取决于发送的数据是什么
  • waitForReadyRead 函数在此示例中没有预期的效果。该函数的文档说,如果您在连接到 readyRead 信号的插槽内调用 waitForReadyRead(),即使返回 true,该信号也不会被发送。 doc.qt.io/qt-4.8/qiodevice.html#readyRead
  • @mastash3ff 它按预期工作并且文档是正确的。如果从readyRead 槽内调用,readyRead 槽将不会在waitForReadyRead 返回 true 时再次进入。如果它确实再次进入readyRead 函数,当数据可用时,此代码将无法按预期工作。 waitForReadyRead 是一个阻塞函数,不需要事件循环。
  • 可以任意拆分数据包与发送的数据量无关没有任何迹象表明只有在发送“大量”数据。您可以发送两个字节,一次接收一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 2015-07-27
  • 2011-01-12
  • 2011-11-01
相关资源
最近更新 更多