[C#]路由跟踪tracert
2013-11-07 16:55
246 查看
using System; using System.Threading; using System.Diagnostics; using System.Text.RegularExpressions; using System.Net; using System.Net.NetworkInformation; namespace tracert { class Program { static byte[] PING_BUFFER = new byte[] { 0 }; static int g_nHops = 30; static int g_nTimeout = 3000; static bool g_bCanceled = false; public struct ICMP_PARAM { internal long m_nSendTicks; internal IPAddress m_IPAddress; internal PingOptions m_PingOptions; } static void icmp_PingCompleted(object sender, PingCompletedEventArgs e) { ICMP_PARAM param = (ICMP_PARAM)e.UserState; long nDeltaMS = (DateTime.Now.Ticks - param.m_nSendTicks) / TimeSpan.TicksPerMillisecond; Console.WriteLine("{0}:\t{1} ms\t{2}", param.m_PingOptions.Ttl, (e.Reply.Status == IPStatus.TimedOut) ? "*" : nDeltaMS.ToString(), e.Reply.Address.ToString()); if (param.m_IPAddress.Equals(e.Reply.Address)) { Console.WriteLine("已到达目标地址!"); g_bCanceled = true; return; } if (param.m_PingOptions.Ttl >= g_nHops) { Console.WriteLine("已达到最大跃点计数!"); g_bCanceled = true; return; } Ping icmp = (Ping)sender; param.m_PingOptions.Ttl++; param.m_nSendTicks = DateTime.Now.Ticks; icmp.SendAsync(param.m_IPAddress, g_nTimeout, PING_BUFFER, param.m_PingOptions, param); } static void Usage() { Console.WriteLine("Usage: {0} [-h max_hops] [-w timeout] ip/domain", Process.GetCurrentProcess().ProcessName); } static void Main(string[] args) { string szDomain = ""; if (args.Length == 0) { Usage(); return; } else { string szTmp = ""; for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("-")) { if (args[i].Length == 2) { if (i + 1 < args.Length) { szTmp = args[i + 1]; } else { Usage(); return; } } else { szTmp = args[i].Substring(2); } switch (args[i][1]) { case 'h': case 'H': if (!int.TryParse(szTmp, out g_nHops)) { Usage(); return; } break; case 'w': case 'W': if (!int.TryParse(szTmp, out g_nTimeout)) { Usage(); return; } break; default: Usage(); return; } } else { szDomain = args[i]; } } } Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress); ICMP_PARAM param = new ICMP_PARAM(); param.m_PingOptions = new PingOptions(1, false); if (!IPAddress.TryParse(szDomain, out param.m_IPAddress)) { // 解析域名 try { Regex regEx = new Regex("\\d+\\.\\d+\\.\\d+\\.\\d+"); IPHostEntry hostEntry = Dns.GetHostEntry(szDomain); foreach (IPAddress ipAddr in hostEntry.AddressList) { if (regEx.IsMatch(ipAddr.ToString())) { param.m_IPAddress = ipAddr; break; } } if (param.m_IPAddress == null) { Usage(); return; } Console.WriteLine("正在跟踪到 {0}[{1}] 间的路由:", szDomain, param.m_IPAddress.ToString()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); return; } } else { Console.WriteLine("正在跟踪到 {0} 间的路由:", param.m_IPAddress.ToString()); } Ping icmp = new Ping(); icmp.PingCompleted += new PingCompletedEventHandler(icmp_PingCompleted); param.m_nSendTicks = DateTime.Now.Ticks; icmp.SendAsync(param.m_IPAddress, g_nTimeout, PING_BUFFER, param.m_PingOptions, param); while (!g_bCanceled) { Thread.Sleep(1); } } static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { Console.WriteLine("程序被终止!"); } } }
tracert的原理比较简单,每个路由器收到ICMP报文都会将TTL减一再发送到下一个路由,当TTL减少到0时将值返回源IP地址,可以利用这个原理从1开始逐步增加TTL的值来获取到指定IP路径上经过的路由IP。附上的代码是C#控制台代码。
相关文章推荐
- url访问 路由跟踪 命令 tracert
- Windows下的路由跟踪tracert
- tracert路由跟踪工具使用方法
- tracert路由跟踪命令分析判断
- Java调用cmd下的tracert(路由跟踪)命令
- tracert路由跟踪命令分析推断
- tracert 路由跟踪
- tracert 路由跟踪信息
- Tracert(跟踪路由)是路由跟踪实用程序
- tracert路由跟踪(ICMP)
- Visual C# Simulate "Tracert" Command
- 如何做路由跟踪图,tracert命令
- tracert路由跟踪工具使用方法
- C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码
- c#中对文件的操作小结(http://www.a2605.org/ddvipcom/program/c-/index1/134.htm)
- 在C#中使用COM+实现事务控制
- C#基础学习 —— 异步编程篇 2
- C#基础概念二十五问
- C# 编码规则(实例版)
- 看陈广老师c#参考视频总结(第八篇)