【问题标题】:C# Testing active internet connection. Pinging google.comC# 测试活动的互联网连接。 ping google.com
【发布时间】:2010-10-22 12:18:10
【问题描述】:

C# 2008

我正在使用此代码来测试互联网连接。因为我的应用程序必须登录到 Web 服务器。但是,如果用户互联网连接失败或电缆被拔出。我必须通知用户。

 // Ping www.google.com to check if the user has a internet connection.
    public bool PingTest()
    {
        Ping ping = new Ping();

        PingReply pingStatus = ping.Send(IPAddress.Parse("208.69.34.231"));

        if (pingStatus.Status == IPStatus.Success)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

我认为我可以测试 Internet 连接的唯一方法是 ping www.google.com。因此,我使用了一个已设置为 500 毫秒的服务器计时器,在失效的事件中它将调用此 ping 函数。如果 ping 返回 false。然后我的应用将采取适当的行动。

您认为使用 google 来测试 Internet 连接是件好事吗?如果谷歌失败了,那么我的应用程序将无法运行。轮询 1/2 秒是过多还是过少?只是想知道我的整个想法是否好?

非常感谢,

【问题讨论】:

  • 除此之外,请不要使用这样的 if 语句。将代码的最后 8 行更改为:“return pingStatus.Status == IPStatus.Success;”
  • 很遗憾,我没有给你一个好的答案,但你可能不想每 0.5 秒 ping 一个站点,你最终可能会被阻止。
  • 如果您选择任意主机,我也建议您尝试一组主机。 www.google.com、www.live.com、www.yahoo.com 等。只有在所有 3 个都失败时才通知用户。如果用户和谷歌之间的路由器出现故障,但他们仍在互联网上,您不想错误地提醒他们他们的连接已断开。
  • 为什么你的逻辑不是: ConnectToMyServer() if (fail) { PingGoogle() } if (GooglePingFailed) 然后提醒用户为什么它失败了?或者代替ping,使用Http ...很常见的是所有端口都被阻止但80出。

标签: c# networking


【解决方案1】:

为什么要 ping 谷歌?你真正关心的唯一服务器是你想与之交谈的网络服务器,对吧?所以 ping 那个。这样,如果用户与 Web 服务器之间有任何问题,您可以通知用户 - 这是唯一重要的事情。

如果互联网出现问题,这意味着用户只能在自己的城镇内做任何事情,您可能无法访问 Google,但如果您仍然可以访问您感兴趣的网络服务器,为什么要报告问题?另一方面,如果网络服务器出现故障但 Google 没有,您为什么想告诉用户有问题?

同样,为什么要使用 ping?为什么不向 Web 服务器上的已知 URL 发送 HTTP 请求?毕竟,如果网络正常,但 Web 服务器进程本身已关闭,那肯定与用户的网络出现故障一样糟糕。

编辑:我没有注意到你每半秒重复一次这个问题。这对任何人来说都不是一件愉快的事。当然,一分钟一次就足够了,不是吗?

【讨论】:

  • 如果对服务器的 ping 失败,请 ping Google。这样他就可以判断用户是否在网络上,但服务器已关闭。
  • 出于安全原因,网络服务器上已禁用 ping (icmp)。我确实创建了一个套接字来测试端口号上的 Web 服务器。但是,响应速度很慢。
  • 哪个端口?当然,您唯一关心的是侦听网络请求的那个。
【解决方案2】:

查看这个重复的问题,它有一个不需要 ping 的好答案:

C# - How do I check for a network connection

您可以订阅 System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged 事件,然后仅当它指示网络已关闭时才向服务器发出 ping/web 请求以查看它是否可用。

【讨论】:

    【解决方案3】:

    我可能遗漏了一些东西,但是,为什么您需要在需要使用它之前测试服务器是否已启动并且 Web 服务正在运行?如果您在 Web 服务中调用某个方法并且没有得到及时响应,那么请采取您认为合适或需要的任何操作?

    这似乎只是设计的工程。

    [编辑]

    感谢 robUK 的澄清。您应该收听 NET Rocks 播客剧集“Udi Dahan Scales Web Applications!” (日期 12/08/2008)。他们讨论了向请求添加 GUID 并等到您在响应中获得相同的 GUID。也许您可以每秒触发一次,例如 10 次尝试,如果您在 10 次尝试后没有得到响应(附带 GUID),那么请采取所需的操作?

    祝你好运……

    【讨论】:

    • 你好。该应用程序需要一直监控以防发生某些事情,并且我的应用程序需要采取适当的措施。我已经测试过ping google。但我认为现在这不是一个好主意。好像 ping 只失败一次,记住我每隔几秒就 ping 一次。然后应用程序会认为 Internet 连接已丢失并采取措施。
    【解决方案4】:

    我有一个应用需要做类似的事情。我们有一些不同的架构,即发布/订阅消息总线。对于那些有兴趣听到来自各种服务的“心跳”的应用程序,我们允许他们在总线上注册他们的兴趣。每隔几秒钟左右,每个服务都会发布一条健康状态消息,然后消费者将收到该消息。如果消费者在一定时间内没有收到健康状态消息,他们可以采取适当的措施,直到再次听到。

    这种设置比轮询服务器甚至更糟糕的 ping 它更具可扩展性。想象一下,如果您有 100 或 1000 个客户端每隔几秒就轮询或 ping 您的服务器。不好。

    【讨论】:

    • 不是真的...如果您获取 Juval 兄弟的示例代码 (msdn.microsoft.com/en-us/magazine/cc163537.aspx),您可以快速运行一个管道模型。我们运行 OTOH 的服务非常复杂。 :)
    • 是的,你是对的。让所有这些客户 ping 一个网站是个坏主意。但是,我以前从未这样做过,因此正在寻找不同的方法来做到这一点。我刚刚快速浏览了这篇文章。我认为客户将订阅该服务是否正确。如果 Web 服务器出现故障,该服务将回调到客户端以通知他们。这方面还有其他文章吗?我猜双工是如果客户端出线,那么可以向服务发送回调。
    • 当然。 ESB 上有很多很棒的东西,例如esb.codeplex.com。当然,您并没有实现整个 ESB 模式。但是,作为 ESB 一部分的一些概念正是您想要做的。
    【解决方案5】:

    你可以像这样简单地测试

    [DllImport("wininet.dll")]
    private extern static bool InternetGetConnectedState(out int conn, int val);
    

    C#完整源代码

    http://net-informations.com/csprj/communications/internet-connection.htm

    【讨论】:

    • 我不会相信这种方法。出于某种原因,即使 LAN 控制器被禁用(Windows 8.1 x64),此方法也会返回 true
    【解决方案6】:

    建议设置超过 0.5 秒,因为有时您的延迟会变长。我有时在 DSL 上甚至有 3.5 秒。

    【讨论】:

      【解决方案7】:

      最好看看你是否在网络上,而不是打扰服务器 ping 它。例如,请参阅Detect Internet V. local lan connection。如果您使用的是 Windows 7 / Server 2008 R2,您可以在连接发生变化时收到一个事件,这对每个人来说都比不断的 ping 和轮询要快乐得多。

      【讨论】:

        【解决方案8】:

        尽管我同意 Jon 的观点,ping 您的网络服务器可能是最好的想法,但我想提出另一个解决方案,该解决方案可以单独使用,也可以与服务的初始 ping 一起使用。

        这些是 NetworkChange 类中的一个内置事件,称为 NetworkAvailabilityChanged,无论您是否在线,您都可以使用它从 Windows 获取整体状态。只需为其添加一个侦听器,然后当它发生更改时您会收到通知。

        private void MyForm_Load(object sender, EventArgs e)
        {
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        }
        
        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            if (e.IsAvailable)
            {
                WriteLog("Network is available again, updating items");
                timer1_Tick(sender, EventArgs.Empty);
                return;
            }
        
            WriteLog("Network isn't available at the moment");
        }
        

        它适用于 .Net 2.0 及更高版本。更多信息可以在MSDN找到。

        【讨论】:

          猜你喜欢
          • 2018-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-17
          • 1970-01-01
          • 1970-01-01
          • 2020-11-29
          相关资源
          最近更新 更多