程序侦测当前网络连通性的各种实现

用程序进行网络状态检查  在实际的应用开发中,我们的应用程序经常需要在运行时侦测当前系统的,特别是在应用程序需要访问网络的时候,可以通过运行时的侦测网络连通性,及时反馈给用户,以便用户做出正确的选择;也可以在得到侦测结果后,系统根据网络的连通性状态做出相应的处理,比如在需要网络访问才能正常使用的应用程序中,一旦检测到网络不能正常使用之后,做出相应的处理,可以更好的防止不必要错误异常发生。当前系统.NET进行网络的连通性侦测有很多种方法,本文将使用.NET(C#/VB)代码展示多种具有代表性且比较简易的方法来的连通性。

第一种方法:使用WebRequest/HttpWebRequest对象来访问指定的主机名。代码如下:

//通过访问网页的方式确定当前系统的连通性
//需要注意,选择的主机名/域名必须确保异常的可能性尽可能小
public bool HttpRequestMonitor(string host)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
    request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36";
    request.Method = "GET";
    try
    {
        using (HttpWebResponse response = ((HttpWebResponse)request.GetResponse()))
        {
            return true;
        }
    }
    catch (Exception ex)
    {
        return false;
    }
    return true;
}

上面使用的是HttpWebRequest的方式来检测,你也可以直接使用WebRequest,代码如下:

//需要确保主机名/域名的连通性高
public static bool WebRequestMonitor(string host)
{
    try
    {
        WebRequest myRequest = WebRequest.Create(host);
        WebResponse myResponse = myRequest.GetResponse();
    }
    catch (WebException)
    {
        return false;
    }
    return true;
}

这两种方法都可以达到检测的目的,优势是方便理解,也能快速上手,但有一个劣势,就是用来检测的网站域名必须要能够确保长时间正常在线,如果要访问的域名出现故障,那么检测将不准确。

第二种方法:TCP Socket检测,这里可以使用主机名,也可以使用IP地址。使用主机名/域名的方式如下:

//使用主机名方式来检测连通性
// 如果是域名,后面的port一般为80
public static bool TcpSocketMonitor(string host, int port)
{
    try
    {
        using(TcpClient client = new TcpClient(host, port))
        {
        	client.Close();
        }
    }
    catch (Exception ex)
    {
        return false;
    }
    return true;
}

使用IP地址来访问:

//基本和使用主机名检测的方法类似.
public static bool TcpSocketMonitorByIp(string ip, int port)
{
    try
    {
        using (TcpClient client = new TcpClient(new IPEndPoint(IPAddress.Parse(ip), port)))
        {
            client.Close();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
    return true;
}

这种方法的优势也是使用难度不高,劣势同样是选择的目标必须在线率高,不然会存在不稳定的现象。如果使用IP的方式,可以使用两台机器进行互相检测,这样可以比较好的规避在线率的问题。

第三种方法:也就是我们常用的Ping了,Ping同样可以使用主机名/域名或者IP,代码如下:

//使用主机名/域名的方式来检测网络的连通性
public bool PingServer(string host)
{
    try
    {
        Ping ping = new Ping();
        PingReply replye = ping.Send(host, 1000);
        //如果使用IP,那么只需ping.Send(IPAddress.Parse(host), 1000)这种方式即可
        return replye.Status == IPStatus.Success;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
}

 这种方式比前面的方法有一定的优势,即无需对指定端口的访问,但劣势同样和前面的一样,依赖目标服务器,并且很有可能会出现禁Ping的情况。如果是内部的服务器相互Ping,效果会好些。

第四种方法:使用DNS来检测网络的连通性,这种方法是通过DNS来获取域名的IP,代码如下:

//请求DNS返回域名的IP,如果没有错误,说明网络连通
public bool DnsLookup(string host)
{
    try
    {
        IPHostEntry ipHE = Dns.GetHostEntry(host);
        return true;
    }
    catch (Exception ex)
    {
        //Console.WriteLine(ex.Message);
        return false;
    }
}

这个方法优于前面三种方法,而且前面三种方法的基础也是DNS,因此用这种方法应该是当前最佳的。优势是简单,并且一般不太可能出现DNS异常的情况。

第五种方法:使用Windows Internet API (WinINet)来操作,这个方法来源于网络[1],一般比较少使用这种方式,代码如下:

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int connDescription, int ReservedValue);
//尝试建立到互联网的连接来检测连通性
public static bool IsConnectionAvailable()
{
    int Desc;
    return InternetGetConnectedState(out connDesc, 0);
}

 

第六种方法:使用WMI的方式确定当前网络的连通性[2]。该方法是使用WMI来PING,方法比较复杂,需要了解WMI的方法,具体方法如下:

strComputer = "."
Set objWMIService = GetObject(_ 
    "winmgmts:\\" & strComputer & "\root\cimv2")
Set colPings = objWMIService.ExecQuery _
    ("Select * From Win32_PingStatus where Address = '192.168.1.1'")

For Each objStatus in colPings
    If IsNull(objStatus.StatusCode) _
        or objStatus.StatusCode<>0 Then 
        WScript.Echo "Computer did not respond." 
    Else
        Wscript.Echo "Computer responded."
    End If
Next

   在实际使用中,个人比较喜欢选用DNS的方式来确定网络连通性,当然也不一定,在实际情况中,根据自己的需求选择适当的方式即可。

 

附注:

1. 本文的大部分方法都可以在这里找到:http://www.codeproject.com/Tips/147662/Testing-Internet-Connectivity

非常感谢作者的耐心和细心分类,由于全部是英文,我权当翻译了一下好了,很多没有实际中使用的方法,本文直接引用了原文的例子,有的稍作修改。

2. WMI的方式是在微软官方网站中的例子,你可以在这里找到:http://msdn.microsoft.com/en-us/library/windows/desktop/aa394595(v=vs.85).aspx

Friday, June 14, 2013 | .NET技术

文章评论

  • # re: 程序侦测当前网络连通性的各种实现
    这个对于开发者很常用

发表评论

Please add 4 and 8 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,属于互联网行业分类中的杂牌军。