[英]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.