我创建了一个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());
}
最好的方式(在我看来)是实现你自己的Client
类,它将封装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;
};
最简单的方法:在插槽功能中使用QObject::sender()
在connect语句中使用C ++ 11 lambda函数,也可以在没有sender()
函数的情况下执行此操作:
connect(socket, &QIODevice::readyRead,
[this, socket()] { readData(socket) });
和匹配函数(不需要但可以是一个插槽):
void foo::readData(QTcpSocket *socket)
{
socket->whatever();
}