QTcpServer listen QHostAddress::Any network operation timed out



  • Using Desktop QT 5.9.1 Mingw 32bit, QTcpServer listen on QHostAddress::Any, sometimes it works, sometimes it reports "network operation timed out".
    The OS is windows 10

    Edit:
    There was an error message in the Application out window:
    QSocks5SocketEnginePrivate::_q_controlSocketReadNotification: Unexpectedly received data while in state=10 and mode=2

    This seems to be a bug of QTcpServer.



  • @mikelij
    We need a little more knowledge.
    Can you share full code?
    https://forum.qt.io/topic/54727/solved-network-problems-qtcpsocket-qtcpserver/5



  • Does upgrading to Qt 5.9.2 solve the problem?



  • @Taz742 said in QTcpServer listen QHostAddress::Any network operation timed out:

    @mikelij
    We need a little more knowledge.
    Can you share full code?
    https://forum.qt.io/topic/54727/solved-network-problems-qtcpsocket-qtcpserver/5

    This is my code.

    void ServerSocket::startListening()
    {
        while (!tcpServer.isListening() && !tcpServer.listen(QHostAddress::Any, this->serverPort)) {
            QMessageBox::StandardButton ret = QMessageBox::critical(NULL,
                                            tr("Loopback"),
                                            tr("Unable to start the test: %1.")
                                            .arg(tcpServer.errorString()),
                                            QMessageBox::Retry
                                            | QMessageBox::Cancel);
            if (ret == QMessageBox::Cancel)
                return;
        }
        connect(&tcpServer, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
    }
    


  • @VRonin
    Tried 5.9.2. It did not work. Still got the "network operation timed out" error.



  • Ok, let's try not to stop the event loop:

    void ServerSocket::startListening()
    {
        while (!tcpServer.listen(QHostAddress::Any, this->serverPort)) {
            QMessageBox::StandardButton ret = QMessageBox::critical(NULL,
                                            tr("Loopback"),
                                            tr("Unable to start the test: %1.")
                                            .arg(tcpServer.errorString()),
                                            QMessageBox::Retry
                                            | QMessageBox::Cancel);
            if (ret == QMessageBox::Cancel)
                return;
        }
        connect(&tcpServer, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
    }
    


  • @VRonin
    Did not work. Still the same error.



  • @Taz742
    My code is copied from the official loopback example.
    //dialog.h
    /****************************************************************************
    **
    ** Copyright (C) 2016 The Qt Company Ltd.
    ** Contact: https://www.qt.io/licensing/
    **
    ** This file is part of the examples of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:BSD$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see https://www.qt.io/terms-conditions. For further
    ** information use the contact form at https://www.qt.io/contact-us.
    **
    ** BSD License Usage
    ** Alternatively, you may use this file under the terms of the BSD license
    ** as follows:
    **
    ** "Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are
    ** met:
    ** * Redistributions of source code must retain the above copyright
    ** notice, this list of conditions and the following disclaimer.
    ** * Redistributions in binary form must reproduce the above copyright
    ** notice, this list of conditions and the following disclaimer in
    ** the documentation and/or other materials provided with the
    ** distribution.
    ** * Neither the name of The Qt Company Ltd nor the names of its
    ** contributors may be used to endorse or promote products derived
    ** from this software without specific prior written permission.
    **
    **
    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    #ifndef DIALOG_H
    #define DIALOG_H

    #include <QDialog>
    #include <QTcpServer>
    #include <QTcpSocket>

    QT_BEGIN_NAMESPACE
    class QDialogButtonBox;
    class QLabel;
    class QProgressBar;
    class QPushButton;
    class QTcpServer;
    class QTcpSocket;
    class QAction;
    QT_END_NAMESPACE

    class Dialog : public QDialog
    {
    Q_OBJECT

    public:
    Dialog(QWidget *parent = 0);

    public slots:
    void start();
    void acceptConnection();
    void startTransfer();
    void updateServerProgress();
    void updateClientProgress(qint64 numBytes);
    void displayError(QAbstractSocket::SocketError socketError);

    private:
    QProgressBar *clientProgressBar;
    QProgressBar *serverProgressBar;
    QLabel *clientStatusLabel;
    QLabel *serverStatusLabel;

    QPushButton *startButton;
    QPushButton *quitButton;
    QDialogButtonBox *buttonBox;
    
    QTcpServer tcpServer;
    QTcpSocket tcpClient;
    QTcpSocket *tcpServerConnection;
    int bytesToWrite;
    int bytesWritten;
    int bytesReceived;
    

    };

    #endif

    //dialog.cpp

    /****************************************************************************
    **
    ** Copyright (C) 2016 The Qt Company Ltd.
    ** Contact: https://www.qt.io/licensing/
    **
    ** This file is part of the examples of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:BSD$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see https://www.qt.io/terms-conditions. For further
    ** information use the contact form at https://www.qt.io/contact-us.
    **
    ** BSD License Usage
    ** Alternatively, you may use this file under the terms of the BSD license
    ** as follows:
    **
    ** "Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are
    ** met:
    ** * Redistributions of source code must retain the above copyright
    ** notice, this list of conditions and the following disclaimer.
    ** * Redistributions in binary form must reproduce the above copyright
    ** notice, this list of conditions and the following disclaimer in
    ** the documentation and/or other materials provided with the
    ** distribution.
    ** * Neither the name of The Qt Company Ltd nor the names of its
    ** contributors may be used to endorse or promote products derived
    ** from this software without specific prior written permission.
    **
    **
    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    #include <QtWidgets>
    #include <QtNetwork>

    #include "dialog.h"

    static const int TotalBytes = 50 * 1024 * 1024;
    static const int PayloadSize = 64 * 1024; // 64 KB

    Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    {
    clientProgressBar = new QProgressBar;
    clientStatusLabel = new QLabel(tr("Client ready"));
    serverProgressBar = new QProgressBar;
    serverStatusLabel = new QLabel(tr("Server ready"));

    startButton = new QPushButton(tr("&Start"));
    quitButton = new QPushButton(tr("&Quit"));
    
    buttonBox = new QDialogButtonBox;
    buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
    buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
    
    connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
    connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(&tcpServer, SIGNAL(newConnection()),
            this, SLOT(acceptConnection()));
    connect(&tcpClient, SIGNAL(connected()), this, SLOT(startTransfer()));
    connect(&tcpClient, SIGNAL(bytesWritten(qint64)),
            this, SLOT(updateClientProgress(qint64)));
    connect(&tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));
    
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(clientProgressBar);
    mainLayout->addWidget(clientStatusLabel);
    mainLayout->addWidget(serverProgressBar);
    mainLayout->addWidget(serverStatusLabel);
    mainLayout->addStretch(1);
    mainLayout->addSpacing(10);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);
    
    setWindowTitle(tr("Loopback"));
    

    }

    void Dialog::start()
    {
    startButton->setEnabled(false);

    #ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
    #endif

    bytesWritten = 0;
    bytesReceived = 0;
    
    while (!tcpServer.isListening() && !tcpServer.listen()) {
        QMessageBox::StandardButton ret = QMessageBox::critical(this,
                                        tr("Loopback"),
                                        tr("Unable to start the test: %1.")
                                        .arg(tcpServer.errorString()),
                                        QMessageBox::Retry
                                        | QMessageBox::Cancel);
        if (ret == QMessageBox::Cancel)
            return;
    }
    
    serverStatusLabel->setText(tr("Listening"));
    clientStatusLabel->setText(tr("Connecting"));
    tcpClient.connectToHost(QHostAddress::LocalHost, tcpServer.serverPort());
    

    }

    void Dialog::acceptConnection()
    {
    tcpServerConnection = tcpServer.nextPendingConnection();
    connect(tcpServerConnection, SIGNAL(readyRead()),
    this, SLOT(updateServerProgress()));
    connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
    this, SLOT(displayError(QAbstractSocket::SocketError)));

    serverStatusLabel->setText(tr("Accepted connection"));
    tcpServer.close();
    

    }

    void Dialog::startTransfer()
    {
    // called when the TCP client connected to the loopback server
    bytesToWrite = TotalBytes - (int)tcpClient.write(QByteArray(PayloadSize, '@'));
    clientStatusLabel->setText(tr("Connected"));
    }

    void Dialog::updateServerProgress()
    {
    bytesReceived += (int)tcpServerConnection->bytesAvailable();
    tcpServerConnection->readAll();

    serverProgressBar->setMaximum(TotalBytes);
    serverProgressBar->setValue(bytesReceived);
    serverStatusLabel->setText(tr("Received %1MB")
                               .arg(bytesReceived / (1024 * 1024)));
    
    if (bytesReceived == TotalBytes) {
        tcpServerConnection->close();
        startButton->setEnabled(true);
    

    #ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
    #endif
    }
    }

    void Dialog::updateClientProgress(qint64 numBytes)
    {
    // callen when the TCP client has written some bytes
    bytesWritten += (int)numBytes;

    // only write more if not finished and when the Qt write buffer is below a certain size.
    if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4*PayloadSize)
        bytesToWrite -= (int)tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));
    
    clientProgressBar->setMaximum(TotalBytes);
    clientProgressBar->setValue(bytesWritten);
    clientStatusLabel->setText(tr("Sent %1MB")
                               .arg(bytesWritten / (1024 * 1024)));
    

    }

    void Dialog::displayError(QAbstractSocket::SocketError socketError)
    {
    if (socketError == QTcpSocket::RemoteHostClosedError)
    return;

    QMessageBox::information(this, tr("Network error"),
                             tr("The following error occurred: %1.")
                             .arg(tcpClient.errorString()));
    
    tcpClient.close();
    tcpServer.close();
    clientProgressBar->reset();
    serverProgressBar->reset();
    clientStatusLabel->setText(tr("Client ready"));
    serverStatusLabel->setText(tr("Server ready"));
    startButton->setEnabled(true);
    

    #ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
    #endif
    }

    My code is a little different from the example. My code listens on QHostAddress::Any, and a port number. The loopback example, use listern(), without any parameter. The default value of address is QHostAddress::Any, the default port is 0.

    Tried the loopback example again. It failed also.



  • Your firewall or Router is blocking your listen function. Nothing wrong with your code as it works on my machine windows 10 x64.



  • @Sunfluxgames
    No idea now. My Windows 10 firewall is turned off. Regarding Router, no idea about how to do that.



  • @Global-Moderators @Sunfluxgames @Taz742 @VRonin
    Finally I found the root cause! I set the global proxy settings in internet options. Go to IE, Tools->Internet options->Connections tab->Lan Settings->Check "use a proxy server for your LAN(These settings will not apply to dial up or VPN connections). And set the proxy server ip address/port for protocols, this settings has impact to the QT server listen functionality, causing the "network operation timed out" error. After I turned off the proxy settings in internet options. the QT server listen functionality worked properly.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.