C# 测试活动的互联网连接。Ping Google.com。

16

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

我认为唯一测试互联网连接的方法是ping www.google.com。所以我使用了一个服务器定时器,将其设置为500毫秒,并在流逝事件中调用此ping函数。如果ping返回false,则我的应用程序将采取适当的措施。

您认为使用google作为测试互联网连接的方法是否好。如果google失败,那么我的应用程序将无法正常工作。每隔半秒轮询是否太多或太少?只是想知道我的整个想法是否好。

非常感谢。


12
除此之外,请不要像那样使用if语句。请将您代码的最后8行更改为:"return pingStatus.Status == IPStatus.Success;" - Jon Skeet
3
很不幸,我没有一个好的答案给你,但你可能不希望每0.5秒就Ping一个网站,否则你可能会被屏蔽。 - Andy White
为什么不这样写逻辑:ConnectToMyServer(),如果失败了就PingGoogle(),如果GooglePingFailed,则向用户发出警报说明失败原因?或者可以使用Http而不是ping,因为通常所有端口都被阻止,但80端口是开放的。 - Chad Grant
8个回答

25
为什么要ping谷歌?你真正关心的只是你想要与之通信的网络服务器,对吧?那就直接ping它。这样,如果用户和网络服务器之间有任何问题,你就可以通知用户 - 这是唯一重要的事情。
如果出现了与互联网相关的问题,意味着用户只能在自己的城镇内进行操作,你可能无法访问谷歌,但如果你仍然可以访问感兴趣的网络服务器,为什么要报告问题呢?另一方面,如果网络服务器崩溃了,而谷歌没有崩溃,为什么不告诉用户存在问题呢?
同样地,为什么要使用ping?为什么不向已知URL的网络服务器发送HTTP请求呢?毕竟,如果网络正常,但网络服务器进程本身崩溃了,那肯定和用户的网络崩溃一样糟糕。
编辑:我没有注意到问题中你每隔半秒就会重复这个过程。这对任何人来说都不太好。一分钟一次肯定够频繁了,不是吗?

6
如果服务器的ping测试失败,可以尝试对Google进行ping测试。这样就能判断用户是否已连接至互联网,但服务器出现问题了。 - Jonathan C Dickinson
出于安全考虑,Web服务器上已禁用ping(icmp)。我创建了一个套接字来测试端口号上的Web服务器。然而,它响应非常缓慢。 - ant2009
1
哪个端口呢?你唯一关心的是监听网络请求的那个端口,对吧。 - Jon Skeet

6

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

C# - 如何检查网络连接

您可以订阅 System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged 事件,只有在它指示网络已断开时才进行ping/web请求以查看服务器是否可用。


2

1
我不会信任这个方法。由于某种原因,即使 LAN 控制器被禁用(Windows 8.1 x64),该方法仍会返回“true”。 - itsho

2
我可能漏掉了什么,但是为什么在需要使用它之前要测试服务器是否正常运行和Web服务是否运行?如果调用Web服务中的方法并且没有得到及时响应,则采取任何您认为合适或需要的操作即可。这似乎是设计上过度工程化了。
[编辑]
感谢robUK的澄清。您应该收听NET Rocks播客第“Udi Dahan Scales Web Applications!”(日期为2008年12月08日)。他们讨论将GUID添加到请求中,并等待在响应中获得相同的GUID。也许您可以每秒钟发出一次请求,尝试10次,如果在10次尝试后没有收到带有GUID的响应,则采取所需的操作?
祝你好运。

你好。这个应用程序需要一直监控以防发生任何事情,然后我的应用程序必须采取适当的行动。我已经测试了向谷歌发送ping请求,但现在我认为这不是一个好主意。因为如果ping请求失败了一次,记住我每隔几秒钟就会发送一次ping请求,那么应用程序将认为互联网连接已经丢失并采取行动。 - ant2009

2
我有一个需要完成类似任务的应用程序。我们采用了不同的架构,即发布/订阅消息总线。对于那些希望听到各种服务“心跳”的应用程序,我们允许它们在总线上注册感兴趣的内容。每隔几秒钟,每个服务都会发布一个健康状态消息,然后消费者将接收到这些消息。如果消费者在一定时间内没有接收到健康状态消息,则可以采取适当的措施,直到再次收到为止。
与轮询服务器或更糟糕的 Ping 相比,此设置要可扩展得多。想象一下,如果您有 100 或 1000 个客户端每隔几秒钟轮询或 ping 您的服务器,就会很糟糕。

不是很难...如果你获取Juval兄弟的示例代码(http://msdn.microsoft.com/en-us/magazine/cc163537.aspx),你可以很快地运行一个模拟的管道。另一方面,我们运行的服务非常复杂。 :) - JP Alioto
是的,你说得对。让所有客户端都向一个网站发送请求是个坏主意。然而,我以前从未做过这件事,所以正在寻找不同的方法来解决这个问题。我只是快速浏览了一下文章。如果我理解正确,客户端将订阅该服务。如果 Web 服务器宕机,服务将回调客户端通知他们。还有其他相关文章吗?我想双工通信是指如果客户端离线,则可以向服务发送回调。 - ant2009
当然。ESB上有很多好东西,例如http://esb.codeplex.com/。当然,您不是在实现整个ESB模式。但是,您正在尝试实现ESB的一些概念。 - JP Alioto

1
最好检查一下你是否在网络上,而不是打扰服务器进行ping测试。例如,请参见检测互联网与本地局域网连接。如果你使用的是Windows 7 / Server 2008 R2,当连接发生变化时,你可以获得一个事件,这对于每个人来说都比持续ping测试和轮询更加愉快。

1
建议将时间设置为0.5秒以上,因为有时您的延迟可能会更高。我在DSL上有时甚至达到3.5秒。

0
尽管我同意 Jon 的看法,即ping您的Web服务器可能是最好的主意,但我想提出另一个解决方案,可以单独使用或与对服务的初始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 上找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接