在实现类似于Free IP Scanner 2.1的Ip扫描器软件中,会用到ping命令。如果使用Qt编程实现,主要会用QThread、QProcess这两个类。关于这两个类的具体用法可以查阅Qt助手或者QT官网。
在QT中为了扫描大量的Ip,通常需要将扫描Ip的任务放在一个单独的线程来完成,这样需要子类化QThread,重写其run()方法。从QThread类派生出一个ShellProcess的子类,该类的头文件代码如下:
#ifndef SHELLPROCESS_H #define SHELLPROCESS_H #include <QThread> #include <QtCore/QStringList> // Ping IP的线程子类 class ShellProcess : public QThread { Q_OBJECT public: explicit ShellProcess(QObject *parent = 0); QStringList getIpRangle(); //获取需要扫描的IP列表 void setIpRange(QStringList ipRange); //设置需要扫描的IP列表 protected: void run(); signals: void commandSuccessed(QString ip); void commandFailed(QString ip); public slots: private: QStringList ipRange; //需要扫描的IP列表 }; #endif // SHELLPROCESS_H
ShellProcess类的实现代码如下:
#include "shellprocess.h" #include <QtCore/QtDebug> #include <QtCore/QProcess> ShellProcess::ShellProcess(QObject *parent) : QThread(parent) { } QStringList ShellProcess::getIpRangle() { return this->ipRange; } void ShellProcess::setIpRange(QStringList ipRange) { this->ipRange = ipRange; } void ShellProcess::run() { QString ip; //依次扫描Ip列表中的各个IP foreach( ip, ipRange ) { int exitCode; //对每个Ip执行ping命令检测其是否在线 qDebug() << "ping " + ip << endl; #ifdef Q_OS_WIN QString strArg = "ping " + ip + " -n 1 -i 2"; exitCode = QProcess::execute(strArg); #else //其他平台(Linux或Mac) exitCode = QProcess::execute("ping", QStringList() << "-c 1" << "-t 2" << ip)); #endif if(0 == exitCode) { //it‘s alive qDebug() << "shell ping " + ip + " sucessed!"; //发射该IP在线的信号 emit commandSuccessed(ip); } else { qDebug() << "shell ping " + ip + " failed!"; //发射IP离线的信号 emit commandFailed(ip); } } }
在实际编程中可以这样使用ShellProcess类:
#define THREAD_SIZE 10 //线程数 ShellProcess *shellProcess; for(int i=0;i<THREAD_SIZE;i++){ shellProcess= new ShellProcess(this); connect(shellProcess, SIGNAL(commandSuccessed(QString)), this, SLOT(slot_onCommandSuccessed(QString))); connect(shellProcess, SIGNAL(commandFailed(QString)), this, SLOT(slot_onCommandFailed(QString))); connect(shellProcess, SIGNAL(finished()), shellProcess, SLOT(deleteLater())); //设置每个线程的Ip扫描范围,一共10个线程 shellProcess->setIpRange(ip_in_thread[i]); //启动线程 shellProcess->start(); }
具体的项目代码可以参看我github上使用Qt5.2的一个Ip扫描器:ip_scan,目前只完成了一部分功能。
另外,需要注意的是ping命令在Windows下和Linux(Mac)下的命令有所不同,可以参考Linux和Windows下ping命令详解1和Linux和Windows下ping命令详解2