基于Qt开发的网络诊断工具

导语:

项目名称:基于Qt开发的网络诊断工具
开发环境:VS2008
QT版本:4.7
数据读入:用户自行选中的.ini配置文件
功能实现:解析.ini文件,实时检测相关的域名连通性以及DNS解析的结果是否匹配.ini文件对应内容
模块设计:
				WorkThread  //工作线程类
				  Log //日志打印类
				  Mainwindow //主窗口类
				  Mainwindow2//弹窗类

项目源码:

  • WorkThread.hpp

//WorkThread.h
#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>
#include <QMap>
#include <QString>
#include <QTcpSocket>
#include<QHostInfo>
#include <windows.h>
#include <QProgressDialog>
#include <QDebug>
#include <QHostAddress>
#include <QtNetwork\qhostinfo.h>
#include <QTcpSocket>
#include <QMessageBox>
#include<QMutex>
#include <time.h>
#include <QAbstractSocket>
#include <QTimer>
#include<QProgressDialog>
#include "LOG.h"
//#include "Log.hpp"




class WorkerThread : public QThread{

	Q_OBJECT
signals:
	void windowShow(QString text);

private:
	QVector<QString>_v1;   //元素是每一段
	QVector<QString>_v2;  //元素是每一小段每一行内容
	QVector<QString>_domain; //存储每一段的域名部分
	QMap< QString,QVector<QString> >_m;
	QString _text;
	QProgressDialog* progress;
	int count;
	LOG* log;
	//QTimer *timer;
	QMutex mutex;

private slots:
		void lookedUp(const QHostInfo &host);  

public:
	bool Search(QString s1,QString s2);
	WorkerThread(QObject *parent=0);
	~WorkerThread();
    void RequsetNewthread(QVector<QString> v,QMap< QString,QVector<QString> >m);

protected:
	void run();

};


#endif // WORKTHREAD_H



//WorkThread.cpp

#include "workthread.h"


 WorkerThread::WorkerThread(QObject *parent)
	: QThread(parent)
	{

		_text+="\n******************************************************************\n\n";
		_text+="\n********************  NetWork Checking... ...  *******************\n\n";
		_text+="\n******************************************************************\n\n";

    	count=0;	
		log=new LOG();
}


 
 void WorkerThread::RequsetNewthread(QVector<QString> v, QMap< QString,QVector<QString> >m){

	 _v1=v;
	 _m=m;
	 start();


 }



void WorkerThread::run(){

	/* timer = new QTimer(this);
	timer->start(100);
	*/

	progress=new QProgressDialog("Parsing content", "Cancel", 0,100);
	progress->setWindowModality(Qt::WindowModal);
	progress->setMinimumDuration(5);  
	progress->setWindowTitle("Parsing now ..."); 
	progress->show();

	//为什么点击cancel之后不报警告
	if(progress->wasCanceled())                                  
	{
	
		QMessageBox::warning(NULL,"Warning","you have canceled this action.");
	    return;
	}


	for (int i = 0; i < 100; i++) {
    
		Sleep(100);
		progress->setValue(i);

	}
	progress->setValue(100);

	
	



while(1){//实时监控


	Sleep(1000);
    _domain.clear();
	count=0;

	QString log_=log->Log_record(" Paring result: ");
	_text+=log_;
	_text+="\n";
	
	
	//对每一个小段进行处理 
  for( int i=0;i<9;++i){   
		
	    QString arr(_v1[i]);
	    _v2.clear();
		

	//以\n为分隔符去提取,将每一段的没一行的内容作为一个vecor的元素   [account.wps.cn]\ndirectUseHttpDns=0\nip1=140.210.77.190\nip2=114.112.36.130\nip6=114.112.66.245 
      	size_t begin=0;
	 do 
	    {

		 size_t end=arr.indexOf("\n",begin);
		 if(end==-1) {
			//最后一次,应该把从begin下标开始全部都读进去
			QString replenish=arr.mid(begin);
			_v2.push_back(replenish);
			break;

		}
		 QString tmp_var=arr.mid(begin,end-begin);
	 	 _v2.push_back(tmp_var);
		 begin=end+1;                                   

	 } while(1);




	//判断v2[0]元素即指定域名的连通性
	QTcpSocket socket(0);
	socket.abort(); //取消原有连接
	socket.connectToHost(_v2[0],80); //建立一个TCP连接             第二个参数是服务器方面的端口号

	// socket->connectToHost("imap", 143);
	if(socket.waitForConnected(1000))                
	{
		_text+=(_v2[0]+" is regular... \n\n");
	}
	else{
		_text+=(_v2[0]+" is not regular... \n\n");	
	}

	
  _domain.push_back(_v2[0]);

}//end of for...


   emit windowShow(_text);


//把每一个域名都存储一下

 for(int j=0;j<9;++j){
   	QHostInfo::lookupHost(_domain[j], this, SLOT(lookedUp(QHostInfo)));          

  
}


}//end of while(1);

}



void WorkerThread::lookedUp(const QHostInfo &host)
{

	mutex.lock();
	++count;
	

	QString tag;
	_text+="\n";
	_text+=(host.hostName()+" analytical result is :   ");
	QList<QHostAddress> addrList = host.addresses();

	if (!addrList.isEmpty())
	{  	

		for  (int i = 0; i < addrList.size(); i++)
		{
			_text+=(addrList[i].toString());

			if(Search(addrList[i].toString(),host.hostName())) {      //Search():与host关联的域名在v2的元素项中一一比对判断是否存在

				tag="true";
				_text+=("  "+tag+"\n");
			

			}
			else{
				tag="false";
				_text+=(" "+tag+"\n");
				

			}

		}//end of for:对应解析出的相关的ip列表遍历的循环

	}
	
	//如果列表为空,打印LOG
	else{
		_text+="The analytical result is NULL...";
	}



if(count==9){
		_text += "\n\n\n\n\n\n";
		emit windowShow(_text);
	}


   mutex.unlock();

}

bool WorkerThread::Search(QString s1,QString s2){

	//在 成员变量 m  map<string,vector<string>>中去查找

	QVector<QString>vv=_m[s2];

	for(int i=0;i<vv.size();++i){

		QString edit=vv[i].mid(4);
		if( QString::compare(s1, edit) == 0){             //QString 的字符串相等的比对方法
			return true;
		}
	}
	return false;

}


WorkerThread::~WorkerThread(){

	delete progress;
	delete log;
	//delete timer;
}

//完善的话:   1.可以在弹窗之前增加一个解析的界面设计:进度条对话框     2.每一个大段前打印一次Log       3.窗口伴随下移


  • Log.hpp
//Log.h
#ifndef LOG_H
#define LOG_H

#include <QString>
#include <windows.h>

class LOG{


public:
	
	QString GetTimeStamp();
	QString  Log_record(QString message_);


};


#endif



//Log.cpp

#include "LOG.h"

QString LOG::GetTimeStamp(){


	QString str_year;
	QString str_month;
	QString str_day;
	QString str_hour;
	QString str_minute;
	QString str_second;
	QString str_msecond;
	QString str_dayofweek;
	QString time_;

	SYSTEMTIME sys;
	GetLocalTime( &sys );

	str_year = QString::number(sys.wYear);
	str_month = QString::number(sys.wMonth);
	str_day = QString::number(sys.wDay);
	str_hour = QString::number(sys.wHour);
	str_minute = QString::number(sys.wMinute);
	str_second = QString::number(sys.wSecond);
	str_msecond = QString::number(sys.wMilliseconds);
	str_dayofweek = QString::number(sys.wDayOfWeek);

	time_+=(str_year+"."+str_month+"."+str_day+"    "+" "+str_hour+"h"+ " : "+str_minute+"min"+" : "+str_second+"s "+" : "+str_msecond+"ms  "+"DayOfWeek: " +str_dayofweek );

	return time_;

}






QString LOG:: Log_record(QString message_)
{
	QString StringTime;
	QString tmp=GetTimeStamp();

	StringTime="["+tmp+"]"+message_;


	return StringTime;



}


  • test.hpp
//test.h
#ifndef TEST_H
#define TEST_H

#include <QMainWindow>
#include <QTextEdit>
#include <QAction>
#include <QMenuBar>
#include<windows.h>
#include <QWidget>
#include <QDialog>
#include <QMessageBox>
#include<QThread>
#include <QToolBar>
#include <QTime>
#include<fstream>
#include<QDebug>
#include<QPushButton>
#include <QValidator>
#include <QGridLayout>
#include <QFileDialog>
#include<QTextEdit>
#include<QString>
#include <QInputDialog>
#include <QList>
#include "workthread.h"




//弹窗类
class MainWindow2 : public QMainWindow{

	Q_OBJECT
public:
	MainWindow2(QWidget *parent = 0);
	~MainWindow2();
	//void Show_window(QString content);
	void mfunc_parse(QVector<QString>v,QMap< QString,QVector<QString> >m);

private:
	QAction *saveAction;	



public:
	QTextEdit* textEdit2;        //文本框指针
	WorkerThread thread_;        //线程类对象

private slots:		
		void save();
		void onWindowShow(QString text);

};








//主窗口类
class MainWindow : public QMainWindow{

	Q_OBJECT
public:
	//void mfunc_parse();
	//bool Search(QString s1,QString s2);

public:
	MainWindow(QWidget *parent = 0);
	~MainWindow();
	//void func_parse(QString s,QTextEdit* &textEdit2);
	
    void RequsetNew(QVector<QString> v, QMap<QString,QVector<QString>>m);


private slots:		
	void open();
	void save();
	void parse();		


protected:
	void funcParse();


private:
	QAction *saveAction;	
	QAction *openAction;
	QAction *parseAction;
	QTextEdit* textEdit;
	
	QString path; //保存打开文件的路径
	QString str;  //用来传递文本内容
	QVector<QString>v1;//元素是每一段
	QVector<QString>v2;  //元素是每一小段每一行内容
	MainWindow2 win2;
	QMap< QString,QVector<QString> >m;


	//static QString tmp;  //用来诊断信息的(+=)输出

};


#endif // MAINWINDOW_H





//test.cpp

#include"test.h"
MainWindow2::MainWindow2(QWidget *parent) :
QMainWindow(parent){

	setWindowTitle(tr(" opening new  Window..."));
	textEdit2 = new QTextEdit(this);
	setCentralWidget(textEdit2);

	saveAction = new QAction(QIcon(":/new_mini/doc-open2"), tr("&Save..."), this);
	connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
	//添加到菜单栏
	QMenu *file = menuBar()->addMenu(tr("&File"));
	file->addAction(saveAction);

	//添加到工具栏
	QToolBar *toolBar = addToolBar(tr("&File"));
	toolBar->addAction(saveAction);


	connect( &thread_, SIGNAL(windowShow(QString )),
		this, SLOT(onWindowShow(QString)) );
	


	statusBar();


}



void MainWindow2::save(){


	QString path = QFileDialog::getSaveFileName(this,
		tr("Open File"),
		".",
		tr("Text Files(*.txt)"));
	if(!path.isEmpty()) {
		QFile file(path);
		if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
			QMessageBox::warning(this, tr("Write File"),
				tr("Cannot open file:\n%1").arg(path));
			return;
		}
		QTextStream out(&file);
		out << textEdit2->toPlainText();
		file.close();
	} else {
		QMessageBox::warning(this, tr("Path"),
			tr("You did not select any file."));
	}


}

void  MainWindow2:: mfunc_parse(QVector<QString>v, QMap< QString,QVector<QString> >m){

	thread_.RequsetNewthread(v,m);


}



	//判断玩HOST连通性之后,再去解析拿到关联的ip地址列表,然后去比对
	///执行流在这块存在问题: 并没有按照预期执行到这块之后然后去拿到关系的IP列表进行判断

void MainWindow2::onWindowShow(QString text){

		textEdit2->setText(text);
		this->show();

}





MainWindow2::~MainWindow2(){

	delete textEdit2;

}




///
华丽分割//华丽分割
///




MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent){

	setWindowTitle(tr("Main Window"));
	textEdit = new QTextEdit(this);
	setCentralWidget(textEdit);
	//win2=new MainWindow2(this);
	

	//设置图标
	openAction = new QAction(QIcon(":/new_mini/doc-open1"), tr("&Open..."), this);
	parseAction = new QAction(QIcon(":/new_mini/doc-open3"), tr("&Parse..."), this);
	saveAction = new QAction(QIcon(":/new_mini/doc-open2"), tr("&Save..."), this);
	
	//设置快捷键
	openAction->setShortcuts(QKeySequence::Open);
	saveAction->setShortcuts(QKeySequence::Save);
	
	//设置提示信息
	openAction->setStatusTip(tr("Open an existing file"));
	saveAction->setStatusTip(tr("Save a file"));
	parseAction->setStatusTip(tr("Parse an existing file"));
	
	//设置信号槽
	connect(openAction, SIGNAL(triggered()), this, SLOT(open()));	
	connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));	
	connect(parseAction,  SIGNAL(triggered()), this, SLOT(parse()));

	
	//添加到菜单栏
	QMenu *file = menuBar()->addMenu(tr("&File"));
	file->addAction(openAction);
	file->addAction(saveAction);
	file->addAction(parseAction);
	
	//添加到工具栏
	QToolBar *toolBar = addToolBar(tr("&File"));
	toolBar->addAction(openAction);
	toolBar->addAction(saveAction);
	toolBar->addAction(parseAction);


	statusBar();


	

}



void MainWindow::funcParse(){


	//对content字符串S进行预处理,先提取第一段
	QString tmp_;//包含每一小段全部内容的string
	QVector<QString>vtmp;													


	//利用循环以'\n\n'为分隔符,把每一段的内容push进v1;	
	size_t start=0;
	size_t index=0;	
	for(int i=0;i<10-1;++i){

		vtmp.clear();
		size_t finish=str.indexOf("\n\n",start);      //遇到两个换行符的时候然后停止,读取一个段
		//if(finish==-1) 
		//	break;
		tmp_=str.mid(start,finish-start);
		v1.push_back(tmp_);
		start=finish+2;                                                   
		qDebug()<<tmp_;



		size_t end=tmp_.indexOf("\n",0);
		QString nowords=tmp_.mid(0,end);//tmp_的第一行
		size_t begin=0;															
		do 																		
		{																		
			//
			size_t end=tmp_.indexOf("\n",begin);								
			if(end==-1) {														
				//最后一次,应该把从begin下标开始全部都读进去					
				QString replenish=tmp_.mid(begin);								
				vtmp.push_back(replenish);										
				break;															
				//
			}																	
			QString tmp_var=tmp_.mid(begin,end-begin);							
			vtmp.push_back(tmp_var);											
			begin=end+1;    													
		}while(1);																


		m[nowords]=vtmp;


	} //  V1每一个大段的内容解析完毕


}



//openAction的槽函数
void MainWindow::open(){


	QString path = QFileDialog::getOpenFileName(this,
		tr("Open File"),
		".",
		tr("Text Files(*.txt)"));
	if(!path.isEmpty()) {
		QFile file(path);
		if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
			QMessageBox::warning(this, tr("Read File"),
				tr("Cannot open file:\n%1").arg(path));
			return;
		}
		QTextStream in(&file);
		str=in.readAll();
		textEdit->setText(str);
		file.close();
	} else {
		QMessageBox::warning(this, tr("Path"),
			tr("You did not select any file."));
	}
	

	//打开之后跟着调用一个函数去填充V1和m的内容

	funcParse();


}

	
//saveAction的槽函数
	void MainWindow::save(){


		QString path = QFileDialog::getSaveFileName(this,
			tr("Open File"),
			".",
			tr("Text Files(*.txt)"));
		if(!path.isEmpty()) {
			QFile file(path);
			if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
				QMessageBox::warning(this, tr("Write File"),
					tr("Cannot open file:\n%1").arg(path));
				return;
			}
			QTextStream out(&file);
			out << textEdit->toPlainText();
			file.close();
		} else {
			QMessageBox::warning(this, tr("Path"),
				tr("You did not select any file."));
		}


}

void MainWindow::RequsetNew(QVector<QString> v, QMap<QString,QVector<QString>>m){


       win2.mfunc_parse(v,m);


}




//parseAction的槽函数
void MainWindow::parse(){

	RequsetNew(v1,m);	
	
	//(win2.textEdit2)->setText("loading .... .... ....");
	//win2.show();
}


MainWindow::~MainWindow(){

}


  • main.cpp

#include "test.h"
#include <QtGui/QApplication>

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



项目处理结果:

1.用户点击“打开”菜单,手动选择.iniwen文件导入
2.后台工作线程拿到文件内容的相关参数准备进行后台解析
3.数据解析前会有一个进度条对话框ProcessDialog的显示
4.进度条显示完毕,新弹窗中实时while(1)的显示解析结果

碍于繁琐,执行图片不再赘述。如有问题询问欢迎评论区留言~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拥抱@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值