Question

I've created a hello-world program to help me understand how QTcpServer and QTcpSocket work. In it the QTcpServer accepts new connections and connects their readyRead() signal to the MainWindow::onNewData() slot where their new data is appended to a plain text control.

The problem is that multiple sockets can be opened simultaneously. So when I get the readyRead() signal and I want to read the data with readAll(), how do I know which socket emitted it?

Here's the relevant parts of the code. I'm not storing the QTcpSocket pointers at all here, but even if I did, I still wouldn't know which one of them emitted the signal.

    // constructor
    server = new QTcpServer(this);
    connect(server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
    server->listen(QHostAddress::LocalHost, 3333);

void MainWindow::onNewConnection()
{
    QTcpSocket* socket = server->nextPendingConnection();
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
    connect(socket, SIGNAL(readyRead()), this, SLOT(onNewData()));
}

void MainWindow::onNewData()
{
    ui->plainTextEdit->appendPlainText(WHICH_SOCKET_EMITTED_IT()->readAll());
}
Was it helpful?

Solution

The best way (as it seems to me) is to implement your own Client class which will encapsulate QTcpSocket

class Client : public QObject
{
Q_OBJECT
public:
    Client(QTcpSocket *socket)
        : m_socket(socket)
{
    connect(socket, SIGNAL(readyRead()), this, SLOT(onNewData()));
}

private slots:
    void onNewData();

private:
    QTcpSocket *m_socket;
};

Easiest way: use QObject::sender() in slot function

OTHER TIPS

Using a C++11 lambda functions in the connect statement, it's also possible to do this without the sender() function:

connect(socket, &QIODevice::readyRead,
        [this, socket()] { readData(socket) });

and a matching function (which does not need to be but can be a slot):

void foo::readData(QTcpSocket *socket)
{
    socket->whatever();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top