使用C#检查互联网连接是否可用

26

最简单的方法是通过编程来检查互联网连接是否可用?

编辑: 如建议所示,我尝试使用以下方法,但它始终返回true。

[Flags]
enum InternetConnectionState : int
{
    INTERNET_CONNECTION_MODEM = 0x1,
    INTERNET_CONNECTION_LAN = 0x2,
    INTERNET_CONNECTION_PROXY = 0x4,
    INTERNET_RAS_INSTALLED = 0x10,
    INTERNET_CONNECTION_OFFLINE = 0x20,
    INTERNET_CONNECTION_CONFIGURED = 0x40
}

class Program
{
    [DllImport("WININET", CharSet = CharSet.Auto)]
    static extern bool InternetGetConnectedState(ref InternetConnectionState lpdwFlags, int dwReserved);

static void Main(string[] args)
{
    InternetConnectionState flags = 0;
    bool isConnected = InternetGetConnectedState(ref flags, 0);
    Console.WriteLine(isConnected);
    //Console.WriteLine(flags);
    Console.ReadKey();
}
}

补充信息(如果有帮助):我通过共享的 wifi 网络访问互联网。


1
我不确定哪个API处理它,但在Windows Vista及以上版本中实际上验证了您与互联网的连接。我相信这些信息是通过API公开的,因此,如果您正在寻找在Vista和即将推出的Windows 7下最有效的解决方案,那么您需要的就是该API,如果您或其他人能够找出它是哪一个。 - jasonh
编辑了问题,包含了建议解决方案的结果。对我来说没有起作用,请帮忙。谢谢! - Michell
1
我也曾经遇到过同样的问题。尝试了不同的解决方案,但卡在了同一个地方! - blitzkriegz
1
InternetGetConnectedState只是链中的第一个测试 - 它旨在告诉您是否连接了拨号连接(如果您正在使用拨号连接)。如果您有局域网连接,它几乎总是返回true。如果您从InternetGetConnectedState获得true,则可以继续进行其他测试,例如检查是否可以进行名称解析,是否可以访问要连接到的主机(使用最终将使用的端口和协议)等。请参见我下面的答案。 - KristoferA
可能是如何检查网络连接?的重复问题。 - T.Todua
9个回答

21

这里有你可以调用的Windows API。它在wininet.dll中,名为InternetGetConnectedState

using System;
using System.Runtime;
using System.Runtime.InteropServices;

public class InternetCS
{
    //Creating the extern function...
    [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 ) ;
    }
}

1
@colithium:在参数声明之前应该使用refoutint out是无效的。 - Mehrdad Afshari
1
@Michell:现在应该可以编译了。当然,你需要添加一个“Main”方法。 - Mehrdad Afshari
是的,谢谢。我重新格式化了我链接的代码,但是错过了那个。 - colithium
4
如果你在使用拨号连接,那这个工具可以很好地检查网络的连接或断开状态。但如果你在使用局域网连接,它可能会给出错误的判断。 - KristoferA
3
这个函数的MSDN页面显示它返回像INTERNET_CONNECTION_LAN、INTERNET_CONNECTION_MODEM和INTERNET_CONNECTION_PROXY这样的标志,它们的描述中说“本地系统使用x连接到互联网”。同时,它也说明:“InternetGetConnectedState返回TRUE表示至少有一个连接可用于访问互联网。” - colithium
显示剩余3条评论

10

这是我迄今发现的最佳解决方案:

public static bool isConnected()
    {
        try
        {
            string myAddress = "www.google.com";
            IPAddress[] addresslist = Dns.GetHostAddresses(myAddress);

            if (addresslist[0].ToString().Length > 6)
            {
                return true;
            }
            else
                return false;

        }
        catch
        {
            return false;
        }

    }

用法:

if(isConnected())
{
    //im connected to the internet
}
else
{
    //not connected
}

但是如果谷歌忘记续订他们的域名注册呢? ;) - ColinM
这在代理后无法工作,我相信GetInternetConnectedState可以。 - Philip Johnson

10

微软的Windows Vista和7使用NCSI(网络连接状态指示器)技术:

NCSI对www.msftncsi.com进行DNS查找,然后请求http://www.msftncsi.com/ncsi.txt。这个文件是一个纯文本文件,仅包含文本“Microsoft NCSI”。 NCSI发送了一个DNS查找请求以获取dns.msftncsi.com。这个DNS地址应该解析为131.107.255.255。如果地址不匹配,则假定互联网连接未正常工作。


2
这是这里最好的答案。而其他答案仅仅不能提供准确的结果(特别是System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()),而其他答案只检查DNS(你的DNS服务器可能已经宕机,但你仍然有互联网连接),NCSI方法首先检查DNS,如果失败,则尝试直接通过IP地址连接,以便确定您的互联网是否真的断开或者只是DNS宕机。请参阅http://technet.microsoft.com/en-us/library/ee126135%28v=WS.10%29.aspx - public wireless

7
您可以在 .NET 2.0+ 中使用以下方法检查网络连接。
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

这可能只会在本地网络中返回true,所以对于您可能无效。


2
MSDN:“如果任何网络接口被标记为“up”且不是环回或隧道接口,则认为存在网络连接。”因此,它并不能保证网络连接是连接到互联网的连接。尽管如此,仍然很有用。 - colithium
程序员通常会在应用程序可能挂起或崩溃之前检查特定服务/主机是否可用,然后启动其他例程。因此,可以使用“ping”方法或“dns”方法(ping响应可能关闭-没有完美的解决方案)。 - TomeeNS

6
这是一个答案完全取决于“情况而定”的问题。因为这取决于您想要检查什么样的连接以及出于什么目的?您想通过http访问某些网站/服务吗?发送smtp邮件?进行dns查询?
最好使用colithium的答案中提供的wininet api组合来检查是否有任何类型的连接。
如果有,尝试一些dns查询(请参阅System.Net.Dns)以获取您感兴趣的资源或一些热门大型网站(如google、altavista、compuserve等)。
接下来,您可以尝试ping(请参阅Roger Willcocks的答案)和/或建立到相同站点的套接字连接。请注意,失败的ping可能只意味着防火墙规则不允许您ping。
如果您能更具体地说明为什么要检查,那么就更容易提供涵盖您要求的答案...

1
我认为这就是我们所有答案汇聚的地方,所以+1。 - colithium

4

最简单的方法可能是检查他们是否能够从网上下载一个你知道可用的文件。使用以下代码下载Google的主页。

WebClient Client = new WebClient ();
String Response;
Response = Client.DownloadString("http://www.google.com");

当无法建立连接时,您应该将其包装在Try .... Catch中以捕获抛出的异常。


7
如果谷歌出了问题怎么办? 吃惊 - colithium
4
Windows Vista会通过ping Microsoft.com来检查您是否连接了互联网,以查看是否能获得响应。这并没有太大的区别 :P - Sekhat
4
谢谢Killersponge,正是我所想的。必须向某个外部服务器发送一些请求,否则,你怎么确切地知道你已经连接到互联网?你怎么知道你的DNS服务器是否可用?你怎么知道所有的东西都正常运作?我认为我的回答可能不是最好的,但也不认为应该被评为-4分。嗯,可能随着时间的推移,这个回答会被修改,所以我现在就把它留下了。我仍然认为这种方法比调用Windows API更好(跨平台可用,Mono环境下也适用)。 - Kibbee
1
+1,快速简单的测试。为了更高的粒度,可以将其分解为单独的测试,但这是一个很好的快速测试,以确保您具有HTTP连接性。如果您想通过代理允许HTTP连接,请将代理设置为默认代理... - KristoferA
1
+1 这是最可靠的方式!不知道为什么会被踩! - softwarematter
显示剩余3条评论

2

0

或者您可以使用DNS查找来检查互联网连接。这种方法比Ping方法更快。

public static bool DnsTest()
    {
        try
        {
            System.Net.IPHostEntry ipHe =
                System.Net.Dns.GetHostByName("www.google.com");
            return true;
        }
        catch
        {
            return false;
        }
    }

0

还有其他选项。

InfoPath库公开了"IsDestinationReachable"方法,它是同名Win API方法的包装器。(看起来Vista不支持它)

然而,我相信从文档中可以看出它依赖于类似PING的东西,所以不一定是一个好的测试。

Vista+使用"Network List Manager"

@colithium Google可能没有崩溃,但如果DNS查找间隔超过超时时间,事情也会失败。在新西兰家里很常见,第一次尝试失败,第二次成功,因为数据已经通过第二个请求返回到ISP DNS或路由器缓存。


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