Qt QTcpServer类一个类(线程)listen监听连接,另一个类(线程)收发数据。
Qt规定,QTcpSocket不能作为参数传递。如果做参数传递,编译时就会报错提示。
用server端获取到连接QTcpSocket对象后如果要另一个线程收发数据。连接线程中新连接信号QTcpServer::newConnection的自定义槽函数中 ,通过QTcpServer::nextPendingConnection()返回获取到QTcpSocket对象,然后通过QTcpSocket::socketDescriptor()获取到socketDescriptor后,发信号传递给另一个线程中建立QTcpSocket对象,再setSocketDescriptor(),就获得了这个QTcpSocket对象。并且可以通过它获取到连接双方ip、port等信息。接收线程槽函数如下:
void CommCtrl::slotSocketConncet(qintptr socketDescriptor)
{
QTcpSocket* pTcpSocket = new QTcpSocket(this);
m_socketList.append(pTcpSocket);//添加到QTcpSocket*的列表,方便管理
pTcpSocket->setSocketDescriptor(socketDescriptor);
connect(pTcpSocket, &QTcpSocket::readyRead, this, &CommCtrl::slotNetReadReady); //有可读的信息,触发读槽函数
connect(pTcpSocket, &QTcpSocket::disconnected, this, &CommCtrl::slotSocketDisconnect);
qDebug() << "connect" << pTcpSocket->peerAddress().toString() << ":" << pTcpSocket->peerPort();
}
但是,这样程序会报警告:
QSocketNotifier: Multiple socket notifiers for same socket 1100 and type Read
查资料了解到,这时需要重写QTcpServer类的虚函数解决这个问题。
protected:
virtual void incomingConnection(qintptr socketDescriptor);
重写QTcpServer类中的虚函数void incomingConnection(qintptr socketDescriptor),就可以获取到socketDescriptor了,而这时QTcpSocket还不会创建,自然不会报QSocketNotifier: Multiple socket notifiers for same socket 1100 and type Read。
重写类头文件:
#ifndef TCPSERVERTHR_H
#define TCPSERVERTHR_H
#include <QTcpServer>
class TcpServerThr : public QTcpServer
{
Q_OBJECT
public:
explicit TcpServerThr(QObject *parent = nullptr);
private:
void incomingConnection(qintptr socketDescriptor);
signals:
void signalNewConnection(qintptr socketDescriptor);
};
#endif // TCPSERVERTHR_H
重写类源文件:
#include "tcpserverthr.h"
#include <QDebug>
TcpServerThr::TcpServerThr(QObject *parent) : QTcpServer(parent)
{
}
void TcpServerThr::incomingConnection(qintptr socketDescriptor)
{
emit signalNewConnection(socketDescriptor);
qDebug() << "TcpServerThr::incomingConnection()";
}