Chani
Chani

Reputation: 5165

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

Upvotes: 4

Views: 5039

Answers (2)

TheDarkKnight
TheDarkKnight

Reputation: 27611

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);
}

Upvotes: 5

Massimo Costa
Massimo Costa

Reputation: 1860

You must set the TCP KeepAplive option to the socket in this way:

mySocket->setSocketOption(QAbstractSocket:: KeepAliveOption, 1);

Upvotes: 0

Related Questions