系统老化平台------QT线程实现扫描IP和端口
一、说明
由于项目需要,需要做一个上位机实现自动化老化的平台,由于其中需求很多,所以通过分布实现。通过记录开发过程,也算是学习的一种方式了,今天就先以QT线程实现扫描IP和端口作为开端。
二、开发环境
目前使用的开发平台是基于window平台下的QT开发,使用的QT版本5.19.2。但是现在QT的官网上已经不提供其离线的安装包。
三、QT实现的两种方式
1、重写run函数实现线程
QT提供一个专门的类来管理线程------Qthread。通过继承Qthread来自定义一个类,并重新定义虚函数run(),然后在run()函数里实现线程需要完成的任务。通过start()来启动函数,因为start()会在内部调用run(),通过quit()退出线程。
2、继承Qobject,通过MoveToThread实现线程
这个也是QT官方推荐线程实现采用这种方式,主要是通过自定义的类继承Qobject,在类中创建Qthread和Qwork(泛指需要线程实现的类)成员,通过MoveToThread()函数将两个成员移动至线程,那么Qwork类中运行的函数则为线程函数,激活线程方式就通过信号和槽实现;
所以对比两种方式可以看出来,第一种适用用于实现较为简单的、重复的工作。而第二种适用大部分的工作场景,只是代码稍复杂些。而接下来,我将用第一种方式来实现扫描IP和端口,从而使在扫描过程中不影响主界面正常运行。
四、 实现过程
以此项目为例:将IP网段为192.168.1.1~192.168.3.255的所有IP中,查找502端口在线的设备。
1、继承Qthread
threadipportscan.h
#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QThread>
#include <QStringList>
class ThreadIpPortScan : public QThread
{
Q_OBJECT
public:
ThreadIpPortScan();
~ThreadIpPortScan();
private:
bool m_b_paused = true;
bool m_b_stop = false;
int m_i_onlinenum = 0;
QStringList m_qstringlist_onlineip;
protected:
void run() Q_DECL_OVERRIDE; //函数重载,此时运行的函数为线程函数,Q_DECL_OVERRIDE一致的;
public:
void search_begin(void); //开始搜寻
void search_done(void); //完成搜寻
void search_stop(void); //停止搜寻
signals:
// 进度的信号,其中包括当前查找的在线系统数量
void signal_scan_progress(int);
// 完成时的信号,需要将所以的IP地址通过Qlist回传至主线程显示;
void signal_online_ip(QStringList);
};
threadipportscan.cpp
#include "threadipportscan.h"
#include <QDebug>
#include <QTcpSocket>
ThreadIpPortScan::ThreadIpPortScan()
{
}
ThreadIpPortScan::~ThreadIpPortScan()
{
this->search_stop();
this->wait();
this->deleteLater();
}
void ThreadIpPortScan::run()
{
//线程任务
while (!m_b_stop)
{
if(!m_b_paused)
{
qDebug() << QThread::currentThreadId() << endl;
m_i_onlinenum = 0;
m_qstringlist_onlineip.clear();
int l_int_scan_progress = 0;
QTcpSocket t_socket(0);
t_socket.abort();
QString t_ip("192.168.0.0"); //这里是固定的,后续可以做成可选择网关扫描<