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


当前回答

简介

在某些情况下,您需要在windows应用程序中使用c#代码检查internet是否可用。可能是在windows窗体中使用internet下载或上传文件,或从远程位置的数据库中获取一些数据,在这些情况下,internet检查是强制性的。

有一些方法可以从后面的代码中使用c#检查internet的可用性。这里解释了所有这些方法,包括它们的局限性。

InternetGetConnectedState(经由wininet)

“wininet”API可以用来检查本地系统是否有活跃的互联网连接。用于此操作的命名空间是'System.Runtime。并使用DllImport导入dll' wininet.dll'。在此之后,创建一个带有extern static的布尔变量,函数名为InternetGetConnectedState,带有两个参数描述和reservedValue,如示例所示。

注意:extern修饰符用于声明外部实现的方法。当您使用Interop服务调用非托管代码时,extern修饰符的常见用法是与DllImport属性一起使用。在这种情况下,方法也必须声明为静态的。

接下来创建一个名称为“IsInternetAvailable”的布尔方法。的 上面的函数将用于这个返回Internet的方法 本地系统状态

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
public static bool IsInternetAvailable()
{
    try
    {
        int description;
        return InternetGetConnectedState(out description, 0);
    }
    catch (Exception ex)
    {
        return false;
    }
}

GetIsNetworkAvailable

下面的示例使用GetIsNetworkAvailable方法来确定网络连接是否可用。

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    System.Windows.MessageBox.Show("This computer is connected to the internet");
}
else
{
    System.Windows.MessageBox.Show("This computer is not connected to the internet");
}

备注(根据MSDN):如果任何网络接口被标记为“向上”且不是环回或隧道接口,则网络连接被认为是可用的。

There are many cases in which a device or computer is not connected to a useful network but is still considered available and GetIsNetworkAvailable will return true. For example, if the device running the application is connected to a wireless network that requires a proxy, but the proxy is not set, GetIsNetworkAvailable will return true. Another example of when GetIsNetworkAvailable will return true is if the application is running on a computer that is connected to a hub or router where the hub or router has lost the upstream connection.

在网络上Ping一个主机名

Ping和PingReply类允许应用程序通过从主机获得回复来确定是否可以通过网络访问远程计算机。这些类可以在System.Net.NetworkInformation命名空间中找到。以ping主机为例。

protected bool CheckConnectivity(string ipAddress)
{
    bool connectionExists = false;
    try
    {
        System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
        System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
        options.DontFragment = true;
        if (!string.IsNullOrEmpty(ipAddress))
        {
            System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
            connectionExists = reply.Status == 
System.Net.NetworkInformation.IPStatus.Success ? true : false;
        }
    }
    catch (PingException ex)
    {
        Logger.LogException(ex.Message, ex);
    }
    return connectionExists;
}

Remarks (As per MSDN): Applications use the Ping class to detect whether a remote computer is reachable. Network topology can determine whether Ping can successfully contact a remote host. The presence and configuration of proxies, network address translation (NAT) equipment, or firewalls can prevent Ping from succeeding. A successful Ping indicates only that the remote host can be reached on the network; the presence of higher level services (such as a Web server) on the remote host is not guaranteed.

欢迎发表意见和建议。编码……快乐!

其他回答

以下是它在Android中的实现方式。

作为概念的证明,我将这段代码翻译成c#:

var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
    {
        //Connection to internet available
    }
    else
    {
        //Connection to internet not available
    }
}
public static bool Isconnected = false;

public static bool CheckForInternetConnection()
{
    try
    {
        Ping myPing = new Ping();
        String host = "google.com";
        byte[] buffer = new byte[32];
        int timeout = 1000;
        PingOptions pingOptions = new PingOptions();
        PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
        if (reply.Status == IPStatus.Success)
        {
            return true;
        }
        else if (reply.Status == IPStatus.TimedOut)
        {
            return Isconnected;
        }
        else
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }
}

public static void CheckConnection()
{
    if (CheckForInternetConnection())
    {
        Isconnected = true;
    }
    else
    {
        Isconnected = false;
    }
}

根据@ChaosPandion的回答,为了尽可能确保结果是正确的,你可以像其他人指出的那样,包括多个大网站。但是,这应该异步完成,以避免太长的等待时间。此外,WebRequest、HttpWebRequest和HttpWebResponse类现在已经过时,应该被HttpClient取代。以下示例考虑了上述因素:

public static async Task<bool> CheckForInternetConnection(TimeSpan? timeoutMs = null, List<string> urls = null)
{
    if (timeoutMs == null)
    {
        timeoutMs = TimeSpan.FromSeconds(10);
    }

    var culture = CultureInfo.InstalledUICulture;
    if (urls == null)
    {
        urls = new List<string>();

        if (culture.Name.StartsWith("fa"))      // Iran
            urls.Add("http://www.aparat.com");
        else if (culture.Name.StartsWith("zh")) // China
            urls.Add("http://www.baidu.com");
        else
        {
            urls.Add("https://www.apple.com/");
            urls.Add("https://www.gstatic.com/generate_204");
        }
    }

    var client = new HttpClient();
    client.Timeout = (TimeSpan)timeoutMs;
    List<Task<string>> tasks = new List<Task<string>>();
    int unresponsiveUrlCount = 0;

    foreach (var url in urls)
    {   
        tasks.Add(client.GetStringAsync(url));             
    }

    Task aggregationTask = null;
    try
    {
        aggregationTask = Task.WhenAll(tasks);
        await aggregationTask;
    }
    catch (Exception)
    {  
        if (aggregationTask?.Exception?.InnerExceptions != null && aggregationTask.Exception.InnerExceptions.Any())
        {
            foreach (var innerEx in aggregationTask.Exception.InnerExceptions)
            {
                unresponsiveUrlCount++;
            }
        }      
    }

    return unresponsiveUrlCount < urls.Count;
}

该方法检查列表中的所有url,如果它们都不可访问,则返回false。我已经添加了苹果的url,因为在我的情况下,它加载相当快,但它可以替换为任何url。

我有三个网络连接测试。

参考系统。Net和system.net.socket 增加以下测试功能:

测试1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试3

public bool IsOnlineTest3()
{
    System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
    System.Net.WebResponse resp = default(System.Net.WebResponse);
    try
    {
        resp = req.GetResponse();
        resp.Close();
        req = null;
        return true;
    }
    catch (Exception ex)
    {
        req = null;
        return false;
    }
}

执行测试

如果您创建了一个名为CheckList的字符串和布尔字典,则可以将每个测试的结果添加到CheckList中。

现在,递归遍历每个KeyValuePair使用for…每一个循环。

如果检查表的值为true,则您知道有Internet连接。

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

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