“连接关闭”当使用 QNetworkAccessManager 和 QTcpServer
Posted
技术标签:
【中文标题】“连接关闭”当使用 QNetworkAccessManager 和 QTcpServer【英文标题】:"Connection closed" When using QNetworkAccessManager and QTcpServer 【发布时间】:2016-10-20 10:27:04 【问题描述】:我有带有 QTcpServer 的简单服务器和带有 QNetworkAccessManager 的简单客户端。
-
当我通过 curl 或浏览器向服务器请求数据时,一切正常
当我通过 QNetworkAccessManager 从任何站点请求数据时,一切正常
但我无法通过 QNetworkAccessManager 从 QTcpServer 读取数据。所有请求都被重置。 QNetworkAccessManager(客户端)在收到来自服务器的数据后立即发送 RST(重置连接)。在客户端代码中,我们收到错误:“连接已关闭”(RemoteHostClosedError)
另外,我尝试使用 DownloadManager 示例中的 QNetworkAccessManager 和 FortuneServer 示例中的 QTcpServer 进行各种组合,但结果是相同的。
经过测试的 Qt 版本:
Mac Qt 5.7 Linux Qt 5.7 Linux Qt 5.6.2 Linux Qt 5.5.1Wireshark 截图:qt-wireshark.png 上半部分(红线部分)是 QNetworkAccessManager 的结果,最新成功的数据包是 curl 尝试从 QTcpServer 获取数据
还有一个简单的例子可以重现错误:testNetwork.zip
这里是客户端的示例代码:
void test(quint16 port)
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
request.setUrl(QUrl(QString("http://127.0.0.1:%1/").arg(port)));
manager->connect(manager, &QNetworkAccessManager::finished,
[](QNetworkReply *reply)
qDebug() << QString("Finished. %1. %2").arg(reply->errorString()).arg(reply->error());
qDebug() << "readed: " << reply->readAll();
);
QNetworkReply *reply = manager->get(request);
reply->connect(reply, &QNetworkReply::readyRead, [reply]()
qDebug() << QString("readyRead: '%1'").arg(QString(reply->readAll()));
);
对于服务器:
QTcpSocket socket;
...
if(socket.waitForReadyRead(5000))
QByteArray request;
request += socket.readAll();
QByteArray responce("HELLO, WORLD! HELLO, WORLD! HELLO, WORLD! HELLO, WORLD!");
socket.write(responce);
if(!socket.waitForBytesWritten())
qWarning() << QString("Error occurred in waitForBytesWritten() method of the tcp socket. %1 (%2)")
.arg(socket.errorString())
.arg(socket.error());
else
qWarning() << QString("Error occurred in read method of the tcp socket. %1 (%2)")
.arg(socket.errorString())
.arg(socket.error());
我还在 qt.io (QTBUG-56631) 上创建了一个错误报告
【问题讨论】:
【参考方案1】:您的客户端正在发出 HTTP 请求,但您的服务器不是 http 服务器 - 它没有发回有效的 HTTP 请求。
当您将客户端指向 Web 服务器时,它就可以工作,因为那是一个 http 服务器。
QByteArray responce("HELLO, WORLD! HELLO, WORLD! HELLO, WORLD! HELLO, WORLD!");
不是有效的 HTTP 响应。
【讨论】:
我要感谢 Qt Forum 上的 raven-worx 的回复: 他的回复:至少回复应该如下所示。注意:每行应以 \r\n 结尾,空行分隔 header- 和 content-section Content-Length 标头是内容的字节数 HTTP/1.1 200 OK 日期:Thu, 20 Oct 2016 12:28: 53 GMT 服务器:MyServer 1.0.0 内容长度:3 内容类型:文本/纯文本连接:已关闭 XXX以上是关于“连接关闭”当使用 QNetworkAccessManager 和 QTcpServer的主要内容,如果未能解决你的问题,请参考以下文章