当前位置: 首页 > news >正文

利用多线程设计群ping工具

扫描局域网内有哪些可以使用的IP

Ping 的工作原理

Ping 基于 ICMP(Internet 控制报文协议)实现网络连通性检测,工作流程如下:

  1. 源主机向目标 IP 发送 ICMP Echo 请求报文(Type=8)
  2. 目标主机收到后,返回 ICMP Echo 应答报文(Type=0)
  3. 源主机通过是否收到应答及时间差,判断目标是否可达及网络延迟
  4. 若超时未收到应答或途中 TTL 耗尽,会收到 ICMP 差错报文

C++ 多线程扫描局域网 IP 步骤

步骤 1:准备开发环境
  • 需支持 C++11 及以上标准(提供线程库)
  • Windows 系统需包含 Windows.h,Linux 系统需包含 netinet/ip_icmp.h 等网络头文件
步骤 2:创建原始套接字

原始套接字用于发送和接收 ICMP 报文,需要管理员 /root 权限

步骤 3:实现 ICMP 报文构造与解析

构造符合 ICMP 规范的 Echo 请求报文,包含类型、代码、校验和、标识符、序列号等字段

步骤 4:实现多线程扫描逻辑

使用线程池并发处理多个 IP 的 Ping 请求,避免线程创建销毁的开销

步骤 5:结果收集与显示

收集各线程返回的扫描结果,统一显示存活的 IP 地址

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <chrono>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")using namespace std;vector<string> liveIPs;
mutex mtx;// 检查单个IP是否存活
bool pingIP(const char* ipAddress) {HANDLE hIcmpFile;unsigned long ipaddr = inet_addr(ipAddress);if (ipaddr == INADDR_NONE) {return false;}hIcmpFile = IcmpCreateFile();if (hIcmpFile == INVALID_HANDLE_VALUE) {return false;}const int requestSize = 32;char requestData[requestSize] = {0};for (int i = 0; i < requestSize; i++) {requestData[i] = 'a' + i;}char replyBuffer[sizeof(ICMP_ECHO_REPLY) + requestSize];DWORD replySize = sizeof(replyBuffer);DWORD timeout = 1000; // 超时时间1秒DWORD result = IcmpSendEcho(hIcmpFile, ipaddr, requestData, requestSize, NULL, replyBuffer, replySize, timeout);IcmpCloseHandle(hIcmpFile);return (result > 0);
}// 线程工作函数:扫描IP段
void scanIPRange(const string& baseIP, int start, int end) {for (int i = start; i <= end; i++) {string ip = baseIP + "." + to_string(i);if (pingIP(ip.c_str())) {lock_guard<mutex> lock(mtx);liveIPs.push_back(ip);}}
}// 生成IP范围并启动多线程扫描
void scanNetwork(const string& baseIP, int threadCount = 10) {liveIPs.clear();// 计算每个线程负责的IP范围int ipsPerThread = 254 / threadCount;vector<thread> threads;for (int i = 0; i < threadCount; i++) {int start = i * ipsPerThread + 1;int end = (i == threadCount - 1) ? 254 : (i + 1) * ipsPerThread;threads.emplace_back(scanIPRange, baseIP, start, end);}// 等待所有线程完成for (auto& t : threads) {if (t.joinable()) {t.join();}}
}int main() {WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {cerr << "WSA初始化失败" << endl;return 1;}string baseIP;cout << "请输入局域网前缀(如192.168.1): ";cin >> baseIP;cout << "开始扫描局域网..." << endl;auto startTime = chrono::steady_clock::now();// 使用10个线程进行扫描scanNetwork(baseIP, 10);auto endTime = chrono::steady_clock::now();chrono::duration<double> elapsed = endTime - startTime;cout << "\n扫描完成,耗时: " << elapsed.count() << "秒" << endl;cout << "存活的IP地址列表:" << endl;for (const auto& ip : liveIPs) {cout << ip << endl;}WSACleanup();return 0;
}

// 线程参数结构
struct ThreadData
{
CString ip;             // IP地址
int thread_id;          // 线程ID
BOOL thread_result;     // Ping结果(TRUE=在线)  
MPingDlg* pDlg;         // 对话框指针
HANDLE hEvent;
};

http://www.dtcms.com/a/318605.html

相关文章:

  • 5G随身WiFi怎么选?实测延迟/网速/续航,中兴V50适合商务,格行MT700适合短租、户外党~避坑指南+适用场景全解析
  • 无监督学习之K-means算法
  • 古多倍体化对被子植物适应性进化的遗传贡献--文献精度154
  • 本地部署 SQLite 数据库管理工具 SQLite Browser ( Web ) 并实现外部访问
  • 根据经纬度(从nc格式环境数据文件中)提取环境因子
  • RabbitMQ面试精讲 Day 12:镜像队列与Quorum队列对比
  • PCL 平面特征点提取
  • 2 SpringBoot项目对接单点登录说明
  • C语言控制语句练习题3
  • 数据结构与算法
  • 嵌入式 - 数据结构:栈和队列
  • [Oracle] ROUND()函数
  • 软件架构:系统结构的顶层设计与战略约束
  • 【前端】Vite中import.meta功能详解
  • 【多模态微调】【从0开始】Qwen2-VL + llamafactory
  • 小杰python高级(one day)——numpy库
  • 应急响应-windows篇
  • Spring选择哪种方式代理?
  • 12、Docker Compose 安装 Redis
  • CGAL Kernel 和 Traits 类深度解析:从官方教程到实践应用
  • 疯狂星期四文案网第30天运营日记
  • 从Token到序列:阿里GSPO算法如何让大模型训练更稳、更强?
  • CubeFS存储(一)
  • 16-DS18B20-±0.5℃精度-12bitADC--55°C ~ +125°C
  • ubuntu server 工业环境部署手册[2025-08-06]
  • ⭐CVPR 文本到 3D 场景生成新突破:Prometheus 框架解析
  • http请求结构体解析
  • 【C++】二叉树进阶
  • 人工智能大数据模型驱动企业创新
  • 商用密码应用安全性评估法律法规的重要性及演变过程