【分享】一个集成tracert和ping的网络监测工具
最近接到一个需求,需求背景是这样的:目前Windows平台下本身都有tracert和ping的实现,而且可以直接在cmd下使用。
需求中有两个要求:
1. Windows平台中的tracert执行速度太慢,一次tracert可能要花十几分钟。所以,需要一个快速的tracert实现。
2.将tracert和ping结合起来:tracert出来的节点,需要ping一下,看看当前节点的连通性。
接到这个需求后,开始的时候有点无从下手,只能先从研究tracert的原理出发,搞清楚原理后才能去提升速率。
tracert原理:
Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由。
首先,tracert送出一个TTL是1的IP 数据包到目的地,当路径上的第一个路由器收到这个数据包时,它将TTL减1。此时,TTL变为0,所以该路由器会将此数据包丢掉,并送回一个「ICMP time exceeded」消息(包括发IP包的源地址,IP包的所有内容及路由器的IP地址),tracert 收到这个消息后,便知道这个路由器存在于这个路径上,接着tracert 再送出另一个TTL是2 的数据包,发现第2 个路由器,以此往复。。。。。
tracert 每次将送出的数据包的TTL 加1来发现另一个路由器,这个重复的动作一直持续到某个数据包 抵达目的地。当数据包到达目的地后,该主机则不会送回ICMP time exceeded消息,一旦到达目的地,由于tracert通过UDP数据包向不常见端口(30000以上)发送数据包,因此会收到「ICMP port unreachable」消息,故可判断到达目的地。
tracert 有一个固定的时间等待响应(ICMP TTL到期消息)。如果这个时间过了,它将打印出一系列的*号表明:在这个路径上,这个设备不能在给定的时间内发出ICMP TTL到期消息的响应。然后,Tracert给TTL记数器加1,继续进行。
读懂tracert的原理后,其实不难发现,TTL=1到TTL=30的请求其实关联性不大,我们要加速实现tracert可以从这里入手。
看一下tracert结果的格式:可以发现,每一次tracert最多会有30个节点,每个节点包含3个时间数据,经查阅是三次请求的响应时间
网上查阅了一些资料,发现可以基于ICMP.dll实现tracert,网友给出了代码:
1 //TraceRoute3.cpp 2 #include <stdio.h> 3 #include <winsock2.h> 4 #include <windows.h> 5 #include <IPHlpApi.h> 6 //增加静态链接库ws2_32.lib 7 #pragma comment(lib,"ws2_32.lib") 8 //声明3个函数类型的指针 9 typedef HANDLE (WINAPI *lpIcmpCreateFile)(VOID); 10 typedef BOOL (WINAPI *lpIcmpCloseHandle)(HANDLE IcmpHandle); 11 typedef DWORD (WINAPI *lpIcmpSendEcho)( 12 HANDLE IcmpHandle, 13 IPAddr DestinationAddress, 14 LPVOID RequestData, 15 WORD RequestSize, 16 PIP_OPTION_INFORMATION RequestOptions, 17 LPVOID ReplyBuffer, 18 DWORD ReplySize, 19 DWORD Timeout 20 ); 21 int main(int argc,char* argv[]){ 22 if(argc!=2){ 23 printf("Usage: %s destIP/n",argv[0]); 24 exit(-1); 25 } 26 WSADATA wsa; 27 if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){ 28 printf("WSAStartup failed./n"); 29 exit(-1); 30 } 31 //转换IP地址到整数 32 unsigned long ip = inet_addr(argv[1]); 33 if(ip==INADDR_NONE){ 34 //用户可能输入的是域名 35 hostent* pHost = gethostbyname(argv[1]); 36 //如果域名无法解析 37 if(pHost==NULL){ 38 printf("Invalid IP or domain name: %s/n", argv[1]); 39 exit(-1); 40 } 41 //取域名的第一个IP地址 42 ip = *(unsigned long*)pHost->h_addr_list[0]; 43 printf("trace route to %s(%s)/n/n",argv[1],inet_ntoa(*(in_addr*)&ip)); 44 }else{ 45 printf("trace route to %s/n/n",argv[1]); 46 } 47 //载入ICMP.DLL动态库 48 HMODULE hIcmpDll = LoadLibrary("icmp.dll"); 49 if(hIcmpDll==NULL){ 50 printf("fail to load icmp.dll/n"); 51 exit(-1); 52 } 53 //定义3个函数指针 54 lpIcmpCreateFile IcmpCreateFile; 55 lpIcmpCloseHandle IcmpCloseHandle; 56 lpIcmpSendEcho IcmpSendEcho; 57 //从ICMP.DLL中获取所需的函数入口地址 58 IcmpCreateFile = (lpIcmpCreateFile)GetProcAddress(hIcmpDll,"IcmpCreateFile"); 59 IcmpCloseHandle = (lpIcmpCloseHandle)GetProcAddress(hIcmpDll,"IcmpCloseHandle"); 60 IcmpSendEcho = (lpIcmpSendEcho)GetProcAddress(hIcmpDll,"IcmpSendEcho"); 61 //打开ICMP句柄 62 HANDLE hIcmp; 63 if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE){ 64 printf("/tUnable to open ICMP file./n"); 65 exit(-1); 66 } 67 //设置IP报头的TTL值 68 IP_OPTION_INFORMATION IpOption; 69 ZeroMemory(&IpOption,sizeof(IP_OPTION_INFORMATION)); 70 IpOption.Ttl = 1; 71 //设置要发送的数据 72 char SendData[32]; 73 memset(SendData,'0',sizeof(SendData)); 74 //设置接收缓冲区 75 char ReplyBuffer[sizeof(ICMP_ECHO_REPLY)+32]; 76 PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer; 77 BOOL bLoop = TRUE; 78 int iMaxHop = 30; 79 while(bLoop && iMaxHop--){ 80 printf("%2d: ",IpOption.Ttl); 81 //发送ICMP回显请求 82 if(IcmpSendEcho(hIcmp,(IPAddr)ip, SendData, sizeof(SendData), &IpOption, 83 ReplyBuffer, sizeof(ReplyBuffer), 3000)!=0){ 84 if(pEchoReply->RoundTripTime==0){ 85 printf("/t<1ms"); 86 }else{ 87 printf("/t%dms",pEchoReply->RoundTripTime); 88 } 89 printf("/t%s/n",inet_ntoa(*(in_addr*)&(pEchoReply->Address))); 90 //判断是否完成路由路径探测 91 if((unsigned long)pEchoReply->Address==ip){ 92 printf("/nTrace complete./n"); 93 bLoop = FALSE; 94 } 95 }else{ 96 printf("/t*/tRequest time out./n"); 97 } 98 IpOption.Ttl++; 99 } 100 IcmpCloseHandle(hIcmp); 101 FreeLibrary(hIcmpDll); 102 WSACleanup(); 103 return 0; 104 }
View Code
运行后可以看到,这里实现了和windows的dos里面一模一样的tracert,但距离我们想要的“快速”还有一定差距。
我们可以在这个基础上做改进:使用多线程来实现最多30跳跃点的请求,每次请求分别执行三次,最后我们可以直接使用90个线程来执行程序,最终将结果
按固定位置填充到定义的数组中。
至于结合ping就比较简单了,直接调用 windows下的ping命令。
最后,需要注意的是,我们使用c++做成一个exe供程序直接调用,这里需要接收外部参数:网址,是否执行ping命令,ping命令的-l参数,ping命令的-n参数
最终结果:
最终效果非常好,执行效率相比windows下的tracert快了非常多,而且非常方便。
注意:在某些系统上执行的时候会报错,需要添加两个dll文件:msvcp120d.dll和msvcr120d.dll到本机的windows/system32或者windows/SysWOW64下
小工具分享给大家,下载地址
转载于:https://www.cnblogs.com/miketwais/p/tracert_ping.html
【分享】一个集成tracert和ping的网络监测工具相关推荐
- Https/Tcp抓包工具Charles、fiddler,ping (网络诊断工具),Android平台HTTPS抓包解决方案及问题分析HttpCanary
市面上已经有一些弱网络模拟工具,比如微软的Network Emulator for Windows Toolkit(NEWT),Facebook的Augmented Traffic Control(A ...
- Windows CE下的网络监测工具(上)
作者:马宁 最近被一个软件网络连接的问题,折腾得死去活来.问题本身不复杂,主要是网络设置不同造成的,在这里不多说了.在调试过程中,用到了Windows CE下的几个网络监测工具,才了解到Windows ...
- 分享一个好用美观的桌面便签工具
最近事情比较杂乱,所以需要一个能在桌面上显示的标签工具,这样可以把待办事项罗列出来,就会清晰一些,也不容易忘记,然后朋友分享给我了这个小工具,个人觉得比较好用,分享给大家. 安装过程 1.在浏览器搜索 ...
- 分享一个自己做的简易敏捷开发管理工具——AgileLite
为了便于管理实验室里的小型项目开发团队,我在今年寒假期间做了这个工具.总共花一星期划拉出来的,所以功能比较简单,只有需求Tickets和Bug Reports管理.当初做这个工具主要是觉得用Word或 ...
- 分享一个运维同学常用的站点监测和测速网站17ce.com, 备用
https://www.17ce.com/ 功能挺多,记录下备用: 监测:Get, Ping, MTR, TraceRoute, Dns, Cdn, LDns 可以提供:趋势.区域.ISP.错误等分析 ...
- 分享一个超强的多功能截图+贴图工具Snipaste
不知道小伙伴们都使用什么软件截图呢?QQ?今天就给大家推荐一款简单但强大的截图工具,也可以让你将截图贴回到屏幕上!Snipaste 你还可以将剪贴板里的文字或者颜色信息转化为图片窗口,并且将它们进行缩 ...
- 分享一个超全的基于jedis的redis工具类
以下为部分代码,完整的代码和redis应用实例,请移步到码云. 码云地址: spring-boot-redis-case: 基于redisUtils的各种redis应用实例 ps:try-final ...
- 分享一个自制的免费的分割pdf的工具
想要一个分割pdf 的软件,网上许多软件下载了只能分割几页,要么就是收费的,无奈,只能自己手写一个. 使用python3,GUI使用tkinter,pdf相关操作使用PyPDF2,最后使用pyinst ...
- 一个集成ssh和vcn和其他的工具MobaXterm
MobaXterm Xserver with SSH, telnet, RDP, VNC and X11 - Home Editionhttps://mobaxterm.mobatek.net/dow ...
最新文章
- mybatis整合ehcache
- java读取本地文件下载_java 读取本地的json文件
- mysql不同count的性能分析
- php7连接oracle数据库,使用一个持久连接连到 Oracle 数据库 - PHP 7 中文文档
- kafka的key为null时如何存储
- mysql delete in死锁_mysql 执行delete引发死锁问题
- Rust核心团队前成员Brian Anderson加入PingCAP
- 讯达机器人_科大讯飞新品频发完善场景布局“双11”斩获三大平台25项冠军
- OpenGait:首个步态识别框架开源了!
- html 头尾代码自动,HTML Head Generator - 纯 CSS 实现的头部元标签代码生成器 - 钉子の次元...
- 《spring-boot学习》-11-定时任务
- leetcode----------Excel Sheet Column Number
- java输出csv文件在excel中显示乱码
- oracle+5秒钟一个间隔,ORACLE日期时间函数大全 (二)
- php可以在dw中吗,php新手求助,为什么在DW中设计里能看到运行php程序的结果,但…...
- 在你的Android上执行Linux命令
- iphone开机白苹果_iphone白苹果原因是什么 iphone白苹果解决方法【介绍】
- 全网最细海龟 (turtle) 画图讲解 (一):初探海龟绘图
- 在武汉火车站转车需要出现吗_武汉火车站可以在站内换乘哪些站 武汉地铁6号线和1号线/13号线换乘...
- html5 声控游戏,7款好玩的声控游戏,用声音征服世界!
热门文章
- RabbitMQ 安装与简单使用
- 控制台程序隐藏方法总结(四种)
- CODING 受邀参加《腾讯全球数字生态大会》
- tcp的发送端一个小包就能打破对端的delay_ack么?
- burp过期了,换一个
- C#常用单元测试框架比较:XUnit、NUnit和Visual Studio(MSTest)
- 三周第三次课 3.7 su命令 3.8 sudo命令 3.9 限制root远程登录
- Python 3.5.2 TypeError: a bytes-like object is required, not 'str’问题解决方案
- oracle创建表空间和用户授权
- iOS 点转成字符串,再字符串转换成点