Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Impossible to bind QTcpSocket again after connection error
Forum Updated to NodeBB v4.3 + New Features

Impossible to bind QTcpSocket again after connection error

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 3 Posters 3.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Karlor
    wrote on last edited by
    #1

    Hi,

    in one our application we encountered a problem with reconnecting to the server over a TCP connection after accidentally disconnecting network cable. After some examination I found that the problem is related to binding QTcpSocket. After a fixed network cable QTcpSocket::bind() got stuck on QAbstract::SocketError = 7 (Connection time out) or QAbstract::SocketError = 7 (Host unreachable).

    I created a test class with one QTcpSocket instance for manually call QTcpSocket methods connectToHost(), bind(), disconnectFromHost() etc. The source code is below.

    SocketConnector.h

    #ifndef SOCKETCONNECTOR_H
    #define SOCKETCONNECTOR_H
    
    #include <QTcpSocket>
    #include <QObject>
    #include <QPushButton>
    #include <QLineEdit>
    
    
    class SocketConnector: public QObject
    {
        Q_OBJECT
    
    public:
        SocketConnector();
    
        void setUi(QLineEdit * leBindAddressW, QLineEdit * leHostAddressW,
                   QLineEdit * leHostPortW);
    
    private:
        QTcpSocket socket;
    
        QLineEdit *leBindAddress = nullptr;
        QLineEdit *leHostAddress = nullptr;
        QLineEdit *leHostPort = nullptr;
    
        QString getSocketState() const;
    
    public slots:
        // Slots for QPushButtons
        void onPbState() const;
        void onPbBind();
        void onPbConnect();
        void onPbDisconnect();
        void onPbClose();
        void onPbAbort();
    
    private slots:
        // Slots for QTcpSocket signals
        void onConnect();
        void onDisconnected();
        void onError(QAbstractSocket::SocketError error);
        void onStateChanged(QAbstractSocket::SocketState state);
    };
    
    
    #endif // SOCKETCONNECTOR_H
    

    SocketConnector.cpp

    #include "SocketConnector.h"
    
    #include <QTcpSocket>
    #include <QPushButton>
    #include <QHostAddress>
    #include <QDebug>
    #include <QString>
    
    
    SocketConnector::SocketConnector():
        QObject(nullptr)
    {
        connect(&socket, SIGNAL(connected()), this, SLOT(onConnect()));
        connect(&socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
        connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onError(QAbstractSocket::SocketError)));
        connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
    }
    
    void SocketConnector::setUi(QLineEdit *leBindAddressW, QLineEdit *leHostAddressW,
                                QLineEdit *leHostPortW)
    {
        leBindAddress = leBindAddressW;
        leHostAddress = leHostAddressW;
        leHostPort    = leHostPortW;
    }
    
    QString SocketConnector::getSocketState() const
    {
        return QString("SocketState: %1, SocketError: %2 - %3")
                .arg(socket.state())
                .arg(socket.error())
                .arg(socket.errorString());
    }
    
    // -----------------------------------------------------------------------------
    // Slots for QTcpSocket signals
    
    
    void SocketConnector::onConnect()
    {
        qDebug() << "Slot onConnected():" << getSocketState();
    }
    
    void SocketConnector::onDisconnected()
    {
        qDebug() << "Slot onDisconnected():" << getSocketState();
    }
    
    void SocketConnector::onError(QAbstractSocket::SocketError error)
    {
        qDebug() << "Slot onError(): error=" << error
                 << " - " << getSocketState();
    }
    
    void SocketConnector::onStateChanged(QAbstractSocket::SocketState state)
    {
        qDebug() << "Slot onStateChanged(): state=" << state << getSocketState();
    }
    
    
    // -----------------------------------------------------------------------------
    // Slots for QPushButton activating actions bind, connection etc.
    
    
    void SocketConnector::onPbState() const
    {
        qDebug() << "onPbState():" << getSocketState();
    }
    
    void SocketConnector::onPbBind()
    {
        QHostAddress bindAddress = QHostAddress(leBindAddress->text());
    
        qDebug() << "onPbBind(): Pressed";
        bool ok = socket.bind(bindAddress, 0, QAbstractSocket::ReuseAddressHint);
        qDebug() << "onPbBind(): ok =" << ok << getSocketState();
    }
    
    void SocketConnector::onPbConnect()
    {
        QString hostAddress = leHostAddress->text();
        int hostPort = leHostPort->text().toInt();
    
        qDebug() << "onPbConnect(): Pressed";
        socket.connectToHost(hostAddress, hostPort);
        qDebug() << "onPbConnect():" << getSocketState();
    }
    
    void SocketConnector::onPbDisconnect()
    {
        qDebug() << "onPbDisconnect(): Pressed";
        socket.disconnectFromHost();
        qDebug() << "onPbDisconnect():" << getSocketState();
    }
    
    void SocketConnector::onPbClose()
    {
        qDebug() << "onPbClose(): Pressed";
        socket.close();
        qDebug() << "onPbClose():" << getSocketState();
    }
    
    void SocketConnector::onPbAbort()
    {
        qDebug() << "onPbAbort(): Pressed";
        socket.abort();
        qDebug() << "onPbAbort():" << getSocketState();
    }
    

    The methods begins with prefix onPb are slots for signals from QPushButtons which are connected outside of class SocketConnector. This QPushButtons activates actions of QTcpSocket: bind(), connectToHost() etc.

    The scenario what I have been tried was:

    I disconnected the network cable and called bind() and after that I called connectToHost(). The debug output was:

    onPbBind(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: -1 - Unknown error"
    onPbBind(): ok = true "SocketState: 4, SocketError: -1 - Unknown error"
    onPbConnect(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: -1 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: -1 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Host unreachable"
    Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
    onPbConnect(): "SocketState: 0, SocketError: 7 - Host unreachable"

    I connect the network cable again and called bind() with same parameters as before.

    onPbBind(): Pressed
    Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
    onPbBind(): ok = false "SocketState: 0, SocketError: 7 - Host unreachable"

    After this step QTcpSocket::bind() is always failing and QTcpSocket::error() signal have been emitted with SocketError: 7 - Host unreachable. I have been tried to call QTcpSocket::disconnectFromHost(), QTcpSocket::close(), QTcpSocket::abort() but nothing helps. The binding keeps failing with the same error emitted.

    But strange thing occurred in this error state when connectToHost() was called.

    onPbConnect(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
    onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
    Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"
    onPbDisconnect(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
    Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
    onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

    The connection was successful and after successful disconnection the binding started to work again.

    onPbBind(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: 7 - Unknown error"
    onPbBind(): ok = true "SocketState: 4, SocketError: 7 - Unknown error"
    onPbConnect(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
    onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
    Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"

    onPbDisconnect(): Pressed
    Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
    Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
    Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
    onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

    Only one solution I have been found is to create QTcpSocket dynamically by new operator and after error occurs delete QTcpSocket and create new one for new connection. But IMHO this is rather workaround than solution.

    Why binding is failing after a fixed network cable? Is there any solution to fix binding?

    kshegunovK JonBJ 2 Replies Last reply
    0
    • K Karlor

      Hi,

      in one our application we encountered a problem with reconnecting to the server over a TCP connection after accidentally disconnecting network cable. After some examination I found that the problem is related to binding QTcpSocket. After a fixed network cable QTcpSocket::bind() got stuck on QAbstract::SocketError = 7 (Connection time out) or QAbstract::SocketError = 7 (Host unreachable).

      I created a test class with one QTcpSocket instance for manually call QTcpSocket methods connectToHost(), bind(), disconnectFromHost() etc. The source code is below.

      SocketConnector.h

      #ifndef SOCKETCONNECTOR_H
      #define SOCKETCONNECTOR_H
      
      #include <QTcpSocket>
      #include <QObject>
      #include <QPushButton>
      #include <QLineEdit>
      
      
      class SocketConnector: public QObject
      {
          Q_OBJECT
      
      public:
          SocketConnector();
      
          void setUi(QLineEdit * leBindAddressW, QLineEdit * leHostAddressW,
                     QLineEdit * leHostPortW);
      
      private:
          QTcpSocket socket;
      
          QLineEdit *leBindAddress = nullptr;
          QLineEdit *leHostAddress = nullptr;
          QLineEdit *leHostPort = nullptr;
      
          QString getSocketState() const;
      
      public slots:
          // Slots for QPushButtons
          void onPbState() const;
          void onPbBind();
          void onPbConnect();
          void onPbDisconnect();
          void onPbClose();
          void onPbAbort();
      
      private slots:
          // Slots for QTcpSocket signals
          void onConnect();
          void onDisconnected();
          void onError(QAbstractSocket::SocketError error);
          void onStateChanged(QAbstractSocket::SocketState state);
      };
      
      
      #endif // SOCKETCONNECTOR_H
      

      SocketConnector.cpp

      #include "SocketConnector.h"
      
      #include <QTcpSocket>
      #include <QPushButton>
      #include <QHostAddress>
      #include <QDebug>
      #include <QString>
      
      
      SocketConnector::SocketConnector():
          QObject(nullptr)
      {
          connect(&socket, SIGNAL(connected()), this, SLOT(onConnect()));
          connect(&socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
          connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),
                  this, SLOT(onError(QAbstractSocket::SocketError)));
          connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                  this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
      }
      
      void SocketConnector::setUi(QLineEdit *leBindAddressW, QLineEdit *leHostAddressW,
                                  QLineEdit *leHostPortW)
      {
          leBindAddress = leBindAddressW;
          leHostAddress = leHostAddressW;
          leHostPort    = leHostPortW;
      }
      
      QString SocketConnector::getSocketState() const
      {
          return QString("SocketState: %1, SocketError: %2 - %3")
                  .arg(socket.state())
                  .arg(socket.error())
                  .arg(socket.errorString());
      }
      
      // -----------------------------------------------------------------------------
      // Slots for QTcpSocket signals
      
      
      void SocketConnector::onConnect()
      {
          qDebug() << "Slot onConnected():" << getSocketState();
      }
      
      void SocketConnector::onDisconnected()
      {
          qDebug() << "Slot onDisconnected():" << getSocketState();
      }
      
      void SocketConnector::onError(QAbstractSocket::SocketError error)
      {
          qDebug() << "Slot onError(): error=" << error
                   << " - " << getSocketState();
      }
      
      void SocketConnector::onStateChanged(QAbstractSocket::SocketState state)
      {
          qDebug() << "Slot onStateChanged(): state=" << state << getSocketState();
      }
      
      
      // -----------------------------------------------------------------------------
      // Slots for QPushButton activating actions bind, connection etc.
      
      
      void SocketConnector::onPbState() const
      {
          qDebug() << "onPbState():" << getSocketState();
      }
      
      void SocketConnector::onPbBind()
      {
          QHostAddress bindAddress = QHostAddress(leBindAddress->text());
      
          qDebug() << "onPbBind(): Pressed";
          bool ok = socket.bind(bindAddress, 0, QAbstractSocket::ReuseAddressHint);
          qDebug() << "onPbBind(): ok =" << ok << getSocketState();
      }
      
      void SocketConnector::onPbConnect()
      {
          QString hostAddress = leHostAddress->text();
          int hostPort = leHostPort->text().toInt();
      
          qDebug() << "onPbConnect(): Pressed";
          socket.connectToHost(hostAddress, hostPort);
          qDebug() << "onPbConnect():" << getSocketState();
      }
      
      void SocketConnector::onPbDisconnect()
      {
          qDebug() << "onPbDisconnect(): Pressed";
          socket.disconnectFromHost();
          qDebug() << "onPbDisconnect():" << getSocketState();
      }
      
      void SocketConnector::onPbClose()
      {
          qDebug() << "onPbClose(): Pressed";
          socket.close();
          qDebug() << "onPbClose():" << getSocketState();
      }
      
      void SocketConnector::onPbAbort()
      {
          qDebug() << "onPbAbort(): Pressed";
          socket.abort();
          qDebug() << "onPbAbort():" << getSocketState();
      }
      

      The methods begins with prefix onPb are slots for signals from QPushButtons which are connected outside of class SocketConnector. This QPushButtons activates actions of QTcpSocket: bind(), connectToHost() etc.

      The scenario what I have been tried was:

      I disconnected the network cable and called bind() and after that I called connectToHost(). The debug output was:

      onPbBind(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: -1 - Unknown error"
      onPbBind(): ok = true "SocketState: 4, SocketError: -1 - Unknown error"
      onPbConnect(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: -1 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: -1 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Host unreachable"
      Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
      onPbConnect(): "SocketState: 0, SocketError: 7 - Host unreachable"

      I connect the network cable again and called bind() with same parameters as before.

      onPbBind(): Pressed
      Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
      onPbBind(): ok = false "SocketState: 0, SocketError: 7 - Host unreachable"

      After this step QTcpSocket::bind() is always failing and QTcpSocket::error() signal have been emitted with SocketError: 7 - Host unreachable. I have been tried to call QTcpSocket::disconnectFromHost(), QTcpSocket::close(), QTcpSocket::abort() but nothing helps. The binding keeps failing with the same error emitted.

      But strange thing occurred in this error state when connectToHost() was called.

      onPbConnect(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
      onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
      Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"
      onPbDisconnect(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
      Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
      onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

      The connection was successful and after successful disconnection the binding started to work again.

      onPbBind(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: 7 - Unknown error"
      onPbBind(): ok = true "SocketState: 4, SocketError: 7 - Unknown error"
      onPbConnect(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
      onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
      Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"

      onPbDisconnect(): Pressed
      Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
      Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
      Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
      onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

      Only one solution I have been found is to create QTcpSocket dynamically by new operator and after error occurs delete QTcpSocket and create new one for new connection. But IMHO this is rather workaround than solution.

      Why binding is failing after a fixed network cable? Is there any solution to fix binding?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      @Karlor said in Impossible to bind QTcpSocket again after connection error:

      Why binding is failing after a fixed network cable? Is there any solution to fix binding?

      Use QUdpSocket. You bind UDP sockets (as UDP is a conectionless protocol) and you connect TCP sockets to your known host (as the TCP sockets are connection-oriented), so unless I'm missing something you're just doing it wrong.

      Either use bind() with QUdpSocket or connectToHost with QTcpSocket.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      4
      • K Karlor

        Hi,

        in one our application we encountered a problem with reconnecting to the server over a TCP connection after accidentally disconnecting network cable. After some examination I found that the problem is related to binding QTcpSocket. After a fixed network cable QTcpSocket::bind() got stuck on QAbstract::SocketError = 7 (Connection time out) or QAbstract::SocketError = 7 (Host unreachable).

        I created a test class with one QTcpSocket instance for manually call QTcpSocket methods connectToHost(), bind(), disconnectFromHost() etc. The source code is below.

        SocketConnector.h

        #ifndef SOCKETCONNECTOR_H
        #define SOCKETCONNECTOR_H
        
        #include <QTcpSocket>
        #include <QObject>
        #include <QPushButton>
        #include <QLineEdit>
        
        
        class SocketConnector: public QObject
        {
            Q_OBJECT
        
        public:
            SocketConnector();
        
            void setUi(QLineEdit * leBindAddressW, QLineEdit * leHostAddressW,
                       QLineEdit * leHostPortW);
        
        private:
            QTcpSocket socket;
        
            QLineEdit *leBindAddress = nullptr;
            QLineEdit *leHostAddress = nullptr;
            QLineEdit *leHostPort = nullptr;
        
            QString getSocketState() const;
        
        public slots:
            // Slots for QPushButtons
            void onPbState() const;
            void onPbBind();
            void onPbConnect();
            void onPbDisconnect();
            void onPbClose();
            void onPbAbort();
        
        private slots:
            // Slots for QTcpSocket signals
            void onConnect();
            void onDisconnected();
            void onError(QAbstractSocket::SocketError error);
            void onStateChanged(QAbstractSocket::SocketState state);
        };
        
        
        #endif // SOCKETCONNECTOR_H
        

        SocketConnector.cpp

        #include "SocketConnector.h"
        
        #include <QTcpSocket>
        #include <QPushButton>
        #include <QHostAddress>
        #include <QDebug>
        #include <QString>
        
        
        SocketConnector::SocketConnector():
            QObject(nullptr)
        {
            connect(&socket, SIGNAL(connected()), this, SLOT(onConnect()));
            connect(&socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
            connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),
                    this, SLOT(onError(QAbstractSocket::SocketError)));
            connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                    this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
        }
        
        void SocketConnector::setUi(QLineEdit *leBindAddressW, QLineEdit *leHostAddressW,
                                    QLineEdit *leHostPortW)
        {
            leBindAddress = leBindAddressW;
            leHostAddress = leHostAddressW;
            leHostPort    = leHostPortW;
        }
        
        QString SocketConnector::getSocketState() const
        {
            return QString("SocketState: %1, SocketError: %2 - %3")
                    .arg(socket.state())
                    .arg(socket.error())
                    .arg(socket.errorString());
        }
        
        // -----------------------------------------------------------------------------
        // Slots for QTcpSocket signals
        
        
        void SocketConnector::onConnect()
        {
            qDebug() << "Slot onConnected():" << getSocketState();
        }
        
        void SocketConnector::onDisconnected()
        {
            qDebug() << "Slot onDisconnected():" << getSocketState();
        }
        
        void SocketConnector::onError(QAbstractSocket::SocketError error)
        {
            qDebug() << "Slot onError(): error=" << error
                     << " - " << getSocketState();
        }
        
        void SocketConnector::onStateChanged(QAbstractSocket::SocketState state)
        {
            qDebug() << "Slot onStateChanged(): state=" << state << getSocketState();
        }
        
        
        // -----------------------------------------------------------------------------
        // Slots for QPushButton activating actions bind, connection etc.
        
        
        void SocketConnector::onPbState() const
        {
            qDebug() << "onPbState():" << getSocketState();
        }
        
        void SocketConnector::onPbBind()
        {
            QHostAddress bindAddress = QHostAddress(leBindAddress->text());
        
            qDebug() << "onPbBind(): Pressed";
            bool ok = socket.bind(bindAddress, 0, QAbstractSocket::ReuseAddressHint);
            qDebug() << "onPbBind(): ok =" << ok << getSocketState();
        }
        
        void SocketConnector::onPbConnect()
        {
            QString hostAddress = leHostAddress->text();
            int hostPort = leHostPort->text().toInt();
        
            qDebug() << "onPbConnect(): Pressed";
            socket.connectToHost(hostAddress, hostPort);
            qDebug() << "onPbConnect():" << getSocketState();
        }
        
        void SocketConnector::onPbDisconnect()
        {
            qDebug() << "onPbDisconnect(): Pressed";
            socket.disconnectFromHost();
            qDebug() << "onPbDisconnect():" << getSocketState();
        }
        
        void SocketConnector::onPbClose()
        {
            qDebug() << "onPbClose(): Pressed";
            socket.close();
            qDebug() << "onPbClose():" << getSocketState();
        }
        
        void SocketConnector::onPbAbort()
        {
            qDebug() << "onPbAbort(): Pressed";
            socket.abort();
            qDebug() << "onPbAbort():" << getSocketState();
        }
        

        The methods begins with prefix onPb are slots for signals from QPushButtons which are connected outside of class SocketConnector. This QPushButtons activates actions of QTcpSocket: bind(), connectToHost() etc.

        The scenario what I have been tried was:

        I disconnected the network cable and called bind() and after that I called connectToHost(). The debug output was:

        onPbBind(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: -1 - Unknown error"
        onPbBind(): ok = true "SocketState: 4, SocketError: -1 - Unknown error"
        onPbConnect(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: -1 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: -1 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Host unreachable"
        Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
        onPbConnect(): "SocketState: 0, SocketError: 7 - Host unreachable"

        I connect the network cable again and called bind() with same parameters as before.

        onPbBind(): Pressed
        Slot onError(): error= QAbstractSocket::NetworkError - "SocketState: 0, SocketError: 7 - Host unreachable"
        onPbBind(): ok = false "SocketState: 0, SocketError: 7 - Host unreachable"

        After this step QTcpSocket::bind() is always failing and QTcpSocket::error() signal have been emitted with SocketError: 7 - Host unreachable. I have been tried to call QTcpSocket::disconnectFromHost(), QTcpSocket::close(), QTcpSocket::abort() but nothing helps. The binding keeps failing with the same error emitted.

        But strange thing occurred in this error state when connectToHost() was called.

        onPbConnect(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
        onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
        Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"
        onPbDisconnect(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
        Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
        onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

        The connection was successful and after successful disconnection the binding started to work again.

        onPbBind(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::BoundState "SocketState: 4, SocketError: 7 - Unknown error"
        onPbBind(): ok = true "SocketState: 4, SocketError: 7 - Unknown error"
        onPbConnect(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::HostLookupState "SocketState: 1, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::ConnectingState "SocketState: 2, SocketError: 7 - Unknown error"
        onPbConnect(): "SocketState: 2, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::ConnectedState "SocketState: 3, SocketError: 7 - Unknown error"
        Slot onConnected(): "SocketState: 3, SocketError: 7 - Unknown error"

        onPbDisconnect(): Pressed
        Slot onStateChanged(): state= QAbstractSocket::ClosingState "SocketState: 6, SocketError: 7 - Unknown error"
        Slot onStateChanged(): state= QAbstractSocket::UnconnectedState "SocketState: 0, SocketError: 7 - Unknown error"
        Slot onDisconnected(): "SocketState: 0, SocketError: 7 - Unknown error"
        onPbDisconnect(): "SocketState: 0, SocketError: 7 - Unknown error"

        Only one solution I have been found is to create QTcpSocket dynamically by new operator and after error occurs delete QTcpSocket and create new one for new connection. But IMHO this is rather workaround than solution.

        Why binding is failing after a fixed network cable? Is there any solution to fix binding?

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by JonB
        #3

        @Karlor
        Like @kshegunov says, for TCP connections you will use bind(), listen() & accept() only at the server side, and connect() only at the client side. I don't know about his UDP suggestion, that's a different matter.

        kshegunovK 1 Reply Last reply
        0
        • JonBJ JonB

          @Karlor
          Like @kshegunov says, for TCP connections you will use bind(), listen() & accept() only at the server side, and connect() only at the client side. I don't know about his UDP suggestion, that's a different matter.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          Do you mean the OS' functions in that last post, because I meant Qt's API.

          Read and abide by the Qt Code of Conduct

          JonBJ 1 Reply Last reply
          0
          • kshegunovK kshegunov

            Do you mean the OS' functions in that last post, because I meant Qt's API.

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #5

            @kshegunov
            Is that addressed to me?

            In my reply I was attempting to back up your previous reply. Perhaps I gave too much (non-Qt) information. I haven't even looked up what Qt names its functions, sounds like with QTcpSocket you use bind() only at server side and connectToHost() only at client side.

            kshegunovK 1 Reply Last reply
            0
            • JonBJ JonB

              @kshegunov
              Is that addressed to me?

              In my reply I was attempting to back up your previous reply. Perhaps I gave too much (non-Qt) information. I haven't even looked up what Qt names its functions, sounds like with QTcpSocket you use bind() only at server side and connectToHost() only at client side.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @JonB said in Impossible to bind QTcpSocket again after connection error:

              Is that addressed to me?

              Yep, says to whom I replied rightwards of the post's date.

              In my reply I was attempting to back up your previous reply. Perhaps I gave too much (non-Qt) information.

              Mhm, I got that. I Just wondered whether the functions you mentioned you meant as the C functions one'd usually use for networking.

              Read and abide by the Qt Code of Conduct

              JonBJ 1 Reply Last reply
              0
              • kshegunovK kshegunov

                @JonB said in Impossible to bind QTcpSocket again after connection error:

                Is that addressed to me?

                Yep, says to whom I replied rightwards of the post's date.

                In my reply I was attempting to back up your previous reply. Perhaps I gave too much (non-Qt) information.

                Mhm, I got that. I Just wondered whether the functions you mentioned you meant as the C functions one'd usually use for networking.

                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by JonB
                #7

                @kshegunov
                Yes, indeed they are the C functions I used years ago, and still recall fondly :) They were native under UNIX, and provided under same names by WinSock. IMHO, if you want to get anything done and still understand what's going on underneath all the obfuscation layers C++ attempts to pile on, you need to know what it's ultimately calling at the OS level, because that's all the C++ still has available to it ;-)

                kshegunovK 1 Reply Last reply
                0
                • JonBJ JonB

                  @kshegunov
                  Yes, indeed they are the C functions I used years ago, and still recall fondly :) They were native under UNIX, and provided under same names by WinSock. IMHO, if you want to get anything done and still understand what's going on underneath all the obfuscation layers C++ attempts to pile on, you need to know what it's ultimately calling at the OS level, because that's all the C++ still has available to it ;-)

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #8

                  @JonB said in Impossible to bind QTcpSocket again after connection error:

                  all the obfuscation layers C++

                  We call them abstraction layers, you see. ;)

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  2
                  • K Offline
                    K Offline
                    Karlor
                    wrote on last edited by
                    #9

                    Thank you for your answers.

                    I have realized I have missed maybe something important. On client side computers are installed multiple network interfaces.

                    I have been informed that the binding in the client side part of our software is implemented for purpose to connect with appropriate network interface to connect to the right server and must use QTcpSocket::bind() with QAbstractSocket::ReuseAddressHint.

                    But even with multiple network interfaces I think @kshegunov's answer is still right. I have tested connections to servers without binding and everything works fine.

                    I would like to ask to some subquestions to this topic.

                    • I am confused by Qt documentation for QAbstractSocket::bind() where is written

                    For TCP sockets, this function may be used to specify which interface to use for an outgoing connection, which is useful in case of multiple network interfaces.

                    Even with multiple network interfaces the binding is not mandatory and only connectToHost() to IP server address should be sufficient, isn't it?

                    • Is it true that binding in mode QAbstractSocket::ReuseAddressHint in calling
                    socket.bind(bindAddress, 0, QAbstractSocket::ReuseAddressHint)
                    

                    is useless, because it will use any available port (the second argument is 0) and reusing has no effect in this case?

                    kshegunovK 1 Reply Last reply
                    0
                    • K Karlor

                      Thank you for your answers.

                      I have realized I have missed maybe something important. On client side computers are installed multiple network interfaces.

                      I have been informed that the binding in the client side part of our software is implemented for purpose to connect with appropriate network interface to connect to the right server and must use QTcpSocket::bind() with QAbstractSocket::ReuseAddressHint.

                      But even with multiple network interfaces I think @kshegunov's answer is still right. I have tested connections to servers without binding and everything works fine.

                      I would like to ask to some subquestions to this topic.

                      • I am confused by Qt documentation for QAbstractSocket::bind() where is written

                      For TCP sockets, this function may be used to specify which interface to use for an outgoing connection, which is useful in case of multiple network interfaces.

                      Even with multiple network interfaces the binding is not mandatory and only connectToHost() to IP server address should be sufficient, isn't it?

                      • Is it true that binding in mode QAbstractSocket::ReuseAddressHint in calling
                      socket.bind(bindAddress, 0, QAbstractSocket::ReuseAddressHint)
                      

                      is useless, because it will use any available port (the second argument is 0) and reusing has no effect in this case?

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #10

                      @Karlor said in Impossible to bind QTcpSocket again after connection error:

                      Even with multiple network interfaces the binding is not mandatory and only connectToHost() to IP server address should be sufficient, isn't it?

                      If it connects then it should be sufficient. I haven't had this particular case, however I imagine the bind() is required to specify your outgoing address (a.k.a. interface), so you're using the correct network. If there isn't ambiguity then I suppose connectToHost would do on its own.

                      Is it true that binding in mode QAbstractSocket::ReuseAddressHint in calling
                      [snippet]

                      That line looks correct, yes.

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      2
                      • K Offline
                        K Offline
                        Karlor
                        wrote on last edited by
                        #11

                        Fortunately in our case the connection via QTcpSocket::connectToHost() without need QTcpSocket::bind() is sufficient. However, this may change in the future, and it may need to specify the outgoing network interface, so the problem of stacked binding of QTcpSocket will be there again.

                        I found hypothetic scenario in which things might go worse if an error occurred. Imagine having two network interfaces labeled as N1 and N2. N1 is disconnected from the network. If the user accidentally decides to bind via QTcpSocket::bind() to N1, the connection fails. Changing the connection to N2 is now impossible. I guess it is impossible because QTcpSocket is still bounded to N1, so rebind to N2 fails and the connection to N2 is not possible.

                        Do you know how to reset QTcpSocket to use QTcpSocket::bind() again?

                        1 Reply Last reply
                        1

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved