【分享】一个集成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,网友给出了代码:
//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的网络监测工具的更多相关文章
- ping(网络诊断工具)
ping(网络诊断工具) Ping是Windows下的一个命令,在Unix和Linux下也有这个命令.ping也属于一个通信协议,是TCP/IP协议的一部分.利用"ping"命令可 ...
- 分享一个非常好用又好看的终端工具--Hyper (支持windows、MacOS、Linux)
分享一个非常好用又好看的终端工具--Hyper 官网地址: https://hyper.is/ 打开官网,选择对应版本安装即可:(可能网络原因,无法下载, 可以从我分享的链接下载 链接: https: ...
- 分享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo+SkyWalking的微服务开发框架
集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo的微服务开发框架 Github源代码地址 htt ...
- 分享一个集成在项目中的REST APIs文档框架swagger
1 为什么是使用swagger? 1-1 当后台开发人员开发好接口,是不是还要重新书写一份接口文档提给前端人员,当然对于程序员最不喜欢的就是书写文档(当然文档是必须的,有利于项目的维护) 1-2 当后 ...
- ping (网络诊断工具)
Ping是Windows.Unix和Lnix系统下的一个命令,ping也属于一个通信协议,是TCP/IP协议的一部分,利用Ping命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障.应用格 ...
- 分享一个LiteDB做的简单考试系统辅助工具
凌晨,被安排在公司值班,因为台风“灿鸿”即将登陆,风力太大,办公楼,车间等重要部分需要关注.所以无聊,那就分享一下,今天给朋友临时做的一个小的考试系统辅助工具吧.其实非常小,需求也很简单,但是可以根据 ...
- Ping命令网络监测
按照由近到远原则: 1. ping 127.0.0.1 先检查TCP/IP协议栈是否正常. 2. ping 本地ip 检查网卡是否工作正常. 3. ping 网关地址 检查和网关连接性. 4. pin ...
- 分享一个自研开发的QA自动化审计工具-Sonar检查
评价一个系统或软件的质量高低,我始终认为除了需求和设计外,代码质量很重要,一个高质量的系统或软件,并不是被测试出来的,更多的是要靠设计和开发出来的.目前也有很多自动化的测试工具,更多的是从功能和性能角 ...
- Monitorix:一款面向Linux的轻型系统和网络监测工具
Monitorix是一款功能非常强大的免费开源轻型工具,目的在于监测Linux中的系统和网络资源.它可以定期收集系统和网络数据,并使用自己的Web界面,通过图形显示相关信息.Monitorix让用户可 ...
随机推荐
- java.util.HashSet
Operations Time Complexity Notes add, remove, contains, size O(1) assuming the hash functions has di ...
- grpc介绍
grpc入门(一) 一.什么是grpc grpc是谷歌开源的一款高性能的rpc框架 (https://grpc.io),可以使用protocol buffers作为IDL(Interface Defi ...
- jQuery 事件方法(二)
方法 描述 bind() 向匹配元素附加一个或更多事件处理器 blur() 触发.或将函数绑定到指定元素的 blur 事件 change() 触发.或将函数绑定到指定元素的 change 事件 cli ...
- springboot 注册服务注册中心(zk)的两种方式
在使用springboot进行开发的过程中,我们经常需要处理这样的场景:在服务启动的时候,需要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,可以故障摘除和负载均衡. 我遇到过两种注 ...
- NanUI文档 - 如何实现C#与Javascript的相互通信
NanUI文档目录 NanUI简介 开始使用NanUI 打包并使用内嵌式的HTML/CSS/JS资源 使用网页来设计整个窗口 如何实现C#与Javascript的相互通信 如何处理NanUI中的下载过 ...
- Box布局
import sys from PyQt4 import QtCore, QtGui class MainWindow(QtGui.QWidget): def __init__(self, paren ...
- Flask分页
一.flask实现的分页组件 from urllib.parse import urlencode,quote,unquote class Pagination(object): "&quo ...
- Python进阶内容(五)--- type和object的关系
面向对象编程(OOP)的两大关系 继承与实现 继承关系: 子类继承自父类(base),可以使用父类的一些方法(method)和属性(attribute) 实现关系: 以类为模板,实例化一个对象,即:对 ...
- React Native分享第三方遇到的问题
这几天做APP的分享,好多东西都不懂,踩了好多坑,所幸现在做好了,开心^_^ 时间紧,随便记一下先. 1.签名文件要和各平台的签名一致 2.新浪微博和微信的分享要打包之后,加上签名了才可以(我一直不知 ...
- 初次了解struts的action类
Action类真正实现应用程序的事务逻辑,它们负责处理请求.在收到请求后,ActionServlet会为这个请求选择适当的Action 如果需要,创建Action的一个实例 调用Action的perf ...