基于ICMP(Ping)的多线程网络通道监视程序(QT)开辟

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

基于ICMP(Ping)的多线程网络通道监视程序(QT)开辟
1、 ICMP原理简介

可参考 ICMP(Ping)功能原理及其C++实现简介 。
2、 网络通道监视程序开辟

设计原理: 通过PING 功能实现服务器、交换机、网闸等设备的网络检测,判定网络的否可达和TTL盘算 。
具备功能:


  • 通过多线程,实现多个网络通道同时检测;
  • 支持动态加包。
  • 支持设置网络延长阈值,超过阈值时提示用户。
①、 界面设计

程序采用QT开辟,UI界面如下图所示:

中心区域为 QTableWidget 控件。
②、 PING接口封装

IPing.h :
  1. #pragma once
  2. class IPing
  3. {
  4. public:
  5.         IPing();
  6.         ~IPing();
  7.         void SetPackSize(int isize);
  8.         void PingHost(const char* ip, int& timems, int& ttl);
  9. private:
  10.         int sock;
  11.        
  12.         unsigned int m_iTxID;
  13.         unsigned int m_iTxSequeNum;
  14.         unsigned int m_iSendPackageSize;
  15. };
  16. void InitWinSockEnv();
  17. void CleanupWinSockEnv();
复制代码
IPing.cxx:
  1. #include "IPing.h"
  2. #include <iostream>
  3. #include <string>
  4. #include <chrono>
  5. #include <thread>
  6. #include <iomanip>
  7. #include <winsock2.h>
  8. #pragma comment(lib,"ws2_32.lib")
  9. #define ICMP_PING_DATA_SIZE           40000     //填充数据长度;
  10. #define ICMP_TYPE_PING_REQUEST        8
  11. #define ICMP_TYPE_PING_REPLY          0
  12. #define ICMP_PING_TIMES               1         //Ping次数
  13. #define MAX_BUFFER_SIZE               40100
  14. typedef unsigned char        uint8;
  15. typedef unsigned short                 uint16;
  16. typedef unsigned int         uint32;
  17. //ICMP校验和计算
  18. uint16 MakeChecksum(char* icmp_packet, int size)
  19. {
  20.         uint16 * sum = (uint16*)icmp_packet;
  21.         uint32 checksum = 0;
  22.         while (size > 1)
  23.         {
  24.                 checksum += ntohs(*sum++);
  25.                 size -= sizeof(uint16);
  26.         }
  27.         if (size)
  28.         {
  29.                 *sum = *((uint8*)sum);
  30.                 checksum += ((*sum << 8) & 0xFF00);
  31.         }
  32.         checksum = (checksum >> 16) + (checksum & 0xffff);
  33.         checksum += checksum >> 16;
  34.         return (uint16)(~checksum);
  35. }
  36. IPing::IPing()
  37. {
  38.         sock = 0;
  39.         m_iTxID = 0;
  40.         m_iTxSequeNum = 0;
  41.         m_iSendPackageSize = 32;
  42.         SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
  43.         sock = s;
  44. }
  45. IPing::~IPing()
  46. {
  47.         if (sock > 0)
  48.         {
  49.                 closesocket(sock);
  50.         }
  51. }
  52. void IPing::SetPackSize(int isize)
  53. {
  54.         m_iSendPackageSize = isize;
  55. }
  56. void IPing::PingHost(const char* ip, int& timems, int& ttl)
  57. {
  58.         std::string strHost = std::string(ip);
  59.     if (strHost.length()< 5)
  60.     {
  61.                 timems = -1;
  62.                 ttl = -1;
  63.                 return;
  64.     }
  65.         struct sockaddr_in pingaddr;
  66.         memset((char *)&pingaddr, 0, sizeof(pingaddr));
  67.         pingaddr.sin_family = AF_INET;
  68.         pingaddr.sin_port = 0;
  69.         pingaddr.sin_addr.s_addr = inet_addr(strHost.c_str());
  70.         for (int ii = 0; ii < ICMP_PING_TIMES; ++ii)
  71.         {
  72.                 //组帧
  73.                 uint8 ucCmdBuf[MAX_BUFFER_SIZE] = { 0 };
  74.                 uint8* pCurr = ucCmdBuf;
  75.                 *pCurr++ = ICMP_TYPE_PING_REQUEST;                 //Type
  76.                 *pCurr++ = 0x00;                                                 //Code
  77.                 *pCurr++ = 0x00;                                                 //Checksum
  78.                 *pCurr++ = 0x00;                                                 //Checksum
  79.                 *pCurr++ = HIBYTE(m_iTxID);                                 //Identifier
  80.                 *pCurr++ = LOBYTE(m_iTxID);                                 //Identifier
  81.                 *pCurr++ = HIBYTE(m_iTxSequeNum);        //Sequence Number
  82.                 *pCurr++ = LOBYTE(m_iTxSequeNum);             //Sequence Number
  83.                 auto send_clock = std::chrono::system_clock::now();
  84.                 DWORD dwSendTime = std::chrono::duration_cast<std::chrono::milliseconds>(send_clock.time_since_epoch()).count();;
  85.                 *pCurr++ = HIBYTE(HIWORD(dwSendTime));   //Current TickCount
  86.                 *pCurr++ = LOBYTE(HIWORD(dwSendTime));   //Current TickCount
  87.                 *pCurr++ = HIBYTE(LOWORD(dwSendTime));   //Current TickCount
  88.                 *pCurr++ = LOBYTE(LOWORD(dwSendTime));   //Current TickCount
  89.                 //Data
  90.                 for (int k = 0; k < m_iSendPackageSize - 4; ++k)
  91.                 {
  92.                         *pCurr++ = 0x61 + (k % 20);
  93.                 }
  94.                 uint16 usCheckSum = MakeChecksum((char*)ucCmdBuf, pCurr - ucCmdBuf);
  95.                 ucCmdBuf[2] = HIBYTE(usCheckSum);
  96.                 ucCmdBuf[3] = LOBYTE(usCheckSum);
  97.                 int txlen = sendto(sock, (char *)&ucCmdBuf, pCurr - ucCmdBuf, 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
  98.                 uint8 ucRxBuf[MAX_BUFFER_SIZE] = { 0 };
  99.                 struct sockaddr_in rxaddr;
  100.                 memset((char *)&rxaddr, 0, sizeof(rxaddr));
  101.                 rxaddr.sin_family = AF_INET;
  102.                 rxaddr.sin_port = 0;
  103.                 rxaddr.sin_addr.s_addr = inet_addr(strHost.c_str());
  104.                 int iSize = sizeof(struct sockaddr_in);
  105.                 do
  106.                 {
  107.                         int rxlen = recvfrom(sock, (char *)&ucRxBuf, sizeof(ucRxBuf), 0, (struct sockaddr *)&rxaddr, &iSize);   
  108.                         if (rxaddr.sin_addr.S_un.S_addr == pingaddr.sin_addr.S_un.S_addr)
  109.                         {       
  110.                                 if (rxlen >= 0)
  111.                                 {
  112.                                         //IP帧获取TTL
  113.                                         ttl = ucRxBuf[8];
  114.                                         //跳过IP Header 20个字节
  115.                                         uint8* pIcmpFrame = ucRxBuf + 20;
  116.                                         //Type和Code
  117.                                         uint8 ucType = pIcmpFrame[0];
  118.                                         uint8 ucCode = pIcmpFrame[1];
  119.                                         if (ucCode != 0x00 || ucType != 0x00)
  120.                                                 goto GO_ON;
  121.                                         //比对ID和序号
  122.                                         uint16 iRxID = pIcmpFrame[4] * 256 + pIcmpFrame[5];
  123.                                         uint16 iRxSequeNum = pIcmpFrame[6] * 256 + pIcmpFrame[7];
  124.                                         if (iRxID == m_iTxID && iRxSequeNum == m_iTxSequeNum)
  125.                                         {
  126.                                                 DWORD dwTimeTransmit = pIcmpFrame[8] * 256 * 256 * 256 + pIcmpFrame[9] * 256 * 256 + pIcmpFrame[10] * 256 + pIcmpFrame[11];
  127.                                                 auto now = std::chrono::system_clock::now();
  128.                                                 DWORD dwNowTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
  129.                                                 timems = dwNowTime - dwTimeTransmit;
  130.                                         }
  131.                                         else
  132.                                                 goto GO_ON;
  133.                                 }
  134.                                 else
  135.                                 {
  136.                                         timems = -1;  //异常
  137.                                 }
  138.                                 m_iTxID++;
  139.                                 m_iTxSequeNum++;
  140.                                 break;
  141.                         }
  142.         GO_ON:
  143.                         auto current_clock = std::chrono::system_clock::now();  
  144.                         DWORD dwCurrentTime = std::chrono::duration_cast<std::chrono::milliseconds>(current_clock.time_since_epoch()).count();;
  145.                         if (dwCurrentTime - dwSendTime > 2000)
  146.                         {
  147.                                 timems = -2;  //超时
  148.                                 return;
  149.                         }
  150.                 }
  151.                 while (true);
  152.         }
  153. }
  154. void InitWinSockEnv()
  155. {
  156.         WSADATA wsaData;
  157.         WSAStartup(MAKEWORD(2, 2), &wsaData);
  158. }
  159. void CleanupWinSockEnv()
  160. {
  161.         WSACleanup();
  162. }
复制代码
③、 PING多线程接口封装

多线程采用 std::thread 实现,线程函数封装如下:
  1. /************************************************************************/
  2. /*                                                                      */
  3. /*  @WrapExecPing函数功能:  线程函数,调用PING接口                       */
  4. /*                                                                      */
  5. /*  @aipaddr, bipaddr参数: 监视的节点IPA和IPB地址                        */
  6. /*  @atimems, btimems参数: IPA地址和IPB地址PING响应时间                  */
  7. /*  @attl, bttl参数:       IPA地址和IPB地址PING响应TTL值                 */
  8. /*  @stopf 参数:           停止线程任务标志位                            */
  9. /*  @package_size 参数:    PING包大小                                   */
  10. /*  @asnd, bsnd参数:       IPA地址和IPB地址PING次数                      */
  11. /*  @f 参数:               线程结束标志位                                */
  12. /*                                                                      */
  13. /************************************************************************/
  14. 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)
  15. {
  16.         IPing aping;
  17.         IPing bping;
  18.     //设置PING包大小
  19.         aping.SetPackSize(package_size);
  20.         bping.SetPackSize(package_size);
  21.         f = true;
  22.         while (!stopf)
  23.         {
  24.                 auto start = std::chrono::system_clock::now();
  25.                 DWORD dwStartTime = std::chrono::duration_cast<std::chrono::milliseconds>(start.time_since_epoch()).count();
  26.                 if (aipaddr.length() > 5)
  27.                 {
  28.             //执行IP地址A的PING
  29.                         aping.PingHost(aipaddr.c_str(), atimems, attl);
  30.                         asnd++;
  31.                 }
  32.                 else
  33.                         std::this_thread::sleep_for(std::chrono::milliseconds(500));
  34.                        
  35.                 if (bipaddr.length() > 5)
  36.                 {
  37.             //执行IP地址B的PING
  38.                         bping.PingHost(bipaddr.c_str(), btimems, bttl);
  39.                         bsnd++;
  40.                 }
  41.                 else
  42.                         std::this_thread::sleep_for(std::chrono::milliseconds(500));
  43.                 auto now = std::chrono::system_clock::now();
  44.                 DWORD dwNowTime = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
  45.                 if (dwNowTime - dwStartTime < 500)
  46.                 {
  47.                         std::this_thread::sleep_for(std::chrono::milliseconds(800));
  48.                 }
  49.         }
  50.         f = false;
  51. }
复制代码
④、 QT主程序开辟

【1】、 界面初始化

  1. MainWindow::MainWindow(QWidget *parent) :
  2.     QMainWindow(parent),
  3.     ui(new Ui::MainWindow)
  4. {
  5.     ui->setupUi(this);
  6.         //初始化Windows套接字环境
  7.         InitWinSock();
  8.         glb_bStopF = false;
  9.        
  10.         //初始化表格控件;
  11.         initTableWidget();
  12.         //初始化PING包大小复选框;
  13.         initComboBox();
  14.         //初始化延迟超限报警阈值;
  15.         initLineEdit();
  16.        
  17.         ui->pushButtonStop->setEnabled(false);
  18.         //设置控件样式表QSS
  19.         setStyleSheet("QMainWindow{ background-color: #365a7a; } QLabel{ color:#E0E0E0; font-weight:bold; }");
  20.        
  21.         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;}");
  22.         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;}");
  23.         ui->lineEdit->setStyleSheet("QLineEdit{background-color:#D9D9D9; color:gray;}");
  24.         ui->comboBox->setStyleSheet("QComboBox{color:gray;}");
  25.         //信号槽定义;
  26.         connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(onButtonStart()));
  27.         connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(onButtonStop()));
  28. }
复制代码
表格控件初始化
  1. void MainWindow::initTableWidget()
  2. {
  3.         //加载nodecfg.ini文件
  4.         extern bool LoadNodeConfig(CHostInfoArray& arry);
  5.         if (false == LoadNodeConfig(arry) || arry.size() <= 0)
  6.         {
  7.                 QMessageBox::warning(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("《nodecfg.ini》打开失败!"));
  8.                 return;
  9.         }
  10.         //初始化表格列
  11.         ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
  12.         ui->tableWidget->setColumnCount(MAX_COLUMN_NUM);
  13.         QStringList headerList;
  14.         headerList << QString::fromLocal8Bit("网络节点名称");
  15.         headerList << QString::fromLocal8Bit("A网IP地址");
  16.         headerList << QString::fromLocal8Bit("B网IP地址");
  17.         headerList << QString::fromLocal8Bit("A网延时");
  18.         headerList << QString::fromLocal8Bit("A网TTL");
  19.         headerList << QString::fromLocal8Bit("B网延时");
  20.         headerList << QString::fromLocal8Bit("B网TTL");
  21.         headerList << QString::fromLocal8Bit("PING次数");
  22.         ui->tableWidget->setHorizontalHeaderLabels(headerList);
  23.         ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}");
  24.         ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section {background-color: #365a7a; color: rgb(220,220,220); font-weight:bold;}");
  25.         ui->tableWidget->setColumnWidth(0, 120);
  26.         ui->tableWidget->setColumnWidth(1, 140);
  27.         ui->tableWidget->setColumnWidth(2, 140);
  28.         ui->tableWidget->setColumnWidth(7, 160);
  29.         //行
  30.         int iSize = arry.size();
  31.         if (iSize > 0)
  32.         {
  33.                 ui->tableWidget->setRowCount(iSize);
  34.                 for (int ii = 0; ii < iSize;++ii)
  35.                 {
  36.                         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));
  37.                         ui->tableWidget->setItem(ii, 1, new QTableWidgetItem());    ui->tableWidget->item(ii, 1)->setText(QString::fromStdString(arry[ii].strIPA));
  38.                         ui->tableWidget->setItem(ii, 2, new QTableWidgetItem());    ui->tableWidget->item(ii, 2)->setText(QString::fromStdString(arry[ii].strIPB));
  39.                         ui->tableWidget->setItem(ii, 3, new QTableWidgetItem());
  40.                         ui->tableWidget->setItem(ii, 4, new QTableWidgetItem());
  41.                         ui->tableWidget->setItem(ii, 5, new QTableWidgetItem());
  42.                         ui->tableWidget->setItem(ii, 6, new QTableWidgetItem());
  43.                         ui->tableWidget->setItem(ii, 7, new QTableWidgetItem());
  44.                 }
  45.         }
  46. }
复制代码
复选框控件初始化
  1. void MainWindow::initComboBox()
  2. {
  3.         ui->comboBox->addItem("32", 32);
  4.         ui->comboBox->addItem("128", 128);
  5.         ui->comboBox->addItem("256", 256);
  6.         ui->comboBox->addItem("512",512);
  7.         ui->comboBox->addItem("1024", 1024);
  8.         ui->comboBox->addItem("2048", 2048);
  9.         ui->comboBox->addItem("2500", 2500);
  10.         ui->comboBox->addItem("3000", 3000);
  11.         ui->comboBox->addItem("4096", 4096);
  12.         ui->comboBox->addItem("5000", 5000);
  13.         ui->comboBox->addItem("8000", 8000);
  14.         ui->comboBox->addItem("10000", 10000);
  15.         ui->comboBox->addItem("13000", 13000);
  16.         ui->comboBox->addItem("15000", 15000);
  17.         ui->comboBox->addItem("18000", 18000);
  18.         ui->comboBox->addItem("24000", 24000);
  19.         ui->comboBox->addItem("28000", 28000);
  20.         ui->comboBox->addItem("32000", 32000);
  21.         ui->comboBox->addItem("36000", 36000);
  22.         ui->comboBox->setCurrentIndex(0);
  23. }
复制代码
编辑框控件初始化
  1. void MainWindow::initLineEdit()
  2. {
  3.         ui->lineEdit->setText("200");
  4. }
复制代码
【2】、 启动多线程

使用 std::thread线程,
  1. void MainWindow::StartPingTask()
  2. {
  3.         int iSize = arry.size();
  4.         if (iSize <= 0)
  5.         {
  6.                 onButtonStop();
  7.                 return;
  8.         }
  9.         //报警阈值
  10.         int alarmval = ui->lineEdit->text().toInt();
  11.         //Ping包大小;
  12.         int index = ui->comboBox->currentIndex();
  13.         int package_size = ui->comboBox->itemData(index).toInt();
  14.         SPINGINFO* pPingInfo = new SPINGINFO[iSize];
  15.         for (int i = 0; i < iSize; i++)
  16.         {
  17.                 pPingInfo[i].host = arry[i];
  18.                 pPingInfo[i].attl = -1;
  19.                 pPingInfo[i].bttl = -1;
  20.                 pPingInfo[i].atimems = -1;
  21.                 pPingInfo[i].btimems = -1;
  22.                 pPingInfo[i].asnd = 0;
  23.                 pPingInfo[i].bsnd = 0;
  24.                 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));
  25.                 pPingInfo[i].t = std::move(T1);
  26.                 std::this_thread::sleep_for(std::chrono::milliseconds(10));
  27.         }
  28. }
复制代码
【3】、 完整代码

  1. #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) :
  2.     QMainWindow(parent),
  3.     ui(new Ui::MainWindow)
  4. {
  5.     ui->setupUi(this);
  6.         //初始化Windows套接字环境
  7.         InitWinSock();
  8.         glb_bStopF = false;
  9.        
  10.         //初始化表格控件;
  11.         initTableWidget();
  12.         //初始化PING包大小复选框;
  13.         initComboBox();
  14.         //初始化延迟超限报警阈值;
  15.         initLineEdit();
  16.        
  17.         ui->pushButtonStop->setEnabled(false);
  18.         //设置控件样式表QSS
  19.         setStyleSheet("QMainWindow{ background-color: #365a7a; } QLabel{ color:#E0E0E0; font-weight:bold; }");
  20.        
  21.         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;}");
  22.         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;}");
  23.         ui->lineEdit->setStyleSheet("QLineEdit{background-color:#D9D9D9; color:gray;}");
  24.         ui->comboBox->setStyleSheet("QComboBox{color:gray;}");
  25.         //信号槽定义;
  26.         connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(onButtonStart()));
  27.         connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(onButtonStop()));
  28. }
  29. 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企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

汕尾海湾

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表