.NET Compact Framework下的Ping(ICMP)的开发

简介:

什么是 Ping Tester?

Ping Tester是一个网络侦测工具(Diagnostics),可以使用在Windows Mobile来检查网络的联通性。

 

简介

文本讲述了在.NET Compact Framework下ping功能的实现。 主要通过P/Invoke的方式调用ICMP相关的API来实现。 同时提供一个Windows Mobile的工具来调用Ping封装类。

 

背景

由于在3G网络下开发数据通信程序,需要验证该网络的连通性和可靠性,所以开发这个Ping封装类方便验证网络的可靠性。

 

原理

Ping(Packet InterNet Groper)是一个网络诊断工具,他的工作原理就是 发送ICMP的“echo request” 数据包到目标主机,然后监听ICMP的“echo response”回应数据包。 Ping通过度量反应时间(round-trip time, RTT)和记录所有丢包情况等信息,产生一个统计报告。下面是我电脑ping博客园的例子,请大家看看本人的网络是如何的不可靠,生活在水深火热的中,写Blog常常断网。


复制代码
C:\ > ping cnblogs.com

Pinging cnblogs.com [
222.92 . 117.56 ] with  32  bytes of data:

Request timed 
out .
Request timed 
out .
Reply from 
222.92 . 117.56 : bytes = 32  time = 360ms TTL = 108
Reply from 
222.92 . 117.56 : bytes = 32  time = 359ms TTL = 108

Ping statistics 
for   222.92 . 117.56 :
    Packets: Sent 
=   4 , Received  =   2 , Lost  =   2  ( 50 %  loss),
Approximate round trip times 
in  milli - seconds:
    Minimum 
=  359ms, Maximum  =  360ms, Average  =  359ms 
复制代码

ping的详细介绍可以参考这篇文章 http://en.wikipedia.org/wiki/Ping

 

解决方案

从上述的原理可知,对ping的开发其实就是对ICMP协议的开发。Internet Control Message Protocol (ICMP) 是网络层的协议,其负责网络主机之间的控制流信息,错误消息,路由信息以及其他数据的传输。关于 ICMP的详细介绍 可以参考这篇文章Internet Control Message Protocol (ICMP)

进行ICMP的开发,主要有以下几个API:
IcmpCreateFile     生成发送ICMP请求的句柄。
IcmpSendEcho2   发送ICMP请求,并得到回应信息。
IcmpCloseHandle  关闭IcmpCreateFile生成的句柄。

下面为这些API的P/Invoke

复制代码
[DllImport( " iphlpapi.dll " )]
internal   static   extern  IntPtr IcmpCreateFile();

[DllImport(
" iphlpapi.dll " )]
internal   static   extern   uint  IcmpSendEcho2(IntPtr icmpHandle, IntPtr Event, IntPtr apcRoutine, IntPtr apcContext,  uint  ipAddress, IntPtr data,  ushort  dataSize,  ref  IPOptions options, IntPtr replyBuffer,  uint  replySize,  uint  timeout);

[DllImport(
" iphlpapi " )]
internal   static   extern   bool  IcmpCloseHandle(IntPtr handle); 
复制代码


通过参考Smart Device Framework 1.4源代码,我实现了一个Ping的封装类, Smart Device Framework 1.4可以在下面链接下载 http://www.opennetcf.com/Products/SmartDeviceFramework/tabid/65/Default.aspx

复制代码
public  IcmpEchoReply Send(IPAddress address,  int  timeout)
{
    
if  (handle  ==  IntPtr.Zero)
    {
        handle 
=  IcmpCreateFile();
    } 

    
if  (replyBuffer  ==  IntPtr.Zero)
    {
        replyBuffer 
=  LocalAlloc(LPTR, ( uint ) 0xffff );
    } 

    requestBuffer 
=  LocalAlloc(LPTR, ( uint )SendBuffer.Length);
    Marshal.Copy(SendBuffer, 
0 , requestBuffer, SendBuffer.Length); 

    
uint  ip  =  BitConverter.ToUInt32(address.GetAddressBytes(),  0 ); 

    IPOptions option 
=   new  IPOptions( null   as  PingOptions); 

    IcmpSendEcho2(handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ip, requestBuffer, (
ushort )SendBuffer.Length,  ref  option, replyBuffer,  0xffff , ( uint )timeout);
    
if  (requestBuffer  !=  IntPtr.Zero)
    {
        LocalFree(requestBuffer);
        requestBuffer 
=  IntPtr.Zero;
    }
    
return  Marshal.PtrToStructure(replyBuffer,  typeof (IcmpEchoReply))  as  IcmpEchoReply;
}

复制代码

上面是发送ICMP请求的核心代码,代码的逻辑是 先生成一个ICMP句柄,为返回结果包分配内存,对发送包进行赋值。然后发送ICMP请求,并等待回应。当接收到回应时把回应的数据包赋值到IcmpEchoReply结构体里面。回应信息可以通过IcmpEchoReply结构体取出。IcmpEchoReply信息可参考下面的客户端代码。

 

客户端

复制代码
IcmpEchoReply reply  =  ping.Send(ip);
if  (reply.status  ==  ( uint )IPStatus.Success)
{
    IPAddress addr 
=   new  IPAddress(reply.address);
    ShowMessage(String.Format(
" Reply from {0}: Echo size={1} time<{2}ms TTL={3} " , addr, reply.dataSize, reply.roundTripTime, reply.ttl));
}
else
{
    IPStatus ipStatus 
=  (IPStatus)reply.status;
    ShowMessage(String.Format(
" PING: transmit failed, error code {0}, {1} " , reply.status.ToString(), ipStatus));
}
复制代码

客户端调用的时候只需要调用Send()方法,然后分析IcmpEchoReply的结果。

ping1 
图1

为了提高可用性,增加对域名的支持。

复制代码
IPAddress address  =   null ;
IPAddress[] addressList 
=   null ;
try
{
    address 
=  IPAddress.Parse(uri);
}
catch
{
    
try
    {
        IPHostEntry entry 
=  Dns.GetHostEntry(uri);
        addressList 
=  entry.AddressList;
    }
    
catch  (Exception ex)
    {
        ShowMessage(String.Format(
" Ping request could not find host {0}. Please check the name and try again. {1} " , textBoxAddress.Text, ex.Message));
    }


if  (address  !=   null )
{
    ShowMessage(String.Format(
" Pinging Host {0} " , uri));
    Ping(address);
}
else
{
    
for  ( int  i  =   0 ; i  <  addressList.Length;  ++ i)
    {
        ShowMessage(String.Format(
" Pinging Host {0} [{1}] " , uri, addressList[i]));
        Ping(addressList[i]);
    }
}

复制代码

当用户输入不是IP地址的时候,会对域名进行解释,把该域名的所对应的所有IP解释出来,存放到addressList里面,然后对每个IP进行Ping。
下面为ping www.google.com的例子,http://www.google.com/对应3个不同的IP。

ping2 
图2


源代码:PingTester.rar

运行环境:VS2008 + Windows Mobile 6 Professional SDK  + CF.NET 2.0

 


    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2009/06/19/1506823.html,如需转载请自行联系原作者



相关文章
|
10天前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
44 12
|
8天前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
|
8天前
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
|
8天前
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
|
8天前
|
网络协议 C#
基于.NET WinForm开发的一款硬件及协议通讯工具
基于.NET WinForm开发的一款硬件及协议通讯工具
|
8天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
2月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
48 4
|
4月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
4月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
87 0
|
5月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
66 0