Как узнать, какой QTcpSocket испустил сигнал readyRead ()?
Я создал программу hello-world, которая поможет мне понять, как работают QTcpServer и QTcpSocket. В нем QTcpServer принимает новые соединения и подключает их сигнал readyRead() к слоту MainWindow::onNewData(), где их новые данные добавляются к элементу управления простым текстом.
Проблема в том, что одновременно можно открыть несколько сокетов. Итак, когда я получаю сигнал
readyRead() и хочу прочитать данные с помощью readAll(), Как я узнаю, какой сокет его испустил?Вот соответствующие части кода. Я здесь вообще не хранятся указатели QTcpSocket, но даже если бы я это сделал, я все равно не знал бы, какой из них испускает сигнал.
// 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());
}
2 ответов:
Лучший способ (как мне кажется) - это реализовать свой собственный
Clientкласс, который будет инкапсулироватьQTcpSocketclass 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; };Самый простой способ: использовать
QObject::sender()в функции слота
Используя лямбда-функции C++11 в операторе connect, можно также сделать это без функции
sender():connect(socket, &QIODevice::readyRead, [this, socket()] { readData(socket) });И соответствующая функция (которая не должна быть, но может быть слотом):
void foo::readData(QTcpSocket *socket) { socket->whatever(); }
Comments