Ildar Ildar - 1 month ago 8
C++ Question

"Connection closed" When using QNetworkAccessManager and QTcpServer

I have simple server with QTcpServer and simple client with QNetworkAccessManager.


  1. When I request data from the server via curl or browser everything is ok

  2. When I request data from any site via QNetworkAccessManager everything is ok

  3. But I can not read data from QTcpServer via QNetworkAccessManager. All requests are reseted. QNetworkAccessManager (client) had send RST (reset connection) right after it received a data from server. And in client code we get the error: "Connection closed" (RemoteHostClosedError)

  4. Aslo, I tried use QNetworkAccessManager from DownloadManager example and QTcpServer from FortuneServer example in various combinations, but the results were the same.



Tested Qt Versions:


  • Mac Qt 5.7

  • Linux Qt 5.7

  • Linux Qt 5.6.2

  • Linux Qt 5.5.1



Wireshark screenshot: qt-wireshark.png

The upper parts (with red lines) are results of QNetworkAccessManager, and the latest packets with success result are curl attempt to get data from QTcpServer

Also there is a simple example to reproduce the error: testNetwork.zip

And here is sample code for client:

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()));
});
}


and for server:

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());
}


Also I created a Bug report on qt.io (QTBUG-56631)

Answer

Your client is making an HTTP request, but your server isn't an http server - it's not sending back a valid HTTP request.

Your client works when you point it at a web server, because that IS an http server.

    QByteArray responce("HELLO, WORLD! HELLO, WORLD! HELLO, WORLD! HELLO, WORLD!");

isn't a valid HTTP response.