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


237

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


6
用户是否可以上网。用户是否可以连接到互联网。为了发送电子邮件日志。
Mohit Deshpande 2010年

11
只需发送电子邮件。如果用户未连接,则您可能会收到某种异常(无论如何您都可能必须处理)。
赛斯2010年

15
另外,请注意,无法检查用户是否已连接到Internet。您所能知道的只是它们过去是否连接过。假设您有一个方法:“ bool c = IsConnected(); if(c){DoSomething();}”-在对IsConnected和DoSomething的调用之间,无线网络路由器可能已拔出。IsConnected实际上应该称为WasRecentlyConnected。
埃里克·利珀特

Windows NLM API应该是最好的。stackoverflow.com/questions/5405895/...
马比尔·拉曼

Answers:


292

这样的事情应该起作用。

System.Net.WebClient

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
            using (client.OpenRead("http://google.com/generate_204")) 
                return true; 
    }
    catch
    {
        return false;
    }
}

18
这可能比对Google进行ping更好,因为我认为我们无法保证Google会继续对ping做出响应。另一方面,我无法想象www.google.com不返回HTML的世界:)
Daniel Vassallo 2010年

3
@Daniel:一方面是正确的,但另一方面,实际上下载网站有点开销imo
Leo 2010年

9
无论哪种方式,都没有理由将4KB拉回-只需使用client.OpenRead(url)即可。如果它没有引发异常,那么它就可以连接。
乔什·M

14
这实际上不是那么有效。如果没有互联网,使用它可以使我的程序在1分钟以上启动。可能是由于尝试解析DNS。Ping 8.8.8.8(google dns)将其更改为3秒。
MadBoy 2013年

8
@DanielVassallo I cannot image a world where www.google.com does not return some HTML在中国为例...
杰罗姆MEVEL

84

绝对没有办法可靠地检查是否存在互联网连接(我假设您的意思是访问互联网)。

但是,您可以请求几乎永不脱机的资源,例如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;
}

24
+1“绝对不可能可靠地检查是否有互联网连接”
woz

6
所有这一切都是检查ping时google是否启动。如果您成功ping通之后的第二个瞬间掉线了,那该怎么办?这样做之前没有必要进行检查。
dbasnett

12
这与我的回答的主要陈述有何矛盾?
狮子座

10
使用“ google.com”将花费更多时间,因为需要解决。相反,直接使用IP执行ping操作会更快。ping通Google公共DNS IP地址(8.8.8.88.8.4.4)对我来说很好。
Mangesh

8
我想重申一点,Beware - many schools and offices block the ping protocol.如果您将这种方法用于将由客户端使用的应用程序,则建议不要使用这种检查Internet的方法
user1 2015年

42

除了检查之外,只需执行操作(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

9
对!只是这样做-但要为所有结果做好准备。
Panic Panic

3
请考虑以下事项:如果网络在x超时时间内关闭(例如,tracelog,路由器重置),则需要执行某些操作
Abir 2015年

2
不是OP,而是我要执行此操作的原因是,如果Internet连接不可用,请避免默认100秒超时。HTTP请求是在后台线程上完成的,因此不会阻塞UI线程,但是直到后台线程从HTTP请求返回并终止后,我的应用程序才能退出。如果我不知道互联网连接已断开,我只想完全避免该请求,而不是尝试找到一些“快乐的中等”超时值。
斯科特·史密斯

2
我的观点是,我们无法说明远程服务何时可用/不可用。另外,那些不响应ping的网站又如何呢?
dbasnett

另一个用例是在线检查器,它会在我的互联网备份后立即提醒我
Ben Philipp

28

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

所以我发现的另一种方法是使用InternetGetConnectedStatemethod。我的代码是

[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);         
}

在测试过程中,我发现安装VMWare播放器时(Internet断开连接)InternetGetConnectedState返回true。必须在控制面板\网络和Internet \网络连接(VMNet1和VMNet8)中禁用它。
HockeyJ 2015年

好的,贾斯汀·奥林格(Justin Oringer.though),尽管我已经检查了它,但必须再次进行验证
Kamran Shahid15年

2
对我来说最好的方法是,在此之后我仍然检查服务连接性,然后启动例程...我只是想避免出现异常。
Wagner Bertolini Junior

4
该代码仅检查网络电缆是否已插入
。– HackerMan

14

通过对Google进行ping操作来测试互联网连接:

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

7
与该答案一起进行描述将比问题的原始作者对更多的人有益。
Boeckm 2012年

13
当心-许多学校和办公室都阻止ping协议。傻,我知道。
上校恐慌

我找不到ping课程。请你帮助我好吗。我正在UWP上工作
否则

12

我不同意那些发表声明的人:“执行任务之前检查连通性有什么意义,因为检查之后可能会立即失去连接”。作为开发人员,我们在许多编程任务中肯定存在一定程度的不确定性,但是将不确定性降低到可接受的水平是挑战的一部分。

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

此页面上的某些响应非常好,但是确实引起了很多性能问题,例如挂起,主要是在没有连接的情况下。

在其中一些答案和我的同事的帮助下,这是我最终使用的解决方案:

         // 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
            }));
        }
    }

11

我已经看到了上面列出的所有选项,并且唯一可以用来检查互联网是否可用的可行选项是“ Ping”选项。导入 [DllImport("Wininet.dll")]和/ System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() 或其他任何NetworkInterface 类的变体 在检测网络的可用性方面效果不佳。这些方法仅检查网络电缆是否已插入。

“ Ping选项”

if(连接可用)返回 true

if(连接不可用,并且网络电缆已插入)返回 false

if(未插入网络电缆) Throws an exception

网络接口

if(可以使用互联网)返回 True

if(Internet不可用,并且网络电缆已插入)返回 True

if(未插入网络电缆)返回 false

[DllImport(“ Wininet.dll”)]

if(可以使用互联网)返回 True

if(Internet不可用,并且网络电缆已插入)返回 True

if(未插入网络电缆)返回 false

所以在的情况下,[DllImport("Wininet.dll")]NetworkInterface 没有知道,如果Internet连接可用的方式。


这是不正确的,我导入了Wininet.dll,插入了网络电缆,并且对于不可用的Internet场景获得了正确的结果。
WaldemarGałęzinowski19年

8

不能解决检查和运行代码之间网络中断的问题,但是相当可靠

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;
}

好主意,但就像您所说的可能并不完美。您也可以缓存发送/接收的字节,以备将来检查。虽然还不完美。
托德

此代码无效,请更正。它仅检查网络电缆是否已插入。
HackerMan '16

5

Ping google.com引入了DNS解析依赖性。Ping 8.8.8.8很好,但是Google离我只有几步之遥。我需要做的就是对互联网上距我最近的设备执行ping操作。

我可以使用Ping的TTL功能对第一个跃点,第二个跃点等进行ping操作,直到收到可路由地址上的内容的回复为止。如果该节点位于可路由地址上,则它位于Internet上。对于我们大多数人来说,第1跳将是我们的本地网关/路由器,而第2跳将是我们光纤连接另一端或其他任何地方的第一点。

此代码对我有用,并且比该线程中的其他一些建议更快地响应,因为它可以对Internet上最接近我的对象执行ping操作。

using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Diagnostics;

internal static bool ConnectedToInternet()
{
    const int maxHops = 30;
    const string someFarAwayIpAddress = "8.8.8.8";

    // Keep pinging further along the line from here to google 
    // until we find a response that is from a routable address
    for (int ttl = 1; ttl <= maxHops; ttl++)
    {
        Ping pinger = new Ping();
        PingOptions options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply = null;
        try
        {
            reply = pinger.Send(someFarAwayIpAddress, 10000, buffer, options);
        }
        catch (System.Net.NetworkInformation.PingException pingex)
        {
            Debug.Print("Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: " + pingex.Message);
            return false;
        }

        System.Diagnostics.Debug.Print("Hop #" + ttl.ToString() + " is " + (reply.Address == null ? "null" : reply.Address.ToString()) + ", " + reply.Status.ToString());

        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print("Hop #" + ttl.ToString() + " is " + reply.Status.ToString() + ", hence we are not connected.");
            return false;
        }

        if (IsRoutableAddress(reply.Address))
        {
            System.Diagnostics.Debug.Print("That's routable so you must be connected to the internet.");
            return true;
        }
    }

    return false;
}

private static bool IsRoutableAddress(IPAddress addr)
{
    if (addr == null)
    {
        return false;
    }
    else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
    {
        return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
    }
    else // IPv4
    {
        byte[] bytes = addr.GetAddressBytes();
        if (bytes[0] == 10)
        {   // Class A network
            return false;
        }
        else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
        {   // Class B network
            return false;
        }
        else if (bytes[0] == 192 && bytes[1] == 168)
        {   // Class C network
            return false;
        }
        else
        {   // None of the above, so must be routable
            return true;
        }
    }
}

4

是在Android中实现的方式。

作为概念证明,我将此代码翻译为C#:

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
    }
}

3
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;
    }
}

2

另一种选择是网络列表管理器API,它是适用于Vista和Windows 7 MSDN文章在这里。本文中的链接是下载代码示例的链接,您可以执行以下操作:

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

确保从“ COM”选项卡中添加对Network List 1.0 Type Library的引用...,该引用将显示为NETWORKLIST。


7
ee 在.NET中使用COM地狱?
jgauffin 2014年

@jgauffin您能否解释为什么应该避免在.NET中使用COM?与我发现的其他解决方案相比,COM解决方案似乎运行良好。
inexcitus

2

尝试通过捕获异常来避免测试连接。因为我们真的希望有时我们可能会失去网络连接。

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline

1
NetworkInterface来自哪里?编辑:我发现它:System.Net.NetworkInformation
inspire_coding


1

我个人认为Anton和moffeltje的答案是最好的,但是我添加了一项检查以排除由VMWare和其他人建立的虚拟网络。

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));
}

仅供参考,从GetIsNetworkAvailable()文档:如果任何网络接口都标记为“打开”并且不是环回或隧道接口,则认为网络连接可用。我不知道virtual是否将始终出现在界面的名称或描述中。那是标准吗?
Mike Cheel

1
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");

1
您是否可以添加有关此速度的信息以及它比其他已发布的解决方案更好的信息。这将帮助您完全解决问题。

8
此选项的问题是,bb即使网络未连接到Internet ,也仍然适用。
halfpastfour.am,2013年

2
虽然确实不能直接回答问题,但我认为在尝试ping Google等之前使用GetIsNetworkAvailable作为预检查还是有用的。–
Ben Hughes

3
此代码不告诉您Internet连接是否可用。如果您插入没有互联网的网络电缆,它将返回true。
HackerMan '16

1

ping的多线程版本:

  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";
          }
      }
  }

0

我认为这不可能,只是不简单。

我已经构建了类似的东西,是的,它并不完美,但是第一步是必不可少的:检查是否存在任何网络连接。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;
}

这很简单,但确实有助于提高检查质量,尤其是当您要检查各种代理配置时。

所以:

  • 检查是否存在网络连通性(将此做得很好,甚至在出现误报以改善NetworkIsAvailable功能时,甚至将日志发送回开发人员)
  • HTTP Ping
  • (通过每个HTTP Ping的代理配置循环)

1
@hackerman,这是非显而易见的第一步。第二步,如果编码器返回true,则编码人员可以对自己的服务器进行快速ping操作。重要的是,这提供了有缺陷的Windows api方法的替代方法。剩下的就是细节。
Todd

3
伪造。如果没有网络接口,则肯定没有互联网。ui可以立即更新,没有延迟,无需在其他主机上进行进一步检查。
Todd

0
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;
    }
}

请评论您的答案。不允许仅用代码回答。
ganchito55

这很自我解释,为了警务而警务?
轧辊

0

使用NetworkMonitor监视网络状态和Internet连接。

样品:

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");
        }
    }
}

好主意,但检查网络可用性,而不是互联网可用性
John Demetriou

此类还检查Internet的可用性:SourceCode

事情是,我尝试了,但是只有在没有可用网络的情况下,它才会触发
John Demetriou

0

介绍

在某些情况下,您需要使用Windows应用程序中的C#代码检查Internet是否可用。可能是使用Internet以Windows形式下载或上传文件,或者是从远程位置的数据库中获取一些数据,在这种情况下,必须进行Internet检查。

有一些方法可以使用C#从后面的代码检查Internet可用性。此处说明所有这些方式,包括其局限性。

  1. InternetGetConnectedState(wininet)

“ wininet” API可用于检查本地系统是否具有有效的Internet连接。用于此的名称空间是“ System.Runtime.InteropServices”,并使用DllImport导入dll“ wininet.dll”。之后,创建一个带有extern static的布尔变量,其函数名称为InternetGetConnectedState,带有两个参数description和reservedValue,如示例所示。

注意:extern修饰符用于声明在外部实现的方法。当您使用Interop服务调用非托管代码时,extern修饰符通常与DllImport属性一起使用。在这种情况下,该方法还必须声明为静态。

接下来,创建一个名称为“ IsInternetAvailable”的方法作为布尔值。此函数将使用上面的函数,该函数返回本地系统的Internet状态

[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;
    }
}
  1. GetIsNetworkAvailable

下面的示例使用GetIsNetworkAvailable方法确定网络连接是否可用。

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");
}

备注(根据MSDN):如果任何网络接口标记为“打开”并且不是环回或隧道接口,则认为网络连接可用。

在许多情况下,设备或计算机未连接到有用的网络,但仍被认为可用,并且GetIsNetworkAvailable将返回true。例如,如果运行应用程序的设备连接到需要代理的无线网络,但未设置代理,则GetIsNetworkAvailable将返回true。GetIsNetworkAvailable将返回true的另一个示例是,如果应用程序正在连接到集线器或路由器的计算机上运行,​​而集线器或路由器失去了上游连接。

  1. ping网络上的主机名

Ping和PingReply类允许应用程序通过获取主机的答复来确定是否可以通过网络访问远程计算机。这些类在System.Net.NetworkInformation命名空间中可用。以下示例显示如何ping主机。

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;
}

备注(根据MSDN):应用程序使用Ping类检测远程计算机是否可访问。网络拓扑可以确定Ping是否可以成功联系远程主机。代理,网络地址转换(NAT)设备或防火墙的存在和配置可以阻止Ping成功。Ping成功表示仅在网络上可以访问远程主机。不能保证远程主机上存在更高级别的服务(例如Web服务器)。

欢迎发表评论/建议。编码愉快!!


-1

对于我的应用程序,我们还通过下载微小文件进行测试。

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;
}

也。某些ISP可能会使用中间服务器来缓存文件。添加随机未使用的参数,例如。https://www.microsoft.com/favicon.ico?req=random_number 可以防止缓存。


-1

我在3g路由器/调制解调器上的那些方法上遇到问题,因为如果Internet断开连接,路由器会将页面重定向到其响应页面,因此您仍然会遇到麻烦,并且您的代码认为存在互联网。苹果(或其他)具有热点检测页面,该页面始终返回一定的响应。下面的示例返回“成功”响应。因此,您将完全确定可以连接互联网并获得真实的响应!

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;
}

-2

我有三个Internet连接测试。

  • 参考System.NetSystem.Net.Sockets
  • 添加以下测试功能:

测试1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试3

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;
    }
}

执行测试

如果你做出DictionaryString,并Boolean呼吁CheckList,在每次测试的结果添加到CheckList

现在,KeyValuePair使用for...each循环递归遍历每个对象。

如果CheckList包含Valuetrue,则说明存在Internet连接。


-4
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

这样可行


46
如果您的DNS缓存中包含Google的IP,它将不会发送DNS请求,因此即使您未连接,它也可能返回true
Thomas Levesque 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.