Details
-
Bug
-
Resolution: Invalid
-
P1: Critical
-
None
-
5.7.0, 5.7.1
-
None
-
Ubuntu 16.04
Description
Since Qt 5.7.0 when flushing the websocket, not all data is sent.
This can be tested with the sample project attached to this ticket.
The project contains two parts:
- a websocket server which just prints the length of the received data and waits a bit between to answer
- a websocket client which can send a file to the server
Running a client built with Qt 5.7.0 or 5.7.1 on a 13MB file, the server receives a little less than 5MB.
When the client is built with Qt 5.6.2, the server receives the whole file.
This seems related to this commit http://code.qt.io/cgit/qt/qtbase.git/commit/?id=aaab800e1651fc9f04d62a76eda9b8cafbbe14c0
The server code:
#include <QCoreApplication> #include <QWebSocketServer> #include <QWebSocket> #include <QThread> class Server : public QObject { public: Server() { mWebSocketServer = new QWebSocketServer("test", QWebSocketServer::NonSecureMode); connect(mWebSocketServer, &QWebSocketServer::newConnection, this, &Server::onNewConnection); } void listen() { mWebSocketServer->listen(QHostAddress::Any, 1234); } void onNewConnection() { mTotal = 0; QWebSocket* socket = mWebSocketServer->nextPendingConnection(); connect(socket, &QWebSocket::binaryMessageReceived, this, &Server::onMessageReceived); connect(socket, &QWebSocket::disconnected, this, &Server::onDisconnected); qDebug() << "New connection"; } void onMessageReceived(const QByteArray& msg) { mTotal += msg.length(); qDebug() << msg.length() << mTotal; QThread::msleep(100); } void onDisconnected() { qDebug() << "Disconnected"; } private: QWebSocketServer* mWebSocketServer; qint64 mTotal = 0; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Server server; server.listen(); return a.exec(); }
The client code:
#include <QCoreApplication> #include <QWebSocket> #include <QFile> static constexpr int CHUNK_SIZE = 262168; class Client : public QObject { public: Client(QWebSocket* socket, const QString& fileName) : mSocket(socket), mFileName(fileName) { connect(mSocket, &QWebSocket::connected, this, &Client::onConnected); connect(mSocket, static_cast<void(QWebSocket::*)(QAbstractSocket::SocketError)>(&QWebSocket::error), this, &Client::onError); } private: void onConnected() { QFile fp(mFileName); fp.open(QIODevice::ReadOnly); while (true) { QByteArray data = fp.read(CHUNK_SIZE); if (data.isEmpty()) { break; } mSocket->sendBinaryMessage(data); waitForDataToBeSent(); } waitForDataToBeSent(); QCoreApplication::instance()->quit(); } void onError(QAbstractSocket::SocketError error) { qDebug() << "error" << error << mSocket->errorString(); } void waitForDataToBeSent() { int flushCount = 0; do { ++flushCount; } while (mSocket->flush()); qDebug() << "flushCount" << flushCount; } QWebSocket* mSocket; QString mFileName; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QWebSocket socket; Client client(&socket, argv[1]); socket.open(QUrl("ws://localhost:1234")); return a.exec(); }