我们的应用程序的某些功能,可能需要一个互联网连接的运行时间测试。 一旦检测到互联网连接,可能会暂时被禁用的功能需要访问Internet和/或用户可以通过警报消息通知。 否则,应用程序可能会导致在操作过程中的错误,否则可能会导致恼人的问题.

Method 1: WebRequest

We may send a web request to a website which assumed to be online always, for example google.com. If we can get a response, then obviously the device that runs our application is connected to the internet.  

siamese网络 test test network connection_Internet Collapse  |  Copy Code

 

public static bool WebRequestTest()
        {
            string url = "http://www.google.com";
            try
            {
                System.Net.WebRequest myRequest = System.Net.WebRequest.Create(url);
                System.Net.WebResponse myResponse = myRequest.GetResponse();
            }
            catch (System.Net.WebException)
            {
                return false;
            }
            return true;
        }

 

Method 2: TCP Socket

There can be some delay in response of web request therefore this method may not be fast enough for some applications. A better way is to check whether port 80, default port for http traffic, of an always online website.

 

siamese网络 test test network connection_siamese网络 test_02 Collapse  |  Copy Code

 

public static bool TcpSocketTest()
        {
            try
            {
                System.Net.Sockets.TcpClient client =
                    new System.Net.Sockets.TcpClient("www.google.com", 80);
                client.Close();
                return true;
            }
            catch (System.Exception ex)
            {
                return false;
            }
        }

 

Method 3: Ping

There can be some delay in response of web request, therefore this method may not be fast enough for some applications. A better way is to check whether port 80, default port for http traffic, of an always online website.  

siamese网络 test test network connection_C#_03 Collapse  |  Copy Code

 

public bool PingTest()
        {
            System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
 
            System.Net.NetworkInformation.PingReply pingStatus =
                ping.Send(IPAddress.Parse("208.69.34.231"),1000);
 
            if (pingStatus.Status == System.Net.NetworkInformation.IPStatus.Success)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

 

You cannot use this method in .NET Compact Framework because there is no NetworkInformation namespace that comes with Compact Framework. However, you can use Smart Device Framework (http://www.opennetcf.com[^], Community Edition is free for download) provided by OpenNETCF. This framework comes with many other useful tools that .NET Compact Framework does not contain.

 

Notice that I used Google’s IP address 208.69.34.231. We could use Google’s web address www.google.com:

 

siamese网络 test test network connection_siamese网络 test_04 Collapse  |  Copy Code

 

System.Net.NetworkInformation.PingReply pingStatus = ping.Send("www.google.com",1000);

 

However, that will require DNS lookup which causes extra delay.

 

Method 4: DNS Lookup

Alternatively you can use DNS lookup to check internet connectivity. This method is faster than Ping method.  

siamese网络 test test network connection_siamese网络 test_05 Collapse  |  Copy Code

 

public static bool DnsTest()
        {
            try
            {
                System.Net.IPHostEntry ipHe =
                    System.Net.Dns.GetHostByName("www.google.com");
                return true;
            }
            catch
            {
                return false;
            }
        }

 

Method 5: Windows Internet API (WinINet)

WinINet API provides functions to test internet connectivity, such as InternetCheckConnection andInternetGetConnectedState. I do not have any idea about what these fucntions do exactly to test internet connectivity. You may refer to http://msdn.microsoft.com/en-us/library/aa384346(v=VS.85).aspx andhttp://msdn.microsoft.com/en-us/library/aa384702(v=VS.85).aspx for details.  

An example usage can be:

 

siamese网络 test test network connection_System_06 Collapse  |  Copy Code

 

[DllImport("wininet.dll")]
        private extern static bool InternetGetConnectedState(out int connDescription, int ReservedValue);
 
	//check if a connection to the Internet can be established 
        public static bool IsConnectionAvailable()
        {
            int Desc;
            return InternetGetConnectedState(out connDesc, 0);
        }

 

 

更多示例:收集网络0 Detect Internet Network Availability

siamese网络 test test network connection_API_07

这个示例很好,自带监听网络状态:http://www.codeproject.com/Articles/64975/Detect-Internet-Network-Availability

 

1. win32 API函数的做法:

要用的函数:InternetGetConnectedState

函数原形:BOOL InternetGetConnectedState(LPDWORD lpdwFlags,DWORD dwReserved);

参数lpdwFlags返回当前网络状态,,参数dwReserved依然是保留参数,设置为0即可。

INTERNET_CONNECTION_MODEM 通过调治解调器连接网络

INTERNET_CONNECTION_LAN 通过局域网连接网络

这个函数的功能是很强的。它可以:

  1. 判断网络连接是通过网卡还是通过调治解调器

  2. 是否通过代理上网

  3. 判断连接是On Line还是Off Line

  4. 判断是否安装“拨号网络服务”

  5. 判断调治解调器是否正在使用

这个win32 API在系统system32文件夹中wininet.dll中

使用这个判断的话,需要在类中这样写:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices;
namespace API {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }                  private const int INTERNET_CONNECTION_MODEM = 1;          private const int INTERNET_CONNECTION_LAN = 2;
        [DllImport("wininet.dll")]         private static extern bool InternetGetConnectedState(ref int dwFlag, int dwReserved);
        private void button1_Click(object sender, EventArgs e)         {             System.Int32 dwFlag = new int();             if (!InternetGetConnectedState(ref dwFlag, 0))             {                 MessageBox.Show("未连网!");             }             else if ((dwFlag & INTERNET_CONNECTION_MODEM) != 0)             {                 MessageBox.Show("采用调治解调器上网!");             }             else if((dwFlag & INTERNET_CONNECTION_LAN)!=0)                {                 MessageBox.Show("采用网卡上网!");               }         }     } }

2. 采用PING的方法 ping一个常见域名,如果ping通则网络正常

using System; using System.Collections.Generic; using System.Text; using System.Net.NetworkInformation; using System.Threading;
namespace ConsoleApplication1 {     class Program     {         static void Main(string[] args)         {             Ping p = new Ping();//创建Ping对象p             PingReply pr = p.Send("10.13.88.111");//向指定IP或者主机名的计算机发送ICMP协议的ping数据包
            if (pr.Status == IPStatus.Success)//如果ping成功             {                 Console.WriteLine("网络连接成功, 执行下面任务...");             }             else             {                 int times = 0;//重新连接次数;                 do                 {                     if (times >= 12)                     {                         Console.WriteLine("重新尝试连接超过12次,连接失败程序结束");                         return;                     }
                    Thread.Sleep(1000);//等待
                    pr = p.Send("10.13.88.111");
                    Console.WriteLine(pr.Status);
                    times++;
                }                 while (pr.Status != IPStatus.Success);
                Console.WriteLine("连接成功");                 times = 0;//连接成功,重新连接次数清为0;             }         }     } }

 一个完整的示例

ASP.net网站程序运行的时候,某些情况下需要判断网络的连通状态,包括局域网、互联网、aol等,甚至某个具体网站的连通情况。以下类库可以实现联网状态检测:

 

using System; using System.Web; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading;   namespace VvxT.Web {     public class Internet     {         #region 利用API方式获取网络链接状态         private static int NETWORK_ALIVE_LAN = 0x00000001;         private static int NETWORK_ALIVE_WAN = 0x00000002;         private static int NETWORK_ALIVE_AOL = 0x00000004;           [DllImport("sensapi.dll")]         private extern static bool IsNetworkAlive(ref int flags);         [DllImport("sensapi.dll")]         private extern static bool IsDestinationReachable(string dest, IntPtr ptr);           [DllImport("wininet.dll")]         private extern static bool InternetGetConnectedState(out int connectionDescription, int reservedValue);           public Internet() { }           public static bool IsConnected()         {             int desc = 0;             bool state = InternetGetConnectedState(out desc, 0);             return state;         }           public static bool IsLanAlive()         {             return IsNetworkAlive(ref NETWORK_ALIVE_LAN);         }         public static bool IsWanAlive()         {             return IsNetworkAlive(ref NETWORK_ALIVE_WAN);         }         public static bool IsAOLAlive()         {             return IsNetworkAlive(ref NETWORK_ALIVE_AOL);         }         public static bool IsDestinationAlive(string Destination)         {             return (IsDestinationReachable(Destination, IntPtr.Zero));         }         #endregion           /// <summary>         /// 在指定时间内尝试连接指定主机上的指定端口。 (默认端口:80,默认链接超时:5000毫秒)         /// </summary>         /// <param name="HostNameOrIp">主机名称或者IP地址</param>         /// <param name="port">端口</param>         /// <param name="timeOut">超时时间</param>         /// <returns>返回布尔类型</returns>         public static bool IsHostAlive(string HostNameOrIp, int? port, int? timeOut)         {             TcpClient tc = new TcpClient();             tc.SendTimeout = timeOut ?? 5000;             tc.ReceiveTimeout = timeOut ?? 5000;               bool isAlive;             try             {                 tc.Connect(HostNameOrIp, port ?? 80);                 isAlive = true;             }             catch             {                 isAlive = false;             }             finally             {                 tc.Close();             }             return isAlive;         }       }       public class TcpClientConnector     {         /// <summary>         /// 在指定时间内尝试连接指定主机上的指定端口。 (默认端口:80,默认链接超时:5000毫秒)         /// </summary>         /// <param name= "hostname ">要连接到的远程主机的 DNS 名。</param>         /// <param name= "port ">要连接到的远程主机的端口号。 </param>         /// <param name= "millisecondsTimeout ">要等待的毫秒数,或 -1 表示无限期等待。</param>         /// <returns>已连接的一个 TcpClient 实例。</returns>         public static TcpClient Connect(string hostname, int? port, int? millisecondsTimeout)         {             ConnectorState cs = new ConnectorState();             cs.Hostname = hostname;             cs.Port = port ?? 80;             ThreadPool.QueueUserWorkItem(new WaitCallback(ConnectThreaded), cs);             if (cs.Completed.WaitOne(millisecondsTimeout ?? 5000, false))             {                 if (cs.TcpClient != null) return cs.TcpClient;                 return null;                 //throw cs.Exception;             }             else             {                 cs.Abort();                 return null;                 //throw new SocketException(11001); // cannot connect             }         }           private static void ConnectThreaded(object state)         {             ConnectorState cs = (ConnectorState)state;             cs.Thread = Thread.CurrentThread;             try             {                 TcpClient tc = new TcpClient(cs.Hostname, cs.Port);                 if (cs.Aborted)                 {                     try { tc.GetStream().Close(); }                     catch { }                     try { tc.Close(); }                     catch { }                 }                 else                 {                     cs.TcpClient = tc;                     cs.Completed.Set();                 }             }             catch (Exception e)             {                 cs.Exception = e;                 cs.Completed.Set();             }         }           private class ConnectorState         {             public string Hostname;             public int Port;             public volatile Thread Thread;             public readonly ManualResetEvent Completed = new ManualResetEvent(false);             public volatile TcpClient TcpClient;             public volatile Exception Exception;             public volatile bool Aborted;             public void Abort()             {                 if (Aborted != true)                 {                     Aborted = true;                     try { Thread.Abort(); }                     catch { }                 }             }         }     } }

 

使用方法:Default.aspx.cs

using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net.Sockets;   namespace VvxT.Web {     public partial class _Default : System.Web.UI.Page     {         protected void Page_Load(object sender, EventArgs e)         {             bool IsConnected = Internet.IsConnected();             bool IsAOLAlive = Internet.IsAOLAlive();               DateTime oldTime1 = DateTime.Now;             bool IsDestinationAlive = Internet.IsDestinationAlive("cn.yahoo.com");             DateTime newTime1 = DateTime.Now;             TimeSpan ts1 = newTime1 - oldTime1;               bool IsLanAlive = Internet.IsLanAlive();             bool IsWanAlive = Internet.IsWanAlive();               DateTime oldTime2 = DateTime.Now;             //bool IsHostAlive = Internet.IsHostAlive("hk.yahoo.com", null, null);//不推荐使用(无法实际控制超时时间)             bool IsHostAlive;             TcpClient tc = TcpClientConnector.Connect("hk.yahoo.com", null, null);//推荐使用(采用线程池强行中断超时时间)             try             {                 if (tc != null)                 {                     tc.GetStream().Close();                     tc.Close();                     IsHostAlive = true;                 }                 else                     IsHostAlive = false;             }             catch { IsHostAlive = false; }             DateTime newTime2 = DateTime.Now;             TimeSpan ts2 = newTime2 - oldTime2;               Response.Write("Connect:" + IsConnected + "<br />");             Response.Write("Lan:" + IsLanAlive + "<br />");             Response.Write("Wan:" + IsWanAlive + "<br />");             Response.Write("Aol:" + IsAOLAlive + "<br />");             Response.Write("Sip(cn.yahoo.com):" + IsDestinationAlive + " 耗时:" + ts1.TotalMilliseconds + "<br />");             Response.Write("TcpClient(hk.yahoo.com):" + IsHostAlive + " 耗时:" + ts2.TotalMilliseconds + "<br />");             }     } }   运行效果: Connect:True Lan:True Wan:True Aol:True Sip(cn.yahoo.com):True 耗时:265.625 TcpClient(hk.yahoo.com):False 耗时:5000   当然,以上类库也可以在C#windows程序中使用。