繁体   English   中英

如何使用 QTcpSocket 读取超过 8192 字节?

[英]how to read more than 8192 byte with QTcpSocket?

我向服务器发送请求并得到响应我的代码是这样的:

QString mywindow::SocketCommunication(QString JsonRequest)
{
    QTcpSocket *socket = new QTcpSocket(this);
    QString result;
    socket->connectToHost(SOCKET_IP, SOCKET_PORT);//SOCKET_IP and SOCKET_PORT are defined constants and are correct

    if (socket->waitForConnected(-1) && socket->state() == QAbstractSocket::ConnectedState)
    {

        if (socket->write(JsonRequest.toLatin1()) == -1)
        {

            socket->disconnectFromHost();
            result = "Could not send message";
        }
        else
        {
            socket->flush();


            if (!socket->waitForReadyRead(90000))
            {
                socket->disconnectFromHost();
                result = "tcp con timeout for reading";
            }
            else
            {
                QByteArray JsonResponse = socket->readAll();// the problem is here

                socket->close();

                JsonResponse = JsonResponse.trimmed();
                QString jsonResp = QString::fromStdString(JsonResponse.toStdString());

                result = ParseResponse(jsonResp) // here i parse the response. it works fine and is not important in this question.
            }
        }
    }

    else
    {
        qDebug() << "cannot connect";
        socket->disconnectFromHost();
        result = "Could not Connect to Server";
    }
    return result;
}

现在,当来自服务器的响应小于 8192 字节时,这可以正常工作。 否则这只读取前 8192 个字节。 当我在读取所有内容后放置socket->error()时,我得到 -1,即 QAbstractSocket::UnknownSocketError。 你知道为什么会发生这种情况,我应该如何补救?

ps :我不认为问题出在 QAbstractSocket::DatagramTooLargeError 是

数据报大于操作系统的限制(可以低至8192字节)。

因为我可以发送超过 8192 并且其他程序可以与更大的消息进行通信。

如果当前值太小,您可能需要将 QAbstractSocket::setReadBufferSize() 设置为更大的值。 但这是一个内部 Qt 缓冲区,默认情况下应该足够大。 很可能您需要设置QAbstractSocket::ReceiveBufferSizeSocketOption这是一个操作系统级别的套接字选项。 请参阅 QAbstractSocket::socketOption() 和QAbstractSocket::setSocketOption()

这里的问题是socket->write()是一个相对底层的操作,它是QIODevice API 的一部分。 不会将您的整个数据拆分成小于 8192 字节的小块以符合 TCP 协议要求。

希望您可以利用QDataStream轻松地发送/接收数据,而无需考虑协议实现:

//send data
QDataStream sender(socket);
QByteArray dataWhichMightBeBiggerThan8192Bytes = jsonRequest.toLatin1();
sender << dataWhichMightBeBiggerThan8192Bytes;

接收数据:

//connect your socket
QObject::connect(
    socket, &QIODevice::readyRead,
    this, &mywindow::_processIncomingData
);

然后,在您的 class 中:

//Is called every time new data is sent to the socket 
void mywindow::_processIncomingData() {

    //prepare to receive data 
    QDataStream receiver(this->_innerSocket); 

    //will loop until the whole waitingBytes of the socket are exhausted 
    while(!receiver.atEnd()) { 

        //start a transaction, so the waitingBytes of the socket can be automatically reset if not all the expected data is there 
        receiver.startTransaction();

        //push waitingBytes into a QByteArray
        QByteArray myJsonAsLatin1;
        receiver >> myJsonAsLatin1;

        //commit : if it failed, means data is missing, so you may keep looping while the client downloads more
        if(auto commitFailed = !receiver.commitTransaction()) continue;

        //commit succeeded, waitingBytes are freed from your QByteArray, you can now process your data
        this->_useMyData(myJsonAsLatin1);

    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM