在。net中检查Internet连接的最快和最有效的方法是什么?


当前回答

另一种选择是网络列表管理器API,它适用于Vista和Windows 7。MSDN文章在这里。在本文中有一个下载代码示例的链接,允许您这样做:

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

请确保从COM选项卡中添加对网络列表1.0类型库的引用…它将显示为NETWORKLIST。

其他回答

public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null)
{
    try
    {
        url ??= CultureInfo.InstalledUICulture switch
        {
            { Name: var n } when n.StartsWith("fa") => // Iran
                "http://www.aparat.com",
            { Name: var n } when n.StartsWith("zh") => // China
                "http://www.baidu.com",
            _ =>
                "http://www.gstatic.com/generate_204",
        };

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.KeepAlive = false;
        request.Timeout = timeoutMs;
        using (var response = (HttpWebResponse)request.GetResponse())
            return true;
    }
    catch
    {
        return false;
    }
}

我个人觉得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));
}

接受的答案很快就成功了,但当没有连接时,失败的速度非常慢。所以我想建立一个健壮的连接检查,它会更快地失败。

据说不是所有环境都支持ping,所以我从接受的答案开始,并从这里添加了一个带有自定义超时的WebClient。你可以选择任何超时,但3秒对我来说是通过wifi连接的。我尝试添加一个快速迭代(1秒),如果第一个迭代失败,则添加一个缓慢迭代(3秒)。但是这没有意义,因为这两个迭代总是失败(当没有连接时)或总是成功(当连接时)。

我正在连接AWS,因为我想在连接测试通过时上传一个文件。

public static class AwsHelpers
{
    public static bool GetCanConnectToAws()
    {
        try
        {
            using (var client = new WebClientWithShortTimeout())
            using (client.OpenRead("https://aws.amazon.com"))
                return true;
        }
        catch
        {
            return false;
        }
    }
}

public class WebClientWithShortTimeout: WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        var webRequest = base.GetWebRequest(uri);
        webRequest.Timeout = 5000;
        return webRequest;
    }
}

另一种选择是网络列表管理器API,它适用于Vista和Windows 7。MSDN文章在这里。在本文中有一个下载代码示例的链接,允许您这样做:

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

请确保从COM选项卡中添加对网络列表1.0类型库的引用…它将显示为NETWORKLIST。

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

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 可以防止缓存。