基于ICMP(Ping)的多线程网络通道监视程序(QT)开辟
1、 ICMP原理简介
可参考 ICMP(Ping)功能原理及其C++实现简介 。
2、 网络通道监视程序开辟
设计原理: 通过PING 功能实现服务器、交换机、网闸等设备的网络检测,判定网络的否可达和TTL盘算 。
具备功能:
- 通过多线程,实现多个网络通道同时检测;
- 支持动态加包。
- 支持设置网络延长阈值,超过阈值时提示用户。
①、 界面设计
程序采用QT开辟,UI界面如下图所示:
中心区域为 QTableWidget 控件。
②、 PING接口封装
IPing.h :
- #pragma once
- class IPing
- {
- public:
- IPing();
- ~IPing();
- void SetPackSize(int isize);
- void PingHost(const char* ip, int& timems, int& ttl);
- private:
- int sock;
-
- unsigned int m_iTxID;
- unsigned int m_iTxSequeNum;
- unsigned int m_iSendPackageSize;
- };
- void InitWinSockEnv();
- void CleanupWinSockEnv();
复制代码 IPing.cxx:
- #include "IPing.h"
- #include <iostream>
- #include <string>
- #include <chrono>
- #include <thread>
- #include <iomanip>
- #include <winsock2.h>
- #pragma comment(lib,"ws2_32.lib")
- #define ICMP_PING_DATA_SIZE 40000 //填充数据长度;
- #define ICMP_TYPE_PING_REQUEST 8
- #define ICMP_TYPE_PING_REPLY 0
- #define ICMP_PING_TIMES 1 //Ping次数
- #define MAX_BUFFER_SIZE 40100
- typedef unsigned char uint8;
- typedef unsigned short uint16;
- typedef unsigned int uint32;
- //ICMP校验和计算
- uint16 MakeChecksum(char* icmp_packet, int size)
- {
- uint16 * sum = (uint16*)icmp_packet;
- uint32 checksum = 0;
- while (size > 1)
- {
- checksum += ntohs(*sum++);
- size -= sizeof(uint16);
- }
- if (size)
- {
- *sum = *((uint8*)sum);
- checksum += ((*sum << 8) & 0xFF00);
- }
- checksum = (checksum >> 16) + (checksum & 0xffff);
- checksum += checksum >> 16;
- return (uint16)(~checksum);
- }
- IPing::IPing()
- {
- sock = 0;
- m_iTxID = 0;
- m_iTxSequeNum = 0;
- m_iSendPackageSize = 32;
- SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- sock = s;
- }
- IPing::~IPing()
- {
- if (sock > 0)
- {
- closesocket(sock);
- }
- }
- void IPing::SetPackSize(int isize)
- {
- m_iSendPackageSize = isize;
- }
- void IPing::PingHost(const char* ip, int& timems, int& ttl)
- {
- std::string strHost = std::string(ip);
- if (strHost.length()< 5)
- {
- timems = -1;
- ttl = -1;
- return;
- }
- struct sockaddr_in pingaddr;
- memset((char *)&pingaddr, 0, sizeof(pingaddr));
- pingaddr.sin_family = AF_INET;
- pingaddr.sin_port = 0;
- pingaddr.sin_addr.s_addr = inet_addr(strHost.c_str());
- for (int ii = 0; ii < ICMP_PING_TIMES; ++ii)
- {
- //组帧
- uint8 ucCmdBuf[MAX_BUFFER_SIZE] = { 0 };
- uint8* pCurr = ucCmdBuf;
- *pCurr++ = ICMP_TYPE_PING_REQUEST; //Type
- *pCurr++ = 0x00; //Code
- *pCurr++ = 0x00; //Checksum
- *pCurr++ = 0x00; //Checksum
- *pCurr++ = HIBYTE(m_iTxID); //Identifier
- *pCurr++ = LOBYTE(m_iTxID); //Identifier
- *pCurr++ = HIBYTE(m_iTxSequeNum); //Sequence Number
- *pCurr++ = LOBYTE(m_iTxSequeNum); //Sequence Number
- auto send_clock = std::chrono::system_clock::now();
- DWORD dwSendTime = std::chrono::duration_cast<std::chrono::milliseconds>(send_clock.time_since_epoch()).count();;
- *pCurr++ = HIBYTE(HIWORD(dwSendTime)); //Current TickCount
- *pCurr++ = LOBYTE(HIWORD(dwSendTime)); //Current TickCount
- *pCurr++ = HIBYTE(LOWORD(dwSendTime)); //Current TickCount
- *pCurr++ = LOBYTE(LOWORD(dwSendTime)); //Current TickCount
- //Data
- for (int k = 0; k < m_iSendPackageSize - 4; ++k)
- {
- *pCurr++ = 0x61 + (k % 20);
- }
- uint16 usCheckSum = MakeChecksum((char*)ucCmdBuf, pCurr - ucCmdBuf);
- ucCmdBuf[2] = HIBYTE(usCheckSum);
- ucCmdBuf[3] = LOBYTE(usCheckSum);
- int txlen = sendto(sock, (char *)&ucCmdBuf, pCurr - ucCmdBuf, 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
- uint8 ucRxBuf[MAX_BUFFER_SIZE] = { 0 };
- struct sockaddr_in rxaddr;
- memset((char *)&rxaddr, 0, sizeof(rxaddr));
- rxaddr.sin_family = AF_INET;
- rxaddr.sin_port = 0;
- rxaddr.sin_addr.s_addr = inet_addr(strHost.c_str());
- int iSize = sizeof(struct sockaddr_in);
- do
- {
- int rxlen = recvfrom(sock, (char *)&ucRxBuf, sizeof(ucRxBuf), 0, (struct sockaddr *)&rxaddr, &iSize);
- if (rxaddr.sin_addr.S_un.S_addr == pingaddr.sin_addr.S_un.S_addr)
- {
- if (rxlen >= 0)
- {
- //IP帧获取TTL
- ttl = ucRxBuf[8];
- //跳过IP Header 20个字节
- uint8* pIcmpFrame = ucRxBuf + 20;
- //Type和Code
- uint8 ucType = pIcmpFrame[0];
- uint8 ucCode = pIcmpFrame[1];
- if (ucCode != 0x00 || ucType != 0x00)
- goto GO_ON;
- //比对ID和序号
- uint16 iRxID = pIcmpFrame[4] * 256 + pIcmpFrame[5];
- uint16 iRxSequeNum = pIcmpFrame[6] * 256 + pIcmpFrame[7];
- if (iRxID == m_iTxID && iRxSequeNum == m_iTxSequeNum)
- {
- DWORD dwTimeTransmit = pIcmpFrame[8] * 256 * 256 * 256 + pIcmpFrame[9] * 256 * 256 + pIcmpFrame[10] * 256 + pIcmpFrame[11];
- auto now = std::chrono::system_clock::now();
- DWORD dwNowTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
- timems = dwNowTime - dwTimeTransmit;
- }
- else
- goto GO_ON;
- }
- else
- {
- timems = -1; //异常
- }
- m_iTxID++;
- m_iTxSequeNum++;
- break;
- }
- GO_ON:
- auto current_clock = std::chrono::system_clock::now();
- DWORD dwCurrentTime = std::chrono::duration_cast<std::chrono::milliseconds>(current_clock.time_since_epoch()).count();;
- if (dwCurrentTime - dwSendTime > 2000)
- {
- timems = -2; //超时
- return;
- }
- }
- while (true);
- }
- }
- void InitWinSockEnv()
- {
- WSADATA wsaData;
- WSAStartup(MAKEWORD(2, 2), &wsaData);
- }
- void CleanupWinSockEnv()
- {
- WSACleanup();
- }
复制代码 ③、 PING多线程接口封装
多线程采用 std::thread 实现,线程函数封装如下:
- /************************************************************************/
- /* */
- /* @WrapExecPing函数功能: 线程函数,调用PING接口 */
- /* */
- /* @aipaddr, bipaddr参数: 监视的节点IPA和IPB地址 */
- /* @atimems, btimems参数: IPA地址和IPB地址PING响应时间 */
- /* @attl, bttl参数: IPA地址和IPB地址PING响应TTL值 */
- /* @stopf 参数: 停止线程任务标志位 */
- /* @package_size 参数: PING包大小 */
- /* @asnd, bsnd参数: IPA地址和IPB地址PING次数 */
- /* @f 参数: 线程结束标志位 */
- /* */
- /************************************************************************/
- void WrapExecPing(std::string aipaddr, std::string bipaddr, int& atimems, int& attl, int& btimems, int& bttl, bool& stopf,int package_size,int& asnd,int&bsnd, bool& f)
- {
- IPing aping;
- IPing bping;
- //设置PING包大小
- aping.SetPackSize(package_size);
- bping.SetPackSize(package_size);
- f = true;
- while (!stopf)
- {
- auto start = std::chrono::system_clock::now();
- DWORD dwStartTime = std::chrono::duration_cast<std::chrono::milliseconds>(start.time_since_epoch()).count();
- if (aipaddr.length() > 5)
- {
- //执行IP地址A的PING
- aping.PingHost(aipaddr.c_str(), atimems, attl);
- asnd++;
- }
- else
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
-
- if (bipaddr.length() > 5)
- {
- //执行IP地址B的PING
- bping.PingHost(bipaddr.c_str(), btimems, bttl);
- bsnd++;
- }
- else
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- auto now = std::chrono::system_clock::now();
- DWORD dwNowTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
- if (dwNowTime - dwStartTime < 500)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(800));
- }
- }
- f = false;
- }
复制代码 ④、 QT主程序开辟
【1】、 界面初始化
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- //初始化Windows套接字环境
- InitWinSock();
- glb_bStopF = false;
-
- //初始化表格控件;
- initTableWidget();
- //初始化PING包大小复选框;
- initComboBox();
- //初始化延迟超限报警阈值;
- initLineEdit();
-
- ui->pushButtonStop->setEnabled(false);
- //设置控件样式表QSS
- setStyleSheet("QMainWindow{ background-color: #365a7a; } QLabel{ color:#E0E0E0; font-weight:bold; }");
-
- ui->pushButtonStart->setStyleSheet("QPushButton{ background-color: transparent;color: #f0f0f0; font-weight:bold;} QPushButton:hover{ background-color:white; color:gray; font-weight:thin; border-radius:4px;} QPushButton:disabled{ color:gray;}");
- ui->pushButtonStop->setStyleSheet("QPushButton{ background-color: transparent;color: #f0f0f0; font-weight:bold;} QPushButton:hover{ background-color:white; color:gray; font-weight:thin; border-radius:4px;} QPushButton:disabled{ color:gray;}");
- ui->lineEdit->setStyleSheet("QLineEdit{background-color:#D9D9D9; color:gray;}");
- ui->comboBox->setStyleSheet("QComboBox{color:gray;}");
- //信号槽定义;
- connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(onButtonStart()));
- connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(onButtonStop()));
- }
复制代码 表格控件初始化
- void MainWindow::initTableWidget()
- {
- //加载nodecfg.ini文件
- extern bool LoadNodeConfig(CHostInfoArray& arry);
- if (false == LoadNodeConfig(arry) || arry.size() <= 0)
- {
- QMessageBox::warning(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("《nodecfg.ini》打开失败!"));
- return;
- }
- //初始化表格列
- ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableWidget->setColumnCount(MAX_COLUMN_NUM);
- QStringList headerList;
- headerList << QString::fromLocal8Bit("网络节点名称");
- headerList << QString::fromLocal8Bit("A网IP地址");
- headerList << QString::fromLocal8Bit("B网IP地址");
- headerList << QString::fromLocal8Bit("A网延时");
- headerList << QString::fromLocal8Bit("A网TTL");
- headerList << QString::fromLocal8Bit("B网延时");
- headerList << QString::fromLocal8Bit("B网TTL");
- headerList << QString::fromLocal8Bit("PING次数");
- ui->tableWidget->setHorizontalHeaderLabels(headerList);
- ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}");
- ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}");
- ui->tableWidget->setColumnWidth(0, 120);
- ui->tableWidget->setColumnWidth(1, 140);
- ui->tableWidget->setColumnWidth(2, 140);
- ui->tableWidget->setColumnWidth(7, 160);
- //行
- int iSize = arry.size();
- if (iSize > 0)
- {
- ui->tableWidget->setRowCount(iSize);
- for (int ii = 0; ii < iSize;++ii)
- {
- ui->tableWidget->setItem(ii, 0, new QTableWidgetItem()); ui->tableWidget->item(ii, 0)->setText(QString::fromStdString(arry[ii].strHostName)); ui->tableWidget->item(ii, 0)->setData(Qt::DisplayRole, QString::fromStdString(arry[ii].strHostName));
- ui->tableWidget->setItem(ii, 1, new QTableWidgetItem()); ui->tableWidget->item(ii, 1)->setText(QString::fromStdString(arry[ii].strIPA));
- ui->tableWidget->setItem(ii, 2, new QTableWidgetItem()); ui->tableWidget->item(ii, 2)->setText(QString::fromStdString(arry[ii].strIPB));
- ui->tableWidget->setItem(ii, 3, new QTableWidgetItem());
- ui->tableWidget->setItem(ii, 4, new QTableWidgetItem());
- ui->tableWidget->setItem(ii, 5, new QTableWidgetItem());
- ui->tableWidget->setItem(ii, 6, new QTableWidgetItem());
- ui->tableWidget->setItem(ii, 7, new QTableWidgetItem());
- }
- }
- }
复制代码 复选框控件初始化
- void MainWindow::initComboBox()
- {
- ui->comboBox->addItem("32", 32);
- ui->comboBox->addItem("128", 128);
- ui->comboBox->addItem("256", 256);
- ui->comboBox->addItem("512",512);
- ui->comboBox->addItem("1024", 1024);
- ui->comboBox->addItem("2048", 2048);
- ui->comboBox->addItem("2500", 2500);
- ui->comboBox->addItem("3000", 3000);
- ui->comboBox->addItem("4096", 4096);
- ui->comboBox->addItem("5000", 5000);
- ui->comboBox->addItem("8000", 8000);
- ui->comboBox->addItem("10000", 10000);
- ui->comboBox->addItem("13000", 13000);
- ui->comboBox->addItem("15000", 15000);
- ui->comboBox->addItem("18000", 18000);
- ui->comboBox->addItem("24000", 24000);
- ui->comboBox->addItem("28000", 28000);
- ui->comboBox->addItem("32000", 32000);
- ui->comboBox->addItem("36000", 36000);
- ui->comboBox->setCurrentIndex(0);
- }
复制代码 编辑框控件初始化
- void MainWindow::initLineEdit()
- {
- ui->lineEdit->setText("200");
- }
复制代码 【2】、 启动多线程
使用 std::thread线程,
- void MainWindow::StartPingTask()
- {
- int iSize = arry.size();
- if (iSize <= 0)
- {
- onButtonStop();
- return;
- }
- //报警阈值
- int alarmval = ui->lineEdit->text().toInt();
- //Ping包大小;
- int index = ui->comboBox->currentIndex();
- int package_size = ui->comboBox->itemData(index).toInt();
- SPINGINFO* pPingInfo = new SPINGINFO[iSize];
- for (int i = 0; i < iSize; i++)
- {
- pPingInfo[i].host = arry[i];
- pPingInfo[i].attl = -1;
- pPingInfo[i].bttl = -1;
- pPingInfo[i].atimems = -1;
- pPingInfo[i].btimems = -1;
- pPingInfo[i].asnd = 0;
- pPingInfo[i].bsnd = 0;
- std::thread T1(WrapExecPing, pPingInfo[i].host.strIPA, pPingInfo[i].host.strIPB, std::ref(pPingInfo[i].atimems), std::ref(pPingInfo[i].attl), std::ref(pPingInfo[i].btimems), std::ref(pPingInfo[i].bttl), std::ref(glb_bStopF), package_size, std::ref(pPingInfo[i].asnd), std::ref(pPingInfo[i].bsnd), std::ref(pPingInfo[i].runf));
- pPingInfo[i].t = std::move(T1);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- }
复制代码 【3】、 完整代码
- #include "mainwindow.h"#include "ui_mainwindow.h"#include "QMessageBox"#include "public.h"#include "IPing.h"#include <thread>#include <chrono>#define MAX_COLUMN_NUM 8CHostInfoArray arry;bool glb_bStopF = false;MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- //初始化Windows套接字环境
- InitWinSock();
- glb_bStopF = false;
-
- //初始化表格控件;
- initTableWidget();
- //初始化PING包大小复选框;
- initComboBox();
- //初始化延迟超限报警阈值;
- initLineEdit();
-
- ui->pushButtonStop->setEnabled(false);
- //设置控件样式表QSS
- setStyleSheet("QMainWindow{ background-color: #365a7a; } QLabel{ color:#E0E0E0; font-weight:bold; }");
-
- ui->pushButtonStart->setStyleSheet("QPushButton{ background-color: transparent;color: #f0f0f0; font-weight:bold;} QPushButton:hover{ background-color:white; color:gray; font-weight:thin; border-radius:4px;} QPushButton:disabled{ color:gray;}");
- ui->pushButtonStop->setStyleSheet("QPushButton{ background-color: transparent;color: #f0f0f0; font-weight:bold;} QPushButton:hover{ background-color:white; color:gray; font-weight:thin; border-radius:4px;} QPushButton:disabled{ color:gray;}");
- ui->lineEdit->setStyleSheet("QLineEdit{background-color:#D9D9D9; color:gray;}");
- ui->comboBox->setStyleSheet("QComboBox{color:gray;}");
- //信号槽定义;
- connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(onButtonStart()));
- connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(onButtonStop()));
- }
- MainWindow::~MainWindow(){ CleanWinSock(); delete ui;}void MainWindow::InitWinSock(){ //初始化Windows套接字环境 InitWinSockEnv();}void MainWindow::CleanWinSock(){ CleanupWinSockEnv();}void MainWindow::initTableWidget(){ //加载网络节点设置文件nodecfg.ini extern bool LoadNodeConfig(CHostInfoArray& arry); if (false == LoadNodeConfig(arry) || arry.size() <= 0) { QMessageBox::warning(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("《nodecfg.ini》打开失败!")); return; } //初始化表格列 ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableWidget->setColumnCount(MAX_COLUMN_NUM); QStringList headerList; headerList << QString::fromLocal8Bit("网络节点名称"); headerList << QString::fromLocal8Bit("A网IP地址"); headerList << QString::fromLocal8Bit("B网IP地址"); headerList << QString::fromLocal8Bit("A网延时"); headerList << QString::fromLocal8Bit("A网TTL"); headerList << QString::fromLocal8Bit("B网延时"); headerList << QString::fromLocal8Bit("B网TTL"); headerList << QString::fromLocal8Bit("PING次数"); ui->tableWidget->setHorizontalHeaderLabels(headerList); ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}"); ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}"); ui->tableWidget->setColumnWidth(0, 120); ui->tableWidget->setColumnWidth(1, 140); ui->tableWidget->setColumnWidth(2, 140); ui->tableWidget->setColumnWidth(7, 160); //行,插入记录 int iSize = arry.size(); if (iSize > 0) { ui->tableWidget->setRowCount(iSize); for (int ii = 0; ii < iSize;++ii) { ui->tableWidget->setItem(ii, 0, new QTableWidgetItem()); ui->tableWidget->item(ii, 0)->setText(QString::fromStdString(arry[ii].strHostName)); ui->tableWidget->item(ii, 0)->setData(Qt::DisplayRole, QString::fromStdString(arry[ii].strHostName)); ui->tableWidget->setItem(ii, 1, new QTableWidgetItem()); ui->tableWidget->item(ii, 1)->setText(QString::fromStdString(arry[ii].strIPA)); ui->tableWidget->setItem(ii, 2, new QTableWidgetItem()); ui->tableWidget->item(ii, 2)->setText(QString::fromStdString(arry[ii].strIPB)); ui->tableWidget->setItem(ii, 3, new QTableWidgetItem()); ui->tableWidget->setItem(ii, 4, new QTableWidgetItem()); ui->tableWidget->setItem(ii, 5, new QTableWidgetItem()); ui->tableWidget->setItem(ii, 6, new QTableWidgetItem()); ui->tableWidget->setItem(ii, 7, new QTableWidgetItem()); } } }void MainWindow::initComboBox(){ //PING包大小选项 ui->comboBox->addItem("32", 32); ui->comboBox->addItem("128", 128); ui->comboBox->addItem("256", 256); ui->comboBox->addItem("512",512); ui->comboBox->addItem("1024", 1024); ui->comboBox->addItem("2048", 2048); ui->comboBox->addItem("2500", 2500); ui->comboBox->addItem("3000", 3000); ui->comboBox->addItem("4096", 4096); ui->comboBox->addItem("5000", 5000); ui->comboBox->addItem("8000", 8000); ui->comboBox->addItem("10000", 10000); ui->comboBox->addItem("13000", 13000); ui->comboBox->addItem("15000", 15000); ui->comboBox->addItem("18000", 18000); ui->comboBox->addItem("24000", 24000); ui->comboBox->addItem("28000", 28000); ui->comboBox->addItem("32000", 32000); ui->comboBox->addItem("36000", 36000); ui->comboBox->setCurrentIndex(0);}void MainWindow::initLineEdit(){ //报警阈值,单元毫秒 ui->lineEdit->setText("200");}//开始检测void MainWindow::onButtonStart(){ ui->comboBox->setEnabled(false); ui->lineEdit->setEnabled(false); ui->pushButtonStart->setEnabled(false); ui->pushButtonStop->setEnabled(true); glb_bStopF = false; ClearTableWidget(); StartPingTask();}void MainWindow::onButtonStop(){ glb_bStopF = true;}/************************************************************************//* *//* @WrapExecPing函数功能: 线程函数,调用PING接口 *//* *//* @aipaddr, bipaddr参数: 监视的节点IPA和IPB地址 *//* @atimems, btimems参数: IPA地址和IPB地址PING响应时间 *//* @attl, bttl参数: IPA地址和IPB地址PING响应TTL值 *//* @stopf 参数: 停止线程任务标志位 *//* @package_size 参数: PING包大小 *//* @asnd, bsnd参数: IPA地址和IPB地址PING次数 *//* @f 参数: 线程结束标志位 *//* *//************************************************************************/void WrapExecPing(std::string aipaddr, std::string bipaddr, int& atimems, int& attl, int& btimems, int& bttl, bool& stopf,int package_size,int& asnd,int&bsnd, bool& f){ IPing aping; IPing bping; aping.SetPackSize(package_size); bping.SetPackSize(package_size); f = true; while (!stopf) { auto start = std::chrono::system_clock::now(); DWORD dwStartTime = std::chrono::duration_cast<std::chrono::milliseconds>(start.time_since_epoch()).count(); if (aipaddr.length() > 5) { aping.PingHost(aipaddr.c_str(), atimems, attl); asnd++; } else std::this_thread::sleep_for(std::chrono::milliseconds(500)); if (bipaddr.length() > 5) { bping.PingHost(bipaddr.c_str(), btimems, bttl); bsnd++; } else std::this_thread::sleep_for(std::chrono::milliseconds(500)); auto now = std::chrono::system_clock::now(); DWORD dwNowTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); if (dwNowTime - dwStartTime < 500) { std::this_thread::sleep_for(std::chrono::milliseconds(800)); } } f = false;}void MainWindow::ClearTableWidget(){ int iRowCount = ui->tableWidget->rowCount(); for (int k = 0; k < iRowCount; ++k) { for (int i = 3; i < MAX_COLUMN_NUM;++i) { ui->tableWidget->item(k, i)->setText(QString("")); } }}void MainWindow::StartPingTask(){ int iSize = arry.size(); if (iSize <= 0) { onButtonStop(); return; } //报警阈值 int alarmval = ui->lineEdit->text().toInt(); //Ping包大小; int index = ui->comboBox->currentIndex(); int package_size = ui->comboBox->itemData(index).toInt(); SPINGINFO* pPingInfo = new SPINGINFO[iSize]; for (int i = 0; i < iSize; i++) { pPingInfo[i].host = arry[i]; pPingInfo[i].attl = -1; pPingInfo[i].bttl = -1; pPingInfo[i].atimems = -1; pPingInfo[i].btimems = -1; pPingInfo[i].asnd = 0; pPingInfo[i].bsnd = 0; //启动线程 std::thread T1(WrapExecPing, pPingInfo[i].host.strIPA, pPingInfo[i].host.strIPB, std::ref(pPingInfo[i].atimems), std::ref(pPingInfo[i].attl), std::ref(pPingInfo[i].btimems), std::ref(pPingInfo[i].bttl), std::ref(glb_bStopF), package_size, std::ref(pPingInfo[i].asnd), std::ref(pPingInfo[i].bsnd), std::ref(pPingInfo[i].runf)); pPingInfo[i].t = std::move(T1); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } //界面更新 do { if (glb_bStopF) break; int iRowCount = ui->tableWidget->rowCount(); for (int k = 0; k < iRowCount;++k) { QString strHostName = ui->tableWidget->item(k, 0)->data(Qt::DisplayRole).toString(); for (int n = 0; n < iSize;++n) { if (strHostName.toStdString() == pPingInfo[n].host.strHostName) { if (pPingInfo[n].atimems == -1) ui->tableWidget->item(k, 3)->setText(QString("---")); else if (pPingInfo[n].atimems == -2) ui->tableWidget->item(k, 3)->setText(QString::fromLocal8Bit("超时")); else { ui->tableWidget->item(k, 3)->setText(QString("%1ms").arg(pPingInfo[n].atimems)); if (pPingInfo[n].atimems > alarmval) ui->tableWidget->item(k, 3)->setBackgroundColor(QColor(255, 0, 0)); //超限,红色提示 else ui->tableWidget->item(k, 3)->setBackgroundColor(QColor(255, 255, 255)); } if (pPingInfo[n].attl < 0) ui->tableWidget->item(k, 4)->setText(QString("---")); else ui->tableWidget->item(k, 4)->setText(QString("%1").arg(pPingInfo[n].attl)); if (pPingInfo[n].btimems == -1) ui->tableWidget->item(k, 5)->setText(QString("---")); else if (pPingInfo[n].btimems == -2) ui->tableWidget->item(k, 5)->setText(QString::fromLocal8Bit("超时")); else { ui->tableWidget->item(k, 5)->setText(QString("%1ms").arg(pPingInfo[n].btimems)); if (pPingInfo[n].btimems > alarmval) ui->tableWidget->item(k, 5)->setBackgroundColor(QColor(255, 0, 0)); //超限,红色提示 else ui->tableWidget->item(k, 5)->setBackgroundColor(QColor(255, 255, 255)); } if (pPingInfo[n].bttl < 0) ui->tableWidget->item(k, 6)->setText(QString("---")); else ui->tableWidget->item(k, 6)->setText(QString("%1").arg(pPingInfo[n].bttl)); QString strSndFrame = QString::fromLocal8Bit("A网:%1 | B网:%2").arg(pPingInfo[n].asnd, 3, 10, QLatin1Char('0')).arg(pPingInfo[n].bsnd, 3, 10, QLatin1Char('0')); ui->tableWidget->item(k, 7)->setText(strSndFrame); break; } } } } while (true); ui->pushButtonStop->setEnabled(false); bool bRunningF = false; do { bRunningF = false; for (int ii = 0; ii < iSize; ++ii) { if (pPingInfo[ii].runf == true) { ui->pushButtonStop->setText(QString::fromLocal8Bit("停止中...")); bRunningF = true; break; } } } while (bRunningF); for (int ii = 0; ii < iSize;++ii) { pPingInfo[ii].t.detach(); } delete []pPingInfo; ui->pushButtonStop->setText(QString::fromLocal8Bit("停止检测")); ui->pushButtonStart->setEnabled(true); ui->pushButtonStop->setEnabled(false); ui->comboBox->setEnabled(true); ui->lineEdit->setEnabled(true);}
复制代码 3、 运行结果
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |