使用QTcpSocket的Tcp包

时间:2014-11-13 13:10:29

标签: qt tcp

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

1 个答案:

答案 0 :(得分:9)

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

通过将第一个字节设置为将要发送的字节数来控制此操作是一种很好的做法。然后,在readyRead中,您读取第一个字节并将数据附加到缓冲区,直到收到预期的数据量。

在接收数据时,这也意味着如果在一次调用readyRead()时收到多条消息,您就可以知道第一条消息的结束位置和下一条消息的开始位置。

以下是在readyRead函数()

中接收数据的客户端示例
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);
    }
}