Qt端口扫描器(多进程)

简介:该扫描器实现了多线程进行扫描,同时支持端口范围,显示所有已打开端口列表。

开发环境:Ubuntu16.04

开发平台:Qt5.9

语言:C++

实现:本程序用的是TCP connect扫描,也是最基本的扫描,利用系统提供的connect()用来与每一个目标计算机的端口进行连接。如果端口处于侦听状态,那connect()就能成功。否则,这个端口即是不可用的,也就是说没有提供服务。

优点:这个技术的一个最大的优点是,你不需要任何权限。系统中的任何用户都有权利使用这个调用。另一个好处就是速度,如果对每个目标端口以线性的方式,使用单独的connect()调用,那么将花费相当长的时间,使用者可以通过多线程同时打开多个套接字来加速扫描。使用非阻塞I/O允许设置一个低的时间用尽周期,同时观察多个套接字。

缺点:但这种方法的缺点是很容易被察觉,并且被防火墙将扫描信息包过滤掉。

目标计算机的Logs文件会显示一连串的连接和连接出错消息,并且能很快使它关闭。

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用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多线程实现局域网端口扫描的示例代码项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原来是阿中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值