Qt UDP 单独在子线程执行
一.需要用到的类
QThread和QUDPSocket
.pro文件中需要引入模块
QT = network
常用接口:
1.bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform) ;//绑定端口
2.qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port);//发送数据
3.void abort() ;//关闭连接
4.qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR);//读数据
每当有数据接收的时候,QUdpSocket都会发送 readyRead()信号,只需要绑定上槽就能接收到数据。
二.server work类
此类的作用主要实现UDP之间的通信,直接上代码。
-
//WUDPServerWorker.h
-
-
-
-
-
-
-
-
class WUDPServerWorker : public QObject
-
{
-
Q_OBJECT
-
public:
-
explicit WUDPServerWorker(QObject *parent = nullptr);
-
~WUDPServerWorker();
-
-
public slots:
-
//绑定槽函数
-
void slotBind(quint16 port);
-
-
void slotBind(QString ip,quint16 port);
-
-
void slotUnBind();
-
-
void slotSendDatagram(const QByteArray &data,const QHostAddress &host, quint16 port);
-
-
public:
-
//绑定端口
-
bool bind(quint16 port = 0, QUdpSocket::BindMode mode = QUdpSocket::DefaultForPlatform);
-
-
bool bind(const QHostAddress &address, quint16 port = 0, QUdpSocket::BindMode mode = QUdpSocket::DefaultForPlatform);
-
-
//解绑端口
-
void unBind();
-
-
//发送数据
-
qint64 sendDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
-
-
//发送数据
-
qint64 sendDatagram(const QByteArray &data,const QHostAddress &host, quint16 port);
-
-
signals:
-
//发送UDP数据
-
void sigReceiveData(const QByteArray &byte);
-
-
private slots:
-
//收到UDP数据
-
void slotReadyRead();
-
-
private:
-
QUdpSocket *m_udpSocket = nullptr; //UDP socket
-
};
-
-
-
-
/WUDPServerWorker.cpp
-
-
-
-
-
WUDPServerWorker::WUDPServerWorker(QObject *parent)
-
: QObject(parent)
-
{
-
m_udpSocket = new QUdpSocket(this);
-
connect(m_udpSocket,SIGNAL(readyRead()),this,SLOT(slotReadyRead()));
-
}
-
-
WUDPServerWorker::~WUDPServerWorker()
-
{
-
if(m_udpSocket)
-
{
-
unBind();
-
delete m_udpSocket;
-
}
-
}
-
-
void WUDPServerWorker::slotBind(quint16 port)
-
{
-
bind(port);
-
}
-
-
void WUDPServerWorker::slotBind(QString ip, quint16 port)
-
{
-
bind(QHostAddress(ip),port);
-
}
-
-
void WUDPServerWorker::slotUnBind()
-
{
-
unBind();
-
}
-
-
void WUDPServerWorker::slotSendDatagram(const QByteArray &data, const QHostAddress &host, quint16 port)
-
{
-
m_udpSocket->writeDatagram(data,host,port);
-
}
-
-
bool WUDPServerWorker::bind(quint16 port, QAbstractSocket::BindMode mode)
-
{
-
return m_udpSocket->bind(port,mode);
-
}
-
-
bool WUDPServerWorker::bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode)
-
{
-
return m_udpSocket->bind(address,port,mode);
-
}
-
-
-
void WUDPServerWorker::unBind()
-
{
-
m_udpSocket->abort();
-
}
-
-
qint64 WUDPServerWorker::sendDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port)
-
{
-
return m_udpSocket->writeDatagram(data,len,host,port);
-
}
-
-
qint64 WUDPServerWorker::sendDatagram(const QByteArray &data, const QHostAddress &host, quint16 port)
-
{
-
return m_udpSocket->writeDatagram(data,host,port);
-
}
-
-
void WUDPServerWorker::slotReadyRead()
-
{
-
//是否还有待读取的传入数据报
-
while(m_udpSocket->hasPendingDatagrams())
-
{
-
QByteArray data;
-
-
//返回待读取的数据报的字节数
-
data.resize(m_udpSocket->pendingDatagramSize());
-
-
QHostAddress peerAddr;
-
-
quint16 peerPort;
-
-
//读取数据报的内容
-
m_udpSocket->readDatagram(data.data(),data.size(),&peerAddr,&peerPort);
-
-
QString port = QString::number(m_udpSocket->localPort());
-
QString peerStr = port " *****recieve udp data [From ] " peerAddr.toString() ":" QString::number(peerPort) "] ";
-
qDebug()<<peerStr;
-
qDebug()<<QThread::currentThreadId();
-
-
emit sigReceiveData(data);
-
}
-
}
-
-
每当有数据收到后,会调用slotReadyRead()槽函数,然后readDatagram()读取数据,可以知道数据来源的地址和端口号。
三.server类
此类主要作用是让udp在单独线程运行,因为UDP在单独线程里面跑,所以通过信号-槽的方式,调用bind()、发送数据等方法。
-
-
-
-
-
-
-
-
-
-
-
class WUDPServerWorker;
-
-
class WUDPServer : public QObject
-
{
-
Q_OBJECT
-
public:
-
explicit WUDPServer(QObject *parent = nullptr);
-
~WUDPServer();
-
-
signals:
-
void sigBind(quint16 port);
-
-
void sigBind(QString ip,quint16 port);
-
-
void sigUnBind();
-
-
void sigSendDatagram(const QByteArray &data, const QHostAddress &host, quint16 port);
-
-
public:
-
//发送数据
-
qint64 sendDatagram(const QByteArray &data, const QHostAddress &host, quint16 port);
-
//绑定端口
-
bool bind(quint16 port = 0, QUdpSocket::BindMode mode = QUdpSocket::DefaultForPlatform);
-
-
bool bind(const QHostAddress &address, quint16 port = 0, QUdpSocket::BindMode mode = QUdpSocket::DefaultForPlatform);
-
-
//解绑端口
-
void unBind();
-
-
//开始线程
-
void start();
-
-
private slots:
-
//收到UDP数据
-
void slotReceiveUdpData(const QByteArray&);
-
-
private:
-
QThread m_workerThread; //UDP工作线程
-
-
WUDPServerWorker *m_work = nullptr; //UDP工作类
-
-
QTimer *m_timer = nullptr;
-
};
-
-
-
-
-
-
///WUDPServer.cpp
-
-
-
-
-
WUDPServer::WUDPServer(QObject *parent)
-
: QObject(parent)
-
{
-
m_work = new WUDPServerWorker;
-
-
m_work->moveToThread(&m_workerThread);
-
connect(this,SIGNAL(sigBind(QString,quint16)),m_work,SLOT(slotBind(QString,quint16)));
-
connect(this,SIGNAL(sigBind(quint16)),m_work,SLOT(slotBind(quint16)));
-
connect(this,SIGNAL(sigUnBind()),m_work,SLOT(slotUnBind()));
-
connect(this,&WUDPServer::sigSendDatagram,m_work,&WUDPServerWorker::slotSendDatagram);
-
-
connect(&m_workerThread, &QThread::finished, m_work, &QObject::deleteLater);
-
connect(m_work,SIGNAL(sigReceiveData(QByteArray)),this,SLOT(slotReceiveUdpData(QByteArray)));
-
}
-
-
WUDPServer::~WUDPServer()
-
{
-
m_workerThread.quit();
-
m_workerThread.wait();
-
}
-
-
qint64 WUDPServer::sendDatagram(const QByteArray &data, const QHostAddress &host, quint16 port)
-
{
-
emit sigSendDatagram(data,host,port);
-
}
-
-
bool WUDPServer::bind(quint16 port, QUdpSocket::BindMode mode)
-
{
-
Q_UNUSED(mode);
-
emit sigBind(port);
-
}
-
-
bool WUDPServer::bind(const QHostAddress &address, quint16 port, QUdpSocket::BindMode mode)
-
{
-
Q_UNUSED(mode);
-
emit sigBind(address.toString(),port);
-
}
-
-
void WUDPServer::unBind()
-
{
-
emit sigUnBind();
-
}
-
-
void WUDPServer::start()
-
{
-
m_workerThread.start();
-
}
-
-
void WUDPServer::slotReceiveUdpData(const QByteArray& byte)
-
{
-
//处理数据
-
qDebug()<<byte;
-
}
-
-
在类中创建了一个线程,将WUDPServerWorker对象放在线程中运行,调用moveToThread()方法即可,需要绑定两个槽,
connect(&m_workerThread,&QThread::finished,&m_workerThread,&QObject::deleteLater)
connect(&m_workerThread, &QThread::finished, m_work, &QObject::deleteLater);
在线程完成后,释放资源,不但要释放线程本身,还需要释放WUDPServerWorker对象。
在程序退出时需要调用以下方法,优雅的结束线程。
m_workerThread.quit();
m_workerThread.wait();
使用方法:
-
WUDPServer *server = new WUDPServer(this);
-
server->start();
-
server->bind(8888);
四.更多参考
五.源码
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbeehh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13