QTcpServer stop working suddenly on Windows
-
Hi qt users, I'm caught by a strange problem.
A listening QTcpServer that is working normally suddenly stop accepting new connections(qBittorrent webui stop working).
I did a little dig into Qt source and found that the WSAAccept function on the listening socket gives me WSAEINVAL error.
As the image shows, I'm listening on 50000 three days ago and it stop working today.
The MSDN doc tells it maybeinvalid level
orcalling accept on a socket that is not listening
. But those make no sense since that socket is working just fine in the last three days.This problem occurs frequently when the socket is listened for two or three days.
I believe it's not a QTcpServer bug since I didn't find anyone report the same issue.
a MRE://server.h #include <QTcpServer> namespace Http { class Server final : public QTcpServer { Q_OBJECT Q_DISABLE_COPY_MOVE(Server) public: explicit Server(QObject *parent = nullptr); private: void incomingConnection(qintptr socketDescriptor) override; }; } //server.cpp #include "server.h" #include <QTcpSocket> using namespace Http; Server::Server(QObject *parent) : QTcpServer(parent) {} void Server::incomingConnection(const qintptr socketDescriptor) { QTcpSocket *serverSocket = nullptr; serverSocket = new QTcpSocket(this); serverSocket->setSocketDescriptor(socketDescriptor); QByteArray x = "HTTP/1.1 400 Bad Request\r\nServer: Boost.Beast/353\r\nContent-Type: text/html\r\nContent-Length: 19\r\n\r\nUnknown HTTP-method"; serverSocket->write(x); } // main.cpp int main(int argc, char* argv[]) { QCoreApplication a(argc, argv); auto server = Http::Server(nullptr); server.listen(QHostAddress::Any, 50001); return QCoreApplication::exec(); }
-
Where do you close and delete the sockets after usage?
-
@Christian-Ehrlicher sorry I forgot that, in this tiny demo the socket is closed and deleted after write
-
Please provide a minimal compileable example of the problem. Your example does not close and cleanup the sockets so after all sockets are used you can not open new ones.
-
@Christian-Ehrlicher I'm having trouble updating my post, the forum gives me
Post content was flagged as spam by Akismet.com
.
I use those to cleanup the sockets.serverSocket->write(x); serverSocket->waitForBytesWritten(); serverSocket->disconnectFromHost(); serverSocket->waitForDisconnected(); serverSocket->deleteLater();
Thanks for your remind, the sockets here were actually properly closed. The problem I met is about the socket that is listening in QTcpServer.
-
You can only try to reproduce it by creating a small test program which creates a QTcpSocket as shown above and opens connections to them until it does no longer works.
-
@isudfv
WSAEINVAL is an invalid argument, as you probably know.
QTcpServer
works solid as a rock for me on macOS, Windows, Linux.The only errors I could think of in your case is still some sort of soft leak, where new instances get created before the old ones get deleted.
AdeleteLater()
posts an event. In theory a bunch of new instances could be created while the old one still blocks a socket. That can lead to nasty stuff in corner cases. => try and immediatedelete
.Another error could be that - despite of, or in addition to a soft leak - you bump a numeric variable in each iteration of a loop, and use it as an argument somewhere. If you don't wrap it at the right moment, the argument could get out of bounds.
That's of course pure speculation without any code shown.
-
If we/the OP believe it may be the case that the process keeps using up socket handles until no more are available at the time of the error, and this happens over days. Then maybe the OP should run a job occasionally to ask Windows which TCP handles/ports/sockets are in use, to see if that gets exhausted? I think
netstat
provides this information under Windows? Send its output to a log file for later examination. Either do a Windows Task for this, or probably can run it viaQProcess
from the Qt code e.g. just before a new connection inincomingConnection()
? -
@Christian-Ehrlicher @Axel-Spoerl @JonB thanks for your advices. I've found that it's a problem caused by uu. I will contact uu for more infomation.