Qt實現端口掃描器

首先展現一下效果:安全

 

 

 

界面經過Qt設計師作出來的。網絡

主要有兩個類。app

首先主函數:socket

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

實現UI循環。tcp

第一個類,主窗體類:ide

#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設計師,因此函數名有點挫。函數

而後是掃描線程類,用來掃描端口:ui

#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

 

類實現:this

#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

 

解釋一下:spa

有三個互斥訪問變量:當前任務端口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

你們好好複習歡迎給我發期末重點啊,贈人玫瑰~~~香的不行

相關文章
相關標籤/搜索