Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if a client connected to a QTcpServer has closed connection?

I want to pass data from a particular location (Shared Memory) to client applications. A thread continuously polls the SHM for new data and as soon as it gets something, it passes it onto the clients.

There can be multiple instances of such client applications which will be connecting to my (QTcpServer) server.

I am planning to simply create a new QTcpSocket each time my server receives a new connection and store all those sockets in a vector. Later, on each successful poll, I will write the data to all the QTcpSocket's stored in the vector.

But if a client drops a connection (closes his window) I need to know about it! Othewise I will keep writing to QTcpSocket's that are no longer existing and end up crashing.

What is the solution here ?

There are only 2 signals in QTcpServer class:

Signals
void    acceptError(QAbstractSocket::SocketError socketError)
void    newConnection()
2 signals inherited from QObject
like image 237
Chani Avatar asked Oct 20 '25 05:10

Chani


1 Answers

You have a class that contains a vector or list of the sockets. So long as this class is derived from QObject, you can use the signals and slots of QTcpSocket to notify the class when it is disconnected.

So, I'd do something like this: -

class Server : public QObject
{
    Q_OBJECT

    public:
        Server();

    public slots:
        // Slot to handle disconnected client
        void ClientDisconnected(); 

    private slots:
        // New client connection
        void NewConnection();

    private:
        QTcpSocket* m_pServerSocket;
        QList<QTcpSocket*> m_pClientSocketList;
};

Server::Server()
{   // Qt 5 connect syntax
    connect(m_pServerSocket, &QTcpServer::newConnection, this, &Server::NewConnection);
}

void Server::NewConnection()
{
    QTcpSocket* pClient = nextPendingConnection();
    m_pClientSocketList.push_back(pClient);

    // Qt 5 connect syntax
    connect(pClient, &QTcpSocket::disconnected, this, &Server::ClientDisconnected);
}

void Server::ClientDisconnected()
{
    // client has disconnected, so remove from list
    QTcpSocket* pClient = static_cast<QTcpSocket*>(QObject::sender());
    m_pClientSocketList.removeOne(pClient);
}
like image 148
TheDarkKnight Avatar answered Oct 22 '25 19:10

TheDarkKnight