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. Exception after deletion QTcpSocket
Qt 6.11 is out! See what's new in the release blog

Exception after deletion QTcpSocket

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 3.1k 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.
  • H Offline
    H Offline
    Heliconter
    wrote on last edited by
    #1

    Hi,
    I wrote a simple Server class that accepts the first connection request, but rejects other. When the first connection is disconnected, the server can again accept the first another connection request.
    I wrote a simple code to test the Server class. This code sets up connection to the Server, then it disconnects from and then reconnects to the Server.
    But when I run Server application and test application I get an exception on the "a.exec();" line of main.cpp file of the Server application.
    I suspect that it is somehow related with socket deletion, because when I remove the "delete m_socket;" line in the server.cpp this exception disappears.
    What have I done wrong?

    main.cpp of Server application
    #include <QCoreApplication>
    #include "server.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Server server;
        server.listen(QHostAddress::Any, 47326);
    
        return a.exec();
    }
    
    server.h
    #ifndef SERVER_H
    #define SERVER_H
    
    #include <QTcpServer>
    #include <QTcpSocket>
    
    class Server : public QObject
    {
        Q_OBJECT
    public:
        explicit Server(QObject *parent = nullptr);
    
        void listen(QHostAddress hostAddress, quint16 port);
    
    public slots:
        void handleConnectionRequest();
        void handleSocketDisconnetion();
    
    private:
        QTcpServer *m_server;
        QTcpSocket *m_socket = nullptr;
    };
    
    #endif // SERVER_H
    
    
    server.cpp
    #include "server.h"
    
    Server::Server(QObject *parent)
        : QObject(parent),
          m_server(new QTcpServer(this))
    {
        connect(m_server, &QTcpServer::newConnection, this, &Server::handleConnectionRequest);
    }
    
    void Server::listen(QHostAddress hostAddress, quint16 port)
    {
        m_server->listen(hostAddress, port);
    }
    
    void Server::handleConnectionRequest()
    {    
        QTcpSocket *socket = m_server->nextPendingConnection();
    
        qInfo() << "New connection request entered";
    
        if (m_socket == nullptr)
        {
            m_socket = socket;
            connect(socket, &QTcpSocket::disconnected, this, &Server::handleSocketDisconnetion);
            qInfo() << "The connection request is accepted";
        }
        else
        {
            delete socket;
            qInfo() << "The connection request is rejected";
        }
    }
    
    void Server::handleSocketDisconnetion()
    {
        delete m_socket;
        m_socket = nullptr;
    
        qInfo() << "Socket is deleted";
    }
    
    main.cpp of test application
    #include <QCoreApplication>
    #include <QTcpSocket>
    #include <QHostAddress>
    #include <QThread>
    
    void connect(QTcpSocket &socket)
    {
        socket.connectToHost(QHostAddress("127.0.0.1"), 47326);
        if (socket.waitForConnected(-1))
            qInfo() << "Connected";
        else
            qInfo() << socket.errorString();
    
        QThread::msleep(100);
    }
    
    void disconnect(QTcpSocket &socket)
    {
        socket.disconnectFromHost();
        if (socket.state() == QAbstractSocket::UnconnectedState || socket.waitForDisconnected(-1))
            qInfo() << "Disconnected";
        else
            qInfo() << socket.errorString();
    
        QThread::msleep(100);
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QTcpSocket socket;
    
        connect(socket);
        disconnect(socket);
        connect(socket);
    
        return a.exec();
    }
    
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You should rather use socker->deleteLater();. That will allow the event loop to handle pending actions on the socket.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      H 1 Reply Last reply
      5
      • SGaistS SGaist

        Hi and welcome to devnet,

        You should rather use socker->deleteLater();. That will allow the event loop to handle pending actions on the socket.

        H Offline
        H Offline
        Heliconter
        wrote on last edited by
        #3

        @SGaist Thank you, deleteLater () eliminates the exception.
        Could you give advice when should I use deleteLater() to delete a QObject?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Each time you want to delete a connected QObject.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          VRoninV 1 Reply Last reply
          1
          • SGaistS SGaist

            Each time you want to delete a connected QObject.

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            @SGaist said in Exception after deletion QTcpSocket:

            connected QObject.

            Specifically, a QObject connected on the receiving end (i.e. the QObject you are deleting might be called "as a slot").
            Calling deleteLater() after the thread event loop finished is a memory leak however

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            2
            • H Offline
              H Offline
              Heliconter
              wrote on last edited by
              #6

              Probably I have found answers about using deleteLater().
              https://stackoverflow.com/a/4889395
              http://doc.qt.io/qt-5/qobject.html#deleteLater
              http://doc.qt.io/qt-5/qobject.html#dtor.QObject

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                To cover 90% of use cases:
                if you are in the main thread and you use the classic main:

                int main(int argc, char *argv[])
                {
                QCoreApplication a(argc, argv);
                //something
                return a.exec();
                }
                

                then always use deleteLater() as it's 100% safe.

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                2

                • Login

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