最近接到一个需求,需求背景是这样的:目前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,网友给出了代码:

 //TraceRoute3.cpp
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <IPHlpApi.h>
//增加静态链接库ws2_32.lib
#pragma comment(lib,"ws2_32.lib")
//声明3个函数类型的指针
typedef HANDLE (WINAPI *lpIcmpCreateFile)(VOID);
typedef BOOL (WINAPI *lpIcmpCloseHandle)(HANDLE IcmpHandle);
typedef DWORD (WINAPI *lpIcmpSendEcho)(
HANDLE IcmpHandle,
IPAddr DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout
);
int main(int argc,char* argv[]){
if(argc!=){
printf("Usage: %s destIP/n",argv[]);
exit(-);
}
WSADATA wsa;
if(WSAStartup(MAKEWORD(,),&wsa)!=){
printf("WSAStartup failed./n");
exit(-);
}
//转换IP地址到整数
unsigned long ip = inet_addr(argv[]);
if(ip==INADDR_NONE){
//用户可能输入的是域名
hostent* pHost = gethostbyname(argv[]);
//如果域名无法解析
if(pHost==NULL){
printf("Invalid IP or domain name: %s/n", argv[]);
exit(-);
}
//取域名的第一个IP地址
ip = *(unsigned long*)pHost->h_addr_list[];
printf("trace route to %s(%s)/n/n",argv[],inet_ntoa(*(in_addr*)&ip));
}else{
printf("trace route to %s/n/n",argv[]);
}
//载入ICMP.DLL动态库
HMODULE hIcmpDll = LoadLibrary("icmp.dll");
if(hIcmpDll==NULL){
printf("fail to load icmp.dll/n");
exit(-);
}
//定义3个函数指针
lpIcmpCreateFile IcmpCreateFile;
lpIcmpCloseHandle IcmpCloseHandle;
lpIcmpSendEcho IcmpSendEcho;
//从ICMP.DLL中获取所需的函数入口地址
IcmpCreateFile = (lpIcmpCreateFile)GetProcAddress(hIcmpDll,"IcmpCreateFile");
IcmpCloseHandle = (lpIcmpCloseHandle)GetProcAddress(hIcmpDll,"IcmpCloseHandle");
IcmpSendEcho = (lpIcmpSendEcho)GetProcAddress(hIcmpDll,"IcmpSendEcho");
//打开ICMP句柄
HANDLE hIcmp;
if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE){
printf("/tUnable to open ICMP file./n");
exit(-);
}
//设置IP报头的TTL值
IP_OPTION_INFORMATION IpOption;
ZeroMemory(&IpOption,sizeof(IP_OPTION_INFORMATION));
IpOption.Ttl = ;
//设置要发送的数据
char SendData[];
memset(SendData,'',sizeof(SendData));
//设置接收缓冲区
char ReplyBuffer[sizeof(ICMP_ECHO_REPLY)+];
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
BOOL bLoop = TRUE;
int iMaxHop = ;
while(bLoop && iMaxHop--){
printf("%2d: ",IpOption.Ttl);
//发送ICMP回显请求
if(IcmpSendEcho(hIcmp,(IPAddr)ip, SendData, sizeof(SendData), &IpOption,
ReplyBuffer, sizeof(ReplyBuffer), )!=){
if(pEchoReply->RoundTripTime==){
printf("/t<1ms");
}else{
printf("/t%dms",pEchoReply->RoundTripTime);
}
printf("/t%s/n",inet_ntoa(*(in_addr*)&(pEchoReply->Address)));
//判断是否完成路由路径探测
if((unsigned long)pEchoReply->Address==ip){
printf("/nTrace complete./n");
bLoop = FALSE;
}
}else{
printf("/t*/tRequest time out./n");
}
IpOption.Ttl++;
}
IcmpCloseHandle(hIcmp);
FreeLibrary(hIcmpDll);
WSACleanup();
return ;
}

运行后可以看到,这里实现了和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下

小工具分享给大家,下载地址

【分享】一个集成tracert和ping的网络监测工具的更多相关文章

  1. ping(网络诊断工具)

    ping(网络诊断工具) Ping是Windows下的一个命令,在Unix和Linux下也有这个命令.ping也属于一个通信协议,是TCP/IP协议的一部分.利用"ping"命令可 ...

  2. 分享一个非常好用又好看的终端工具--Hyper (支持windows、MacOS、Linux)

    分享一个非常好用又好看的终端工具--Hyper 官网地址: https://hyper.is/ 打开官网,选择对应版本安装即可:(可能网络原因,无法下载, 可以从我分享的链接下载 链接: https: ...

  3. 分享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo+SkyWalking的微服务开发框架

    集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo的微服务开发框架 Github源代码地址 htt ...

  4. 分享一个集成在项目中的REST APIs文档框架swagger

    1 为什么是使用swagger? 1-1 当后台开发人员开发好接口,是不是还要重新书写一份接口文档提给前端人员,当然对于程序员最不喜欢的就是书写文档(当然文档是必须的,有利于项目的维护) 1-2 当后 ...

  5. ping (网络诊断工具)

    Ping是Windows.Unix和Lnix系统下的一个命令,ping也属于一个通信协议,是TCP/IP协议的一部分,利用Ping命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障.应用格 ...

  6. 分享一个LiteDB做的简单考试系统辅助工具

    凌晨,被安排在公司值班,因为台风“灿鸿”即将登陆,风力太大,办公楼,车间等重要部分需要关注.所以无聊,那就分享一下,今天给朋友临时做的一个小的考试系统辅助工具吧.其实非常小,需求也很简单,但是可以根据 ...

  7. Ping命令网络监测

    按照由近到远原则: 1. ping 127.0.0.1 先检查TCP/IP协议栈是否正常. 2. ping 本地ip 检查网卡是否工作正常. 3. ping 网关地址 检查和网关连接性. 4. pin ...

  8. 分享一个自研开发的QA自动化审计工具-Sonar检查

    评价一个系统或软件的质量高低,我始终认为除了需求和设计外,代码质量很重要,一个高质量的系统或软件,并不是被测试出来的,更多的是要靠设计和开发出来的.目前也有很多自动化的测试工具,更多的是从功能和性能角 ...

  9. Monitorix:一款面向Linux的轻型系统和网络监测工具

    Monitorix是一款功能非常强大的免费开源轻型工具,目的在于监测Linux中的系统和网络资源.它可以定期收集系统和网络数据,并使用自己的Web界面,通过图形显示相关信息.Monitorix让用户可 ...

随机推荐

  1. springCloud系列教程01:Eureka 注册中心集群搭建

    springCloud系列教程包含如下内容: springCloud系列教程01:Eureka 注册中心集群搭建 springCloud系列教程02:ConfigServer 配置中心server搭建 ...

  2. sql sever模糊查询和聚合函数

    使用is null 的时候 要确保 查询的列 可以为空! null:  01.标识  空值  02.不是0,也不是空串""  03.只能出现在定义 允许为null的字段  04.只 ...

  3. 未能解析此远程名称: 'www.***.com' 解决办法

    今天发布网站的时候在本机IIS上调试完全没问题,但发布到远程服务器上却出现了如下错误: 原因:远程服务器的DNS解析失败,不能对类似于'www.***.com' 的网站解析,所以我们要进行手动解析. ...

  4. zabbix借助onealert实现微信报警

    官网:http://wiki.110monitor.com/integration/zabbix-manual.html) Zabbix安装包部署方式 1)下载agent软件包 请在Zabbix服务器 ...

  5. redis 写入的时候报错

    redis 写入报错 1)报错内容 Exception in thread "main" redis.clients.jedis.exceptions.JedisDataExcep ...

  6. HTML编码规范、CSS编码规范

    HTML编码规范 IE 兼容模式 IE 支持通过特定的 标签来确定绘制当前页面所应该采用的 IE 版本.除非有强烈的特殊需求,否则最好是设置为 edge mode,从而通知 IE 采用其所支持的最新的 ...

  7. js 数组API之every、some用法

    every 判断数组中是否每个元素都满足条件 只有都满足条件才返回true: 只要有一个不满足就返回false: arr.every(function(value,index,array){retur ...

  8. Redis学习笔记(三)Redis支持的5种数据类型的总结

    继续Redis学习笔记(二)来说说剩余的三种数据类型. 三.列表类型(List) 1.介绍 列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的一段片段.列表类型内部是 ...

  9. golang动态加载原生代码思路

    golang动态加载原生代码思路(非plugin,非so文件.使用mmap形式运行机器码,可释放) 1.用go tool objdump,可以看到任意函数的机器码.汇编指令.偏移.(go源码下面有一个 ...

  10. Visual Studio Code+phpstudy(WampServer、LNMP...)为小白打造PHP开发环境

    VS Code是微软近年推出的一款文本编辑器, 相关下载:https://code.visualstudio.com/Download phpstudy是将Apache/Nginx.PHP.MySQ等 ...