qt用多线程实现局域网端口扫描代码项目
时间: 2023-11-16 14:13:02 浏览: 149
QT实现端口扫描
4星 · 用户满意度95%
以下是一个使用Qt多线程实现局域网端口扫描的示例代码项目:
首先,我们需要创建一个QObject子类用于执行端口扫描操作。我们将使用QTcpSocket来检查每个端口是否打开。这是PortScanner类的头文件:
```
#ifndef PORTSCANNER_H
#define PORTSCANNER_H
#include <QObject>
#include <QTcpSocket>
#include <QHostAddress>
class PortScanner : public QObject
{
Q_OBJECT
public:
explicit PortScanner(QObject *parent = nullptr);
signals:
void portFound(int port);
void finished();
public slots:
void scanPort(int port);
private:
QTcpSocket *m_socket;
QHostAddress m_address;
};
#endif // PORTSCANNER_H
```
在PortScanner类中,我们有两个信号:portFound和finished。portFound信号将在找到一个打开的端口时发射,finished信号将在扫描完成时发射。我们也有一个public槽,用于扫描特定的端口。
下面是PortScanner.cpp文件的实现:
```
#include "portscanner.h"
PortScanner::PortScanner(QObject *parent) : QObject(parent)
{
m_socket = new QTcpSocket(this);
}
void PortScanner::scanPort(int port)
{
m_socket->connectToHost(m_address, port);
if(m_socket->waitForConnected(1000))
{
emit portFound(port);
}
m_socket->disconnectFromHost();
}
```
在scanPort槽中,我们使用QTcpSocket连接到指定端口,并等待1秒钟检查连接是否成功。如果连接成功,则发射portFound信号。
接下来,我们需要创建一个Qt多线程类,用于执行PortScanner对象的扫描任务。这是PortScannerThread类的头文件:
```
#ifndef PORTSCANNERTHREAD_H
#define PORTSCANNERTHREAD_H
#include <QObject>
#include <QThread>
#include "portscanner.h"
class PortScannerThread : public QThread
{
Q_OBJECT
public:
explicit PortScannerThread(QObject *parent = nullptr);
signals:
void portFound(int port);
public slots:
void setHostAddress(QString address);
void stop();
protected:
void run() override;
private:
QString m_address;
bool m_stop;
};
#endif // PORTSCANNERTHREAD_H
```
在PortScannerThread类中,我们有一个槽setHostAddress,用于设置要扫描的主机地址。我们还有一个stop槽,用于停止扫描任务。我们还定义了一个portFound信号,用于在找到打开的端口时发射。
下面是PortScannerThread.cpp文件的实现:
```
#include "portscannerthread.h"
PortScannerThread::PortScannerThread(QObject *parent) : QThread(parent)
{
m_stop = false;
}
void PortScannerThread::setHostAddress(QString address)
{
m_address = address;
}
void PortScannerThread::stop()
{
m_stop = true;
}
void PortScannerThread::run()
{
PortScanner scanner;
scanner.moveToThread(this);
connect(this, &PortScannerThread::finished, &scanner, &QObject::deleteLater);
connect(this, &PortScannerThread::portFound, this, &PortScannerThread::portFound);
scanner.finished.connect(this, &PortScannerThread::finished);
scanner.finished.connect(&scanner, &PortScanner::deleteLater);
m_stop = false;
QHostAddress address(m_address);
scanner.m_address = address;
for(int port=1; port<=65535; port++)
{
if(m_stop)
break;
scanner.scanPort(port);
}
emit finished();
}
```
在run函数中,我们创建一个PortScanner对象,并将其移动到当前线程中。我们还建立了一些信号和槽,以确保正确的通信。然后,我们迭代所有可能的端口,并使用PortScanner对象扫描每个端口。如果扫描任务被停止,则退出循环。
最后,我们可以在主窗口中使用PortScannerThread类执行扫描任务。这是MainWindow类的头文件:
```
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "portscannerthread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_startButton_clicked();
void on_stopButton_clicked();
void on_portFound(int port);
private:
Ui::MainWindow *ui;
PortScannerThread *m_thread;
};
#endif // MAINWINDOW_H
```
在MainWindow类中,我们有两个按钮:startButton和stopButton。我们还有一个m_thread成员变量,用于执行扫描任务。
下面是MainWindow.cpp文件的实现:
```
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_thread = new PortScannerThread(this);
connect(m_thread, &PortScannerThread::portFound, this, &MainWindow::on_portFound);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_startButton_clicked()
{
if(m_thread->isRunning())
return;
QString address = ui->addressEdit->text();
m_thread->setHostAddress(address);
m_thread->start();
}
void MainWindow::on_stopButton_clicked()
{
if(!m_thread->isRunning())
return;
m_thread->stop();
m_thread->wait();
}
void MainWindow::on_portFound(int port)
{
ui->resultTextEdit->append(QString("Port %1 is open.").arg(port));
}
```
在on_startButton_clicked槽中,我们使用用户输入的地址创建一个扫描任务,并启动线程。在on_stopButton_clicked槽中,我们停止扫描任务并等待线程退出。在on_portFound槽中,我们将找到的打开的端口显示在文本编辑器中。
这就是使用Qt多线程实现局域网端口扫描的示例代码项目。
阅读全文