如何使用 .NET、C# 和 WPF 检查 Internet 连接

Posted

技术标签:

【中文标题】如何使用 .NET、C# 和 WPF 检查 Internet 连接【英文标题】:How to check the Internet connection with .NET, C#, and WPF 【发布时间】:2011-03-23 13:24:48 【问题描述】:

我正在使用 .NET、C# 和 WPF,我需要检查是否打开了到某个 URL 的连接,但我在 Internet 上找到的任何代码都无法运行。

我试过了:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try

    IAsyncResult result = socket.BeginConnect("localhost/myfolder/", 80, null, null);
    bool success = result.AsyncWaitHandle.WaitOne(3000, true);
    if (!success)
    
        MessageBox.Show("Web Service is down!");
    
    else
        MessageBox.Show("Everything seems ok");

finally

    socket.Close();

但即使我关闭了本地 Apache 服务器,我总是会收到一切正常的消息。

我也试过了:

ing ping = new Ping();
PingReply reply;
try

    reply = ping.Send("localhost/myfolder/");
    if (reply.Status != IPStatus.Success)
        MessageBox.Show("The Internet connection is down!");
    else
        MessageBox.Show("Seems OK");

catch (Exception ex)

    MessageBox.Show("Error: " + ex.Message);

但这总是会出现异常(ping 似乎只能 ping 服务器,所以 localhost 有效,但 localhost/myfolder/ 没有)

请问如何检查连接以便它对我有用?

【问题讨论】:

您是否正在尝试验证您的连接是否正常(在这种情况下 Ping 可以工作),或者某个 URL 是否可以访问? 您是否只需要检查 Internet 连接是否已启动,或者您的特定 Web 服务是否已启动并正在运行?它们可能是两种不同的东西。 某个特定的 Web 服务已启动并正在运行 您只是在检查连接是否最终结束。 您打算使用什么样的网络服务?我怀疑是否有一种通用方法可以检查所有 Web 服务类型 【参考方案1】:

许多开发人员只是通过 ping Google.com 来解决这个“问题”。好吧...? :/ 这在大多数 (99%) 情况下都有效,但是将您的应用程序的工作依赖于某些外部 Web 服务有多专业?

有一个非常有趣的 Windows API 函数称为InternetGetConnectedState(),而不是 ping Google.com,它可以识别您是否可以访问 Internet。

针对这种情况的解决方案是:

using System;
using System.Runtime;
using System.Runtime.InteropServices;
 
public class InternetAvailability

    [DllImport("wininet.dll")]
    private extern static bool InternetGetConnectedState(out int description, int reservedValue);
 
    public static bool IsInternetAvailable( )
    
        int description;
        return InternetGetConnectedState(out description, 0);
    

【讨论】:

在一个测试案例中,我正在通过代理并且代理已关闭并且没有加载浏览器页面,但在技术上没有可用的互联网时,上述方法仍然返回 true。所以这个解决方案不是正确的。我正在使用上述组合并连接到我的服务:) 所有windows版本都存在“wininet.dll”吗? @user2048060 "wininet.dll" 存在除Windows XP and Windows Server 2003 R2 and earlier 之外的所有 Windows 版本 阅读更多:msdn.microsoft.com/en-us/library/windows/desktop/… @AnantDabhi 感谢您的资源。此外,我还发现这个函数msdn.microsoft.com/en-us/library/windows/desktop/… 完全符合 Rowan 所说的。如果需要,您也可以将其添加到您的回复中。 如果我想在网络中断时举办活动怎么办【参考方案2】:

最后我使用了自己的代码:

private bool CheckConnection(String URL)

    try
    
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
        request.Timeout = 5000;
        request.Credentials = CredentialCache.DefaultNetworkCredentials;
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();

        if (response.StatusCode == HttpStatusCode.OK)
            return true;
        else
            return false;
    
    catch
    
        return false;
    

有趣的是,当服务器关闭时(我关闭了我的 Apache),我没有收到任何 HTTP 状态,但会引发异常。但这已经足够好了:)

【讨论】:

如果您想检查您的 HTTP 状态,请获取 WebException 异常并查看 Status 属性。还有一个项目叫做TimeOut 最后,你可以这样做:return (response.StatusCode == HttpStatusCode.OK); 我使用了这种方法,即使我已经连接了互联网并且网站没有问题,大多数时候都会返回 false【参考方案3】:

你可以试试这个;

private bool CheckNet()

    bool stats;
    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() == true)
    
        stats = true;
    
    else
    
        stats = false;
    
    return stats;

【讨论】:

+1 因为它将我指向 NetworkInterface 类。但是,如果 network 已启动但 internet access 已关闭,我认为这不会起作用... 如果我想在它开启和关闭时得到通知怎么办? 这不会检查互联网连接,而只是检查网卡状态【参考方案4】:

使用这个:

private bool CheckConnection()

    WebClient client = new WebClient();
    try
    
        using (client.OpenRead("http://www.google.com"))
        
        
        return true;
    
    catch (WebException)
    
        return false;
    

【讨论】:

虽然可行,但它不正确,因为我们仍然依赖于网站而不是 PC 的互联网连接。 我已经使用了很多年了,但是当我们的一位开发人员被锁在谷歌之外时遇到了一个问题,因为他/她在一小时内向谷歌发送了超过 5000 个请求,这标记了应用程序作为拒绝服务攻击。【参考方案5】:

我认为这在涉及 windows 应用程序、Windows 窗体或 WPF 应用程序时会更准确,而不是使用 WebClient 或 HttpWebRequest,

public class InternetChecker

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

    //Creating a function that uses the API function...
    public static bool IsConnectedToInternet()
    
        int Desc;
        return InternetGetConnectedState(out Desc, 0);
    


在调用 write 时

if(InternetCheckerCustom.CheckNet())

  // Do Work 

else

  // Show Error MeassgeBox 

【讨论】:

【参考方案6】:

我浏览了所有解决方案。 NetworkInterface.GetIsNetworkAvailable() 不检查互联网连接。它只检查是否有任何网络连接可用。

Ping 不可靠,因为许多网络 ping 已关闭。使用 webclient 连接到 google 也不是 100% 可靠的,如果您过于频繁地使用它也会产生性能开销。

使用Windows NLM API 对我来说似乎是一个更好的解决方案。

using NETWORKLIST;

namespace Network.Helpers

    public class InternetConnectionChecker
    
        private readonly INetworkListManager _networkListManager;

        public InternetConnectionChecker()
        
            _networkListManager = new NetworkListManager();
        

        public bool IsConnected()
        
            return _networkListManager.IsConnectedToInternet;
        
        
    

这是将其添加到项目的方法。

【讨论】:

由于不喜欢 Ping 方法,这让我省了一些麻烦,非常感谢!【参考方案7】:

我们可以使用 ping 来询问吗?

try

    System.Net.NetworkInformation.Ping ping = new Ping();

    PingReply result = ping.Send("www.google.com");

    if (result.Status == IPStatus.Success)
        return true;
     return false;

catch

    return false;

【讨论】:

【参考方案8】:

这里有一个类似于Mahbubur Ra​​hman的解决方案,但是直接使用COM接口而不需要引用Network List Manager 1.0 Type Library

dynamic networkListManager = Activator.CreateInstance(
    Type.GetTypeFromCLSID(new Guid("DCB00C01-570F-4A9B-8D69-199FDBA5723B")));
    
bool isConnected = networkListManager.IsConnectedToInternet;

【讨论】:

以上是关于如何使用 .NET、C# 和 WPF 检查 Internet 连接的主要内容,如果未能解决你的问题,请参考以下文章

C# .Net Framework WPF:如何进行 POST 调用并保存登录 Baerer 密钥?

我可以从后面的 C# 代码更新 WPF 绑定的值吗?

如何使用 WPF 和 .NET 3.5 注册全局热键以说出 CTRL+SHIFT+(LETTER)?

用C#写的WPF在XP系统目标机上运行时闪退。

应用程序使用统计信息 – .NET CORE(C#) WPF界面设计

我们可以检查 Powershell 脚本所需的 Powershell/WPF/.Net 版本吗?