C# 使用.NET检查Internet连接的最佳方法是什么?

C# 使用.NET检查Internet连接的最佳方法是什么?,c#,.net,internet-connection,C#,.net,Internet Connection,在.NET中检查Internet连接的最快和最有效的方法是什么?您绝对无法可靠地检查是否存在Internet连接(我假定您指的是访问Internet) public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null) { try { url ??= CultureInfo.InstalledUICulture switch {

在.NET中检查Internet连接的最快和最有效的方法是什么?

您绝对无法可靠地检查是否存在Internet连接(我假定您指的是访问Internet)

public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null)
{
    try
    {
        url ??= CultureInfo.InstalledUICulture switch
        {
            { Name: var n } when n.StartsWith("fa") => // Iran
                "http://www.aparat.com",
            { Name: var n } when n.StartsWith("zh") => // China
                "http://www.baidu.com",
            _ =>
                "http://www.gstatic.com/generate_204",
        };

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.KeepAlive = false
        request.Timeout = timeoutMs;
        using var response = (HttpWebResponse)request.GetResponse();
        return true;
    }
    catch
    {
        return false;
    }
}
但是,您可以请求几乎从不离线的资源,比如ping google.com或类似的东西。我认为这将是有效的

try { 
    Ping myPing = new Ping();
    String host = "google.com";
    byte[] buffer = new byte[32];
    int timeout = 1000;
    PingOptions pingOptions = new PingOptions();
    PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
    return (reply.Status == IPStatus.Success);
}
catch (Exception) {
    return false;
}

这是可行的

只需执行操作(web请求、邮件、ftp等)并做好请求失败的准备,即使检查成功,也必须这样做

考虑以下几点:

1 - check, and it is OK
2 - start to perform action 
3 - network goes down
4 - action fails
5 - lot of good your check did
如果网络断开,您的操作将以与ping一样快的速度失败,等等

1 - start to perform action
2 - if the net is down(or goes down) the action will fail

通过ping Google进行互联网连接测试:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success

另一个选项是适用于Vista和Windows 7的网络列表管理器API。MSDN文章。本文中提供了一个下载代码示例的链接,您可以通过该链接执行以下操作:

AppNetworkListUser nlmUser = new AppNetworkListUser();
Console.WriteLine("Is the machine connected to internet? " + nlmUser.NLM.IsConnectedToInternet.ToString());

请确保从COM选项卡添加对网络列表1.0类型库的引用。。。这将显示为网络列表。

我不同意有人说:“在执行任务之前检查连接有什么意义,因为检查之后连接可能会立即丢失。”。
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
当然,作为开发人员,我们承担的许多编程任务都存在一定程度的不确定性,但将不确定性降低到可接受的程度是挑战的一部分

我最近在制作一个应用程序时遇到了这个问题,该应用程序包含一个链接到在线互动程序服务器的映射功能。当发现缺乏互联网连接时,将禁用此功能

此页面上的一些响应非常好,但是确实导致了很多性能问题,例如挂起,主要是在缺少连接的情况下

在这些答案和我的同事的帮助下,我最终使用了以下解决方案:

         // Insert this where check is required, in my case program start
         ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
    }

    void CheckInternetConnectivity(object state)
    {
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                webClient.Proxy = null;
                webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                webClient.OpenReadAsync(new Uri("<url of choice here>"));
            }
        }
    }

    volatile bool internetAvailable = false; // boolean used elsewhere in code

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            internetAvailable = true;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                // UI changes made here
            }));
        }
    }
//在需要检查的地方插入此选项,在我的例子中是“程序启动”
QueueUserWorkItem(检查InternetConnectivity);
}
void CheckInternetConnectivity(对象状态)
{
if(System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
使用(WebClient WebClient=new WebClient())
{
webClient.CachePolicy=新的System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
webClient.Proxy=null;
webClient.OpenReadCompleted+=webClient\u OpenReadCompleted;
webClient.OpenReadAsync(新Uri(“”);
}
}
}
volatile bool internetAvailable=false;//代码中其他地方使用的布尔值
void webClient\u OpenReadCompleted(对象发送方,OpenReadCompletedEventArgs e)
{
如果(e.Error==null)
{
internetAvailable=true;
Dispatcher.Invoke(DispatcherPriority.Normal,新操作(()=>
{
//此处所做的UI更改
}));
}
}

无法解决网络在检查和运行代码之间出现故障的问题 但它相当可靠

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        // however, this will include all adapters -- filter by opstatus and activity
        NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        return (from face in interfaces
                where face.OperationalStatus == OperationalStatus.Up
                where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
    }

    return false;
}

NetworkInterface.GetIsNetworkAvailable
非常不可靠。只要有一些VMware或其他LAN连接,它就会返回错误的结果。 同样关于
Dns.GetHostEntry
方法,我只是担心在我的应用程序将要部署的环境中,测试URL是否会被阻止

我发现的另一种方法是使用
InternetGetConnectedState
方法。 我的代码是

[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

public static bool CheckNet()
{
     int desc;
     return InternetGetConnectedState(out desc, 0);         
}

如果要在网络/连接发生更改时通知用户/采取措施。
使用NLM API:


    • 我不认为这是不可能的,只是不简单而已

      我已经建立了类似的东西,是的,它并不完美,但第一步是必不可少的:检查是否有任何网络连接。Windows Api做得不好,为什么不做得更好呢

      bool NetworkIsAvailable()
      {
          var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
          foreach (var item in all)
          {
              if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
                  continue;
              if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
                  continue; //Exclude virtual networks set up by VMWare and others
              if (item.OperationalStatus == OperationalStatus.Up)
              {
                  return true;
              }
          }
      
          return false;
      }
      
      这非常简单,但它确实有助于提高检查的质量,特别是当您想要检查各种代理配置时

      因此:

      • 检查是否存在网络连接(使其真正良好,甚至可能在出现误报时将日志发送回开发人员,以改进网络可用功能)
      • HTTP Ping
      • (在每个代理配置上循环使用HTTP ping)

        • ping google.com引入了DNS解析依赖项。Pinging8.8.8.8很好,但谷歌离我还有几步之遥。我所需要做的就是在网上找到离我最近的东西

          我可以使用Ping的TTL功能Ping hop#1,然后Ping hop#2,等等,直到我从可路由地址上的某个东西得到回复;如果该节点位于可路由地址上,则它位于internet上。对我们大多数人来说,hop#1将是我们的本地网关/路由器,而hop#2将是我们光纤连接另一端的第一个点或其他点

          这段代码对我来说很有用,而且响应速度比这个线程中的其他一些建议更快,因为它正在ping互联网上离我最近的任何东西

          
          使用系统诊断;
          Net系统;
          使用System.Net.NetworkInformation;
          使用System.Net.Sockets;
          使用System.Threading.Tasks;
          公共静态异步任务isconnectedPointernatasync()
          {
          常量int maxHops=30;
          const string someFarAwayIpAddress=“8.8.8.8”;
          //沿着从这里到谷歌的路线继续ping
          //直到我们找到一个来自可路由地址的响应
          
          对于(int-ttl=1;ttl=16&&bytes[1]我已经看到了上面列出的所有选项,唯一可行的检查wither internet是否可用的选项是“Ping”选项。 导入
          [DllImport(“Wininet.dll”)]
          系统。
          
          bool NetworkIsAvailable()
          {
              var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
              foreach (var item in all)
              {
                  if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
                      continue;
                  if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
                      continue; //Exclude virtual networks set up by VMWare and others
                  if (item.OperationalStatus == OperationalStatus.Up)
                  {
                      return true;
                  }
              }
          
              return false;
          }
          
          private bool ping()
          {
              System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
              System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
              if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
              {                
                  return true;
              }
              else
              {                
                  return false;
              }
          }
          
          public static bool Isconnected = false;
          
          public static bool CheckForInternetConnection()
          {
              try
              {
                  Ping myPing = new Ping();
                  String host = "google.com";
                  byte[] buffer = new byte[32];
                  int timeout = 1000;
                  PingOptions pingOptions = new PingOptions();
                  PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
                  if (reply.Status == IPStatus.Success)
                  {
                      return true;
                  }
                  else if (reply.Status == IPStatus.TimedOut)
                  {
                      return Isconnected;
                  }
                  else
                  {
                      return false;
                  }
              }
              catch (Exception)
              {
                  return false;
              }
          }
          
          public static void CheckConnection()
          {
              if (CheckForInternetConnection())
              {
                  Isconnected = true;
              }
              else
              {
                  Isconnected = false;
              }
          }
          
          public static bool IsAvailableNetworkActive()
          {
              // only recognizes changes related to Internet adapters
              if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) return false;
          
              // however, this will include all adapters -- filter by opstatus and activity
              NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
              return (from face in interfaces
                      where face.OperationalStatus == OperationalStatus.Up
                      where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                      where (!(face.Name.ToLower().Contains("virtual") || face.Description.ToLower().Contains("virtual")))
                      select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
          }
          
          string remoteUri = "https://www.microsoft.com/favicon.ico"
          
          WebClient myWebClient = new WebClient();
          
          try
          {
              byte[] myDataBuffer = myWebClient.DownloadData (remoteUri);
              if(myDataBuffer.length > 0) // Or add more validate. eg. checksum
              {
                  return true;
              }
          }
          catch
          {
              return false;
          }
          
          var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
          request.UserAgent = "Android";
          request.KeepAlive = false;
          request.Timeout = 1500;
          
          using (var response = (HttpWebResponse)request.GetResponse())
          {
              if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
              {
                  //Connection to internet available
              }
              else
              {
                  //Connection to internet not available
              }
          }
          
          public bool IsOnlineTest1()
          {
              try
              {
                  IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
                  return true;
              }
              catch (SocketException ex)
              {
                  return false;
              }
          }
          
          public bool IsOnlineTest2()
          {
              try
              {
                  IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
                  return true;
              }
              catch (SocketException ex)
              {
                  return false;
              }
          }
          
          public bool IsOnlineTest3()
          {
              System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
              System.Net.WebResponse resp = default(System.Net.WebResponse);
              try
              {
                  resp = req.GetResponse();
                  resp.Close();
                  req = null;
                  return true;
              }
              catch (Exception ex)
              {
                  req = null;
                  return false;
              }
          }
          
          public static bool CheckForInternetConnection()
          {
              try
              {       
                  using (var webClient = new WebClient())
                  using (var stream = webClient.OpenRead("http://captive.apple.com/hotspot-detect.html"))
                  {
                      if (stream != null)
                      {
                          //return true;
                          stream.ReadTimeout = 1000;
                          using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                          {
                              string line;
                              while ((line = reader.ReadLine()) != null)
                              {
                                  if (line == "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>")
                                  {
                                      return true;
                                  }
                                  Console.WriteLine(line);
                              }
                          }
          
                      }
                      return false;
                  }
              }
              catch
              {
          
              }
              return false;
          }
          
            using System;
            using System.Collections.Generic;
            using System.Diagnostics;
            using System.Net.NetworkInformation;
            using System.Threading;
          
          
            namespace OnlineCheck
            {
                class Program
                {
          
                    static bool isOnline = false;
          
                    static void Main(string[] args)
                    {
                        List<string> ipList = new List<string> {
                            "1.1.1.1", // Bad ip
                            "2.2.2.2",
                            "4.2.2.2",
                            "8.8.8.8",
                            "9.9.9.9",
                            "208.67.222.222",
                            "139.130.4.5"
                            };
          
                        int timeOut = 1000 * 5; // Seconds
          
          
                        List<Thread> threadList = new List<Thread>();
          
                        foreach (string ip in ipList)
                        {
          
                            Thread threadTest = new Thread(() => IsOnline(ip));
                            threadList.Add(threadTest);
                            threadTest.Start();
                        }
          
                        Stopwatch stopwatch = Stopwatch.StartNew();
          
                        while (!isOnline && stopwatch.ElapsedMilliseconds <= timeOut)
                        {
                             Thread.Sleep(10); // Cooldown the CPU
                        }
          
                        foreach (Thread thread in threadList)
                        { 
                            thread.Abort(); // We love threads, don't we?
                        }
          
          
                        Console.WriteLine("Am I online: " + isOnline.ToYesNo());
                        Console.ReadKey();
                    }
          
                    static bool Ping(string host, int timeout = 3000, int buffer = 32)
                    {
                        bool result = false;
          
                        try
                        {
                            Ping ping = new Ping();                
                            byte[] byteBuffer = new byte[buffer];                
                            PingOptions options = new PingOptions();
                            PingReply reply = ping.Send(host, timeout, byteBuffer, options);
                            result = (reply.Status == IPStatus.Success);
                        }
                        catch (Exception ex)
                        {
          
                        }
          
                        return result;
                    }
          
                    static void IsOnline(string host)
                    {
                        isOnline =  Ping(host) || isOnline;
                    }
                }
          
                public static class BooleanExtensions
                {
                    public static string ToYesNo(this bool value)
                    {
                        return value ? "Yes" : "No";
                    }
                }
            }
          
          namespace AmRoNetworkMonitor.Demo
          {
              using System;
          
              internal class Program
              {
                  private static void Main()
                  {
                      NetworkMonitor.StateChanged += NetworkMonitor_StateChanged;
                      NetworkMonitor.StartMonitor();
          
                      Console.WriteLine("Press any key to stop monitoring.");
                      Console.ReadKey();
                      NetworkMonitor.StopMonitor();
          
                      Console.WriteLine("Press any key to close program.");
                      Console.ReadKey();
                  }
          
                  private static void NetworkMonitor_StateChanged(object sender, StateChangeEventArgs e)
                  {
                      Console.WriteLine(e.IsAvailable ? "Is Available" : "Is Not Available");
                  }
              }
          }
          
           if (NetworkInterface.GetIsNetworkAvailable() &&
               new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
           //is online
           else
           //is offline
          
          [DllImport("wininet.dll")]
          private extern static bool InternetGetConnectedState(out int description, int reservedValue);
          public static bool IsInternetAvailable()
          {
              try
              {
                  int description;
                  return InternetGetConnectedState(out description, 0);
              }
              catch (Exception ex)
              {
                  return false;
              }
          }
          
          if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
          {
              System.Windows.MessageBox.Show("This computer is connected to the internet");
          }
          else
          {
              System.Windows.MessageBox.Show("This computer is not connected to the internet");
          }
          
          protected bool CheckConnectivity(string ipAddress)
          {
              bool connectionExists = false;
              try
              {
                  System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
                  System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
                  options.DontFragment = true;
                  if (!string.IsNullOrEmpty(ipAddress))
                  {
                      System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
                      connectionExists = reply.Status == 
          System.Net.NetworkInformation.IPStatus.Success ? true : false;
                  }
              }
              catch (PingException ex)
              {
                  Logger.LogException(ex.Message, ex);
              }
              return connectionExists;
          }
          
          public static class AwsHelpers
          {
              public static bool GetCanConnectToAws()
              {
                  try
                  {
                      using (var client = new WebClientWithShortTimeout())
                      using (client.OpenRead("https://aws.amazon.com"))
                          return true;
                  }
                  catch
                  {
                      return false;
                  }
              }
          }
          
          public class WebClientWithShortTimeout: WebClient
          {
              protected override WebRequest GetWebRequest(Uri uri)
              {
                  var webRequest = base.GetWebRequest(uri);
                  webRequest.Timeout = 5000;
                  return webRequest;
              }
          }
          
          bool connection = NetworkInterface.GetIsNetworkAvailable();
          if (connection == true)
           {
               MessageBox.Show("The system is online");
           }
           else {
               MessageBox.Show("The system is offline";
           }