zoukankan      html  css  js  c++  java
  • Qt实现端口扫描器

    首先展示一下效果:

    界面通过Qt设计师做出来的。

    主要有两个类。

    首先主函数:

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }

    实现UI循环。

    第一个类,主窗体类:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QString>
    #include <QDebug>
    #include <QTcpSocket>
    #include "scanner.h"
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        bool checkip(QString ip);
        void startscanner(QString ip,int startport,int endport);
    
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();//开始扫描
        void setBar(int value);//修改进度条
    
        void on_pushButton_2_clicked();//暂停
    
        void on_pushButton_3_clicked();//终止
    
    private:
        Ui::MainWindow *ui;
        Scanner *scanner;
        bool threadisrunnig;
    
    };
    
    #endif // MAINWINDOW_H

    因为是用的Qt设计师,所以函数名有点挫。

    然后是扫描线程类,用来扫描端口:

    #ifndef SCANNER_H
    #define SCANNER_H
    #include<QThread>
    class Scanner:public QThread
    {
        Q_OBJECT
    
    public:
        Scanner();
        void run();//不多说,自己Google
        void stop();//实现线程安全停止,用Terminate是不安全的
    signals:
        sentnowport(int value);//更新进度条
    private:
         volatile bool stopped;
    
    };
    #endif // SCANNER_H

    类实现:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QMutex>
    #include<QThread>
    #include<QProgressBar>
    #include <QGraphicsItem>
    
    QMutex percent;
    QMutex mutex;
    QMutex text;
    int nowport;
    int staport;
    int endport;
    
    QString ip;
    QTextEdit *result;
    
    Scanner::Scanner()
    {
        stopped=false;
    }
    
    void Scanner::run()
    {
        while(!stopped)
        {
            if(nowport>endport)
            {
                break;
            }
    
            mutex.lock();
            int tmpport=nowport++;
            mutex.unlock();
    
           emit sentnowport(nowport);
           QTcpSocket socket(0);
           socket.abort();
           socket.connectToHost(ip,tmpport);
           if(socket.waitForConnected(1000))
            {
    
               //qDebug()<<"connect";
               text.lock();
               QString message="";
               message+=QString::number(tmpport,10)+"  opened!";
               result->append(message);
               text.unlock();
               //qDebug()<<"connect over";
           }
    
           else
               ;//qDebug()<<tmpport<<"not open"<<endl;
    
        }
        stopped=false;
    }
    void Scanner::stop()
    {
        stopped=true;
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->pushButton_2->setVisible(false);
        threadisrunnig=false;
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::setBar(int value)
    {
        //qDebug()<<value;
        ui->progressBar->setValue(value);
    }
    
    bool MainWindow::checkip(QString ip)
    {
        QRegExp rx2("\d+\.\d+\.\d+\.\d+");
         if( !rx2.exactMatch(ip) )
         {
               return false;
         }
         //qDebug()<<"check true";
         return true;
    }
    void MainWindow::on_pushButton_clicked()
    {
        QString desip=ui->lineEdit->text();
        ui->progressBar->setValue(0);
        ui->pushButton_2->setText("暂停");
    
        //qDebug()<<desip;
        if(!checkip(desip))
        {
            ui->lineEdit->setText("ip 地址错误");
        }
        else
        {
            //ui->progressBar->setRange(0,0);
             ip=desip;
             staport=ui->spinBox->value();
             endport=ui->spinBox_2->value();
             nowport=staport;
             result=ui->textEdit;
             result->clear();
             //qDebug()<<staport<<endport<<nowport;
             int num=ui->spinBox_3->value();
    
             scanner=new Scanner[num];
             ui->progressBar->setRange(staport,endport);
    
            ui->pushButton_2->setVisible(true);
             for(int i=0;i<num;i++)
             {
                 scanner[i].start();
                 threadisrunnig=true;
                 connect(scanner+i,SIGNAL(sentnowport(int)),this,SLOT(setBar(int)));
             }
        }
    }
    
    void MainWindow::startscanner(QString ip, int startport, int endport)
    {
        if(startport>endport)
        {
            int tmp=startport;
            startport=endport;
            endport=tmp;
        }
    
         QTcpSocket socket(0);
        for(int i=startport;i<=endport;i++)
        {
            socket.abort();
            socket.connectToHost(ip,i);
            if(socket.waitForConnected(1000))
                 qDebug()<<i<<"connected!";
    
        }
    }
    
    
    void MainWindow::on_pushButton_2_clicked()
    {
        if(ui->pushButton_2->text()=="暂停")
        {
            bool couldPause=false;
            for(int i=0;i<ui->spinBox_3->value();i++)
                if(threadisrunnig&&scanner[i].isRunning()) couldPause=true;
            if(!couldPause) return;
            ui->pushButton_2->setText("继续");
            mutex.lock();
        }
        else
        {
            ui->pushButton_2->setText("暂停");
            mutex.unlock();
        }
    }
    
    void MainWindow::on_pushButton_3_clicked()
    {
        ui->progressBar->setValue(endport);
        ui->pushButton_2->setVisible(false);
        if(!threadisrunnig) return;
        for(int i=0;i<ui->spinBox_3->value();i++)
            scanner[i].stop();
        delete(scanner);
    }
    View Code

    解释一下:

    有三个互斥访问变量:当前任务端口nowport, 扫描结果 textEdit,进度条 progressBar。

    在访问这三个变量的时候要用信号量实现互斥访问。

    by nianhao@ouc,万一被查重了不负责。。

    更新一波,增加网段扫描

    首先是ip遍历函数:

    int ip2num(QString ip)
    {
        bool ok;
        int lp[4];
        QStringList iplist=ip.split('.');
        for (int i=0;i<iplist.length();i++)
            lp[i]=iplist[i].toInt(&ok,10);
        return lp[0] << 24 | lp[1] << 16 | lp[2] << 8 | lp[3];
    }
    
    QString num2ip(int num)//:# int num to ip
    {
        int ip[4];
        ip[3] = (num & 0xff);
        ip[2] = (num & 0xff00) >> 8;
        ip[1] = (num & 0xff0000) >> 16;
        ip[0] = (num & 0xff000000) >> 24;
        QString rip=QString("%1").arg(ip[0])+QString(".")+QString("%1").arg(ip[1])+QString(".")+QString("%1").arg(ip[2])+QString(".")+QString("%1").arg(ip[3]);
        return rip;
    }
    
    bool iprange(QString ip1,QString ip2)
    {
        int num1 = ip2num(ip1);
        int num2 = ip2num(ip2);
        sip=num1;
        eip=num2;
    
        int tmp = num2 - num1;
        if(tmp < 0)
            return false;
        else
            return true;
    }
    View Code

    通过位运算遍历ip地址。

    然后我们修改一下run函数,给线程分配任务时同时给定ip,这样实现ip的遍历void Scanner::run()

    {
        while(!stopped)
        {
            mutex.lock();
            QString tmpIp=nowIp;
    if(nowport>endport||nip>eip) { if(nip>eip) { mutex.unlock(); emit sentnowport(endport); break; } nip++; emit sentnowip(nip); nowIp=num2ip(nip); QString msg=QString("now the scanning ip is %1").arg(nowIp); if(nip<=eip) result->append(msg); nowport=staport; } int tmpport=nowport++; //发出更新进度条信号 emit sentnowport(nowport); mutex.unlock(); //尝试tcp连接 QTcpSocket socket(0); socket.abort(); socket.connectToHost(tmpIp,tmpport); if(socket.waitForConnected(1000)) { //qDebug()<<"connect"; text.lock(); QString message=""; message+=QString::number(tmpport,10)+" opened!"; result->append(message); text.unlock(); //qDebug()<<"connect over"; } else ;//qDebug()<<tmpport<<"not open"<<endl; } stopped=false; }

    最后修改一下界面文件,增加一个指示全局进度的进度条。

    最终效果:

    这样就完成了网络安全的实验了。

    整个项目的源代码:点击这里

    密码:w1lh

    大家好好复习欢迎给我发期末重点啊,赠人玫瑰~~~香的不行

  • 相关阅读:
    查看MAC系统JRE和JDK版本
    【转】频点CTO张成:基于Cocos2d的MMORPG开发经验
    Android上常见度量单位【xdpi、hdpi、mdpi、ldpi】解读
    常见android手机分辨率(xxhdpi,xhdpi)
    Android市场官方的统计信息
    【转】腾讯分析移动设备屏幕分辨率分析报告-(数据基于2012年12月至2013年1月上半月)
    error “base class has incomplete type”
    Eclipse 各种包说明
    怎么鉴别五帝钱真假
    【jzoj 6276】树(线段树)(扫描线)
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/6208708.html
Copyright © 2011-2022 走看看