Qual é a melhor maneira de verificar a conectividade com a Internet usando o .NET?

237

Qual é a maneira mais rápida e eficiente de verificar a conectividade da Internet no .NET?

Mohit Deshpande
fonte
6
Se o usuário tiver uma conexão com a Internet. Se o usuário puder se conectar à Internet. Para enviar um log de email.
Mohit Deshpande
11
Basta enviar o email. Se o usuário não estiver conectado, você provavelmente receberá algum tipo de exceção (com a qual provavelmente precisaria lidar de qualquer maneira).
Seth
15
Além disso, observe que não há como verificar se o usuário está conectado à Internet; tudo o que você pode dizer é se eles estavam conectados no passado . Suponha que você tenha um método: "bool c = IsConnected (); if (c) {DoSomething ();}" - entre a chamada para IsConnected e DoSomething, o roteador de rede sem fio pode ter sido desconectado. IsConnected realmente deve ser chamado WasRecentlyConnected.
Eric Lippert
Windows NLM APIdeve ser o melhor para isso. stackoverflow.com/questions/5405895/…
Mahbubur Rahman 8/03

Respostas:

292

Algo assim deve funcionar.

System.Net.WebClient

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
            using (client.OpenRead("http://google.com/generate_204")) 
                return true; 
    }
    catch
    {
        return false;
    }
}
ChaosPandion
fonte
18
Provavelmente, isso é melhor do que executar ping no Google, porque acho que não temos garantia de que o Google continue respondendo a pings. Por outro lado, não posso imagem um mundo onde www.google.com não retornar algum HTML :)
Daniel Vassallo
3
@ Daniel: true por um lado, mas por outro lado, realmente o download do site é uma pequena sobrecarga imo
Leo
9
De qualquer forma, não há razão para recuperar o 4KB - basta usar client.OpenRead (url). Se não lançar uma exceção, poderá conectar-se.
27411 Josh M.
14
Na verdade, isso não é tão eficiente. Usando isso, meu programa inicia mais de um minuto se não houver internet. Provavelmente devido à tentativa de resolver o DNS. O ping 8.8.8.8 (google dns) mudou para 3 segundos.
MadBoy
8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLna China, por exemplo ...
Jérôme MEVEL
84

Não há absolutamente nenhuma maneira que você pode confiavelmente verificar com se há ou não uma conexão à Internet (suponho que você queira dizer acesso à internet).

No entanto, você pode solicitar recursos que nunca estão offline, como pingar google.com ou algo semelhante. Eu acho que isso seria eficiente.

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);
    return (reply.Status == IPStatus.Success);
}
catch (Exception) {
    return false;
}
Leo
fonte
24
+1 "Não há absolutamente nenhuma maneira de verificar com segurança se há uma conexão à Internet"
woz 19/03/13
6
Tudo o que isso faz é verificar se o Google está ativo quando você fez o ping. Se o instante seguinte após seu ping bem-sucedido na Internet cair, e daí? Não faz sentido verificar antes de fazer.
Dbnett
12
E como isso contradiz a afirmação principal da minha resposta?
Leo
10
Usar "google.com" levará mais tempo, pois precisa ser resolvido. Em vez disso, executar ping diretamente usando IP será mais rápido. Fazer ping nos endereços IP do DNS público do Google ( 8.8.8.8ou 8.8.4.4) funciona bem para mim.
Mangesh
8
Eu gostaria de reiterar o ponto que Beware - many schools and offices block the ping protocol.se você estiver usando este método para um aplicativo que será usado por clientes gostaria de aconselhar contra este método de verificação internet
user1
42

Em vez de verificar, basta executar a ação (solicitação da web, email, ftp etc.) e estar preparado para a solicitação falhar, o que você deve fazer de qualquer maneira, mesmo que sua verificação tenha sido bem-sucedida.

Considere o seguinte:

1 - check, and it is OK
2 - start to perform action 
3 - network goes down
4 - action fails
5 - lot of good your check did

Se a rede estiver inativa, sua ação falhará tão rapidamente quanto um ping, etc.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
dbasnett
fonte
9
Certo! Apenas faça - mas esteja preparado para todos os resultados.
Coronel Panic
3
Considere o seguinte: Você precisa Do Something se a rede está em x amout de tempo (por exemplo TraceLog, redefinição de router)
Abir
2
Não é o OP, mas o motivo pelo qual desejo fazer isso é EVITAR O TEMPO DE 100 SEGUNDO PADRÃO se a conectividade com a Internet não estiver disponível. A solicitação HTTP é feita em um encadeamento em segundo plano, portanto, o encadeamento da interface do usuário não está sendo bloqueado, mas meu aplicativo não pode sair até que o encadeamento em segundo plano retorne da solicitação HTTP e termine. Em vez de tentar encontrar algum valor de tempo limite "médio feliz", gostaria de evitar a solicitação completamente se soubesse que a conexão com a Internet estava inoperante.
Scott Smith
2
Meu argumento é que não podemos explicar quando o serviço remoto pode ficar disponível / indisponível. Além disso, e os sites que não respondem a pings?
Dbnett
Outro caso de uso é um verificador on-line que me alertará assim que minha internet voltar ao ar
Ben Philipp
28

NetworkInterface.GetIsNetworkAvailableé muito confiável. Basta ter alguma conexão VMware ou outra LAN e ele retornará um resultado errado. Também sobre o Dns.GetHostEntrymétodo, eu estava preocupado apenas com o fato de o URL de teste estar bloqueado no ambiente em que meu aplicativo será implantado.

Então, outra maneira que eu descobri é usando o InternetGetConnectedStatemétodo Meu código é

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

public static bool CheckNet()
{
     int desc;
     return InternetGetConnectedState(out desc, 0);         
}
Kamran Shahid
fonte
Durante o teste, descobri que InternetGetConnectedState retornou true quando o VMWare player foi instalado (a Internet desconectada). Teve que desativá-lo no Painel de Controle \ Rede e Internet \ Conexões de Rede (VMNet1 e VMNet8).
HockeyJ
Ok Justin Oringer.though Fui verificar isso, mas tem que verificar novamente
Kamran Shahid
2
A melhor abordagem para mim é que, depois disso, ainda verifico minha conectividade de serviço e inicio as rotinas ... Eu só queria evitar exceções.
Wagner Bertolini Junior
4
Este código só verifica se o cabo de rede está ligado.
Hackerman
14

Um teste para conexão à Internet executando ping no Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Jaime Macias
fonte
7
Uma descrição para acompanhar esta resposta seria benéfica para mais pessoas do que apenas o autor original da pergunta.
Boeckm
13
Cuidado - muitas escolas e escritórios bloqueiam o protocolo ping. Bobo, eu sei.
Coronel Panic
Não consigo encontrar a classe ping. Podes ajudar-me, por favor. Estou trabalhando na UWP e as outras formas de passar pelas informações da rede não estão funcionando
iam
12

Discordo das pessoas que afirmam: "Qual é o sentido de verificar a conectividade antes de executar uma tarefa, pois imediatamente após a verificação, a conexão pode ser perdida". Certamente, há um certo grau de incerteza em muitas tarefas de programação que nós, como desenvolvedores, realizamos, mas reduzir a incerteza a um nível de aceitação faz parte do desafio.

Recentemente, me deparei com esse problema ao criar um aplicativo que inclui um recurso de mapeamento vinculado a um servidor de blocos on-line. Essa funcionalidade era para ser desativada quando uma falta de conectividade com a Internet era observada.

Algumas das respostas nesta página foram muito boas, mas causaram muitos problemas de desempenho, como interrupções, principalmente no caso de ausência de conectividade.

Aqui está a solução que acabei usando, com a ajuda de algumas dessas respostas e de meus colegas:

         // Insert this where check is required, in my case program start
         ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
    }

    void CheckInternetConnectivity(object state)
    {
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                webClient.Proxy = null;
                webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                webClient.OpenReadAsync(new Uri("<url of choice here>"));
            }
        }
    }

    volatile bool internetAvailable = false; // boolean used elsewhere in code

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            internetAvailable = true;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                // UI changes made here
            }));
        }
    }
PJRobot
fonte
11

Eu vi todas as opções listadas acima e a única opção viável para verificar se a Internet está disponível ou não é a opção "Ping". A importação [DllImport("Wininet.dll")]e / System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() ou qualquer outra variação da NetworkInterface classe não funciona bem na detecção da disponibilidade da rede. Esses métodos só verificam se o cabo de rede está conectado ou não.

A "opção Ping"

if(Conexão disponível) retorna true

if(A conexão não está disponível e o cabo de rede está conectado) retorna false

if(O cabo de rede não está conectado) Throws an exception

O NetworkInterface

if(Internet está disponível) True

if(A Internet não está disponível e o cabo de rede está conectado) True

if(O cabo de rede não está conectado) retorna false

O [DllImport ("Wininet.dll")]

if(Internet está disponível) True

if(A Internet não está disponível e o cabo de rede está conectado) True

if(O cabo de rede não está conectado) retorna false

Portanto, no caso de [DllImport("Wininet.dll")] e NetworkInterface Não há como saber se a conexão à Internet está disponível.

HackerMan
fonte
Isso não é verdade, importei o Wininet.dll, liguei o cabo de rede e obtive o resultado correto para o cenário de Internet não estar disponível.
Waldemar Gałęzinowski 02/02/19
8

Não resolve o problema de queda de rede entre verificar e executar seu código, mas é razoavelmente confiável

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        // 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)
                select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
    }

    return false;
}
Anton
fonte
Ótima idéia, mas, como você disse, pode não ser perfeita. Você também pode armazenar em cache os bytes enviados / recebidos para futuras verificações. Ainda não é perfeito.
Todd
Este código não funciona. Corrija. Ele verifica apenas se o cabo de rede está conectado ou não.
HackerMan
5

O ping do google.com introduz uma dependência de resolução de DNS. O ping 8.8.8.8 está bom, mas o Google está a vários passos de mim. Tudo o que preciso fazer é executar ping na coisa mais próxima de mim que está na internet.

Eu posso usar o recurso TTL do Ping para executar o ping no salto 1, depois o salto 2, etc., até obter uma resposta de algo que esteja em um endereço roteável; se esse nó estiver em um endereço roteável, estará na internet. Para a maioria de nós, o salto número 1 será nosso gateway / roteador local e o salto número 2 será o primeiro ponto do outro lado da nossa conexão de fibra óptica ou qualquer outra coisa.

Esse código funciona para mim e responde mais rapidamente do que algumas das outras sugestões deste segmento, porque está executando o ping do que estiver mais próximo de mim na internet.

using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Diagnostics;

internal static bool ConnectedToInternet()
{
    const int maxHops = 30;
    const string someFarAwayIpAddress = "8.8.8.8";

    // Keep pinging further along the line from here to google 
    // until we find a response that is from a routable address
    for (int ttl = 1; ttl <= maxHops; ttl++)
    {
        Ping pinger = new Ping();
        PingOptions options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply = null;
        try
        {
            reply = pinger.Send(someFarAwayIpAddress, 10000, buffer, options);
        }
        catch (System.Net.NetworkInformation.PingException pingex)
        {
            Debug.Print("Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: " + pingex.Message);
            return false;
        }

        System.Diagnostics.Debug.Print("Hop #" + ttl.ToString() + " is " + (reply.Address == null ? "null" : reply.Address.ToString()) + ", " + reply.Status.ToString());

        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print("Hop #" + ttl.ToString() + " is " + reply.Status.ToString() + ", hence we are not connected.");
            return false;
        }

        if (IsRoutableAddress(reply.Address))
        {
            System.Diagnostics.Debug.Print("That's routable so you must be connected to the internet.");
            return true;
        }
    }

    return false;
}

private static bool IsRoutableAddress(IPAddress addr)
{
    if (addr == null)
    {
        return false;
    }
    else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
    {
        return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
    }
    else // IPv4
    {
        byte[] bytes = addr.GetAddressBytes();
        if (bytes[0] == 10)
        {   // Class A network
            return false;
        }
        else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
        {   // Class B network
            return false;
        }
        else if (bytes[0] == 192 && bytes[1] == 168)
        {   // Class C network
            return false;
        }
        else
        {   // None of the above, so must be routable
            return true;
        }
    }
}
Jinlye
fonte
4

Veja como isso é implementado no Android.

Como prova de conceito, traduzi esse código para 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
    }
}
brisa
fonte
3
private bool ping()
{
    System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
    System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
    if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
    {                
        return true;
    }
    else
    {                
        return false;
    }
}
Shai Segev
fonte
2

Outra opção é a API do Network List Manager, disponível para o Vista e Windows 7. Artigo MSDN aqui . No artigo, há um link para baixar exemplos de códigos que permitem fazer isso:

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

Certifique-se de adicionar uma referência à Biblioteca de tipos da lista de rede 1.0 na guia COM ... que será exibida como NETWORKLIST.

Gierow
fonte
7
eeeeww. Usando o inferno COM no .net?
jgauffin
@jgauffin Você pode explicar por que evitar o COM no .NET? Comparada às outras soluções que encontrei, a solução COM parece funcionar muito bem.
inexcitus 20/05/19
2

Tente evitar o teste de conexões capturando a exceção. porque realmente esperamos que, às vezes, possamos perder a conexão de rede.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline
Shervin Ivari
fonte
1
De onde vem o NetworkInterface? EDIT: Acho: System.Net.NetworkInformation
inspire_coding
1

Pessoalmente, acho melhor a resposta de Anton e moffeltje , mas adicionei uma verificação para excluir redes virtuais configuradas pelo VMWare e outros.

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));
}
Spegeli
fonte
FYI dos documentos GetIsNetworkAvailable (): uma conexão de rede é considerada disponível se qualquer interface de rede estiver marcada como "ativa" e não for uma interface de loopback ou túnel. Não sei se virtual sempre estará no nome ou na descrição da interface. Isso é padrão?
Mike Cheel
1
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
Hari Prasath
fonte
1
Você pode adicionar informações relacionadas à velocidade e a como isso é melhor do que outras soluções postadas. Isso ajudará sua resposta a responder completamente à pergunta.
Ren
8
O problema com esta opção é que bbainda seria verdade mesmo quando a rede não estiver conectada à Internet.
Halfpastfour.am
2
Embora seja verdade que esta não respondeu diretamente à pergunta, eu acho que ainda é útil para usar GetIsNetworkAvailable como um pré-check antes de tentar executar ping Google etc.
Ben Hughes
3
Este código não informa se a conexão com a Internet está disponível ou não. Se você conectar um cabo de rede sem internet, ele retornará verdadeiro.
HackerMan
1

Versão multiencadeada do ping:

  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Net.NetworkInformation;
  using System.Threading;


  namespace OnlineCheck
  {
      class Program
      {

          static bool isOnline = false;

          static void Main(string[] args)
          {
              List<string> ipList = new List<string> {
                  "1.1.1.1", // Bad ip
                  "2.2.2.2",
                  "4.2.2.2",
                  "8.8.8.8",
                  "9.9.9.9",
                  "208.67.222.222",
                  "139.130.4.5"
                  };

              int timeOut = 1000 * 5; // Seconds


              List<Thread> threadList = new List<Thread>();

              foreach (string ip in ipList)
              {

                  Thread threadTest = new Thread(() => IsOnline(ip));
                  threadList.Add(threadTest);
                  threadTest.Start();
              }

              Stopwatch stopwatch = Stopwatch.StartNew();

              while (!isOnline && stopwatch.ElapsedMilliseconds <= timeOut)
              {
                   Thread.Sleep(10); // Cooldown the CPU
              }

              foreach (Thread thread in threadList)
              { 
                  thread.Abort(); // We love threads, don't we?
              }


              Console.WriteLine("Am I online: " + isOnline.ToYesNo());
              Console.ReadKey();
          }

          static bool Ping(string host, int timeout = 3000, int buffer = 32)
          {
              bool result = false;

              try
              {
                  Ping ping = new Ping();                
                  byte[] byteBuffer = new byte[buffer];                
                  PingOptions options = new PingOptions();
                  PingReply reply = ping.Send(host, timeout, byteBuffer, options);
                  result = (reply.Status == IPStatus.Success);
              }
              catch (Exception ex)
              {

              }

              return result;
          }

          static void IsOnline(string host)
          {
              isOnline =  Ping(host) || isOnline;
          }
      }

      public static class BooleanExtensions
      {
          public static string ToYesNo(this bool value)
          {
              return value ? "Yes" : "No";
          }
      }
  }
Nime Cloud
fonte
0

Eu não acho que é impossível, apenas não é direto.

Eu criei algo assim, e sim, não é perfeito, mas o primeiro passo é essencial: verificar se há alguma conectividade de rede. A API do Windows não faz um ótimo trabalho, então por que não fazer um trabalho melhor?

bool NetworkIsAvailable()
{
    var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    foreach (var item in all)
    {
        if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            continue;
        if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
            continue; //Exclude virtual networks set up by VMWare and others
        if (item.OperationalStatus == OperationalStatus.Up)
        {
            return true;
        }
    }

    return false;
}

É bem simples, mas realmente ajuda a melhorar a qualidade da verificação, especialmente quando você deseja verificar várias configurações de proxy.

Assim:

  • Verifique se há conectividade de rede (faça isso realmente bom, talvez até os logs sejam enviados de volta aos desenvolvedores quando houver falsos positivos para melhorar a função NetworkIsAvailable)
  • Ping HTTP
  • (Percorra as configurações de proxy com HTTP Pings em cada uma)
Todd
fonte
1
@ hackerman este é o primeiro passo não óbvio. Os codificadores podem executar um ping rápido em seu próprio servidor se retornar verdadeiro, como uma segunda etapa. É importante ressaltar que isso fornece uma alternativa ao método API do Windows defeituoso. O resto são detalhes.
Todd
3
Falsificar. Se nenhuma interface de rede estiver ativa, definitivamente não haverá internet. A interface do usuário pode ser atualizada imediatamente, sem demora, sem mais verificações em outros hosts.
Todd
0
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;
    }
}
Salih Alija
fonte
Por favor, comente sua resposta. Respostas com apenas código não são permitidas.
ganchito55
É bastante auto-explicativo, policiar por causa do policiamento?
rola
0

Use o NetworkMonitor para monitorar o estado da rede e a conexão à Internet.

Amostra:

namespace AmRoNetworkMonitor.Demo
{
    using System;

    internal class Program
    {
        private static void Main()
        {
            NetworkMonitor.StateChanged += NetworkMonitor_StateChanged;
            NetworkMonitor.StartMonitor();

            Console.WriteLine("Press any key to stop monitoring.");
            Console.ReadKey();
            NetworkMonitor.StopMonitor();

            Console.WriteLine("Press any key to close program.");
            Console.ReadKey();
        }

        private static void NetworkMonitor_StateChanged(object sender, StateChangeEventArgs e)
        {
            Console.WriteLine(e.IsAvailable ? "Is Available" : "Is Not Available");
        }
    }
}

fonte
Boa idéia, mas verificações de disponibilidade de rede, não disponibilidade de internet
John Demetriou
Esta classe também verifica a disponibilidade da Internet: SourceCode
a coisa é, eu tentei, mas só demitido se nenhuma rede estava disponível
John Demetriou
0

Introdução

Em alguns cenários, é necessário verificar se a Internet está disponível ou não usando o código C # nos aplicativos Windows. Pode ser fazer o download ou upload de um arquivo usando a Internet no Windows Forms ou obter alguns dados do banco de dados que está em local remoto, nessas situações, a verificação da Internet é obrigatória.

Existem algumas maneiras de verificar a disponibilidade da Internet usando C # do código atrás. Todas essas formas são explicadas aqui, incluindo suas limitações.

  1. InternetGetConnectedState (wininet)

A API 'wininet' pode ser usada para verificar se o sistema local tem conexão ativa com a Internet ou não. O espaço para nome usado para isso é 'System.Runtime.InteropServices' e importa a dll 'wininet.dll' usando DllImport. Depois disso, crie uma variável booleana com estática externa com um nome de função InternetGetConnectedState com a descrição de dois parâmetros e o valor reservado, conforme mostrado no exemplo.

Nota: O modificador externo é usado para declarar um método implementado externamente. Um uso comum do modificador externo é com o atributo DllImport quando você está usando os serviços de interoperabilidade para chamar código não gerenciado. Nesse caso, o método também deve ser declarado como estático.

Em seguida, crie um método com o nome 'IsInternetAvailable' como booleano. A função acima será usada neste método que retorna o status da Internet do sistema local

[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;
    }
}
  1. GetIsNetworkAvailable

O exemplo a seguir usa o método GetIsNetworkAvailable para determinar se uma conexão de rede está disponível.

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

Comentários (Conforme MSDN): Uma conexão de rede é considerada disponível se qualquer interface de rede estiver marcada como "ativa" e não for uma interface de loopback ou túnel.

Existem muitos casos em que um dispositivo ou computador não está conectado a uma rede útil, mas ainda é considerado disponível e GetIsNetworkAvailable retornará true. Por exemplo, se o dispositivo que está executando o aplicativo estiver conectado a uma rede sem fio que requer um proxy, mas o proxy não estiver definido, GetIsNetworkAvailable retornará true. Outro exemplo de quando GetIsNetworkAvailable retornará true é se o aplicativo estiver sendo executado em um computador conectado a um hub ou roteador em que o hub ou roteador perdeu a conexão upstream.

  1. Ping em um nome de host na rede

As classes Ping e PingReply permitem que um aplicativo determine se um computador remoto está acessível pela rede, obtendo resposta do host. Essas classes estão disponíveis no espaço para nome System.Net.NetworkInformation. O exemplo a seguir mostra como executar ping em um host.

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

Comentários (Conforme o MSDN): Os aplicativos usam a classe Ping para detectar se um computador remoto está acessível. A topologia de rede pode determinar se o Ping pode entrar em contato com êxito com um host remoto. A presença e configuração de proxies, equipamentos de conversão de endereços de rede (NAT) ou firewalls podem impedir o êxito do ping. Um ping bem-sucedido indica apenas que o host remoto pode ser acessado na rede; a presença de serviços de nível superior (como um servidor da Web) no host remoto não é garantida.

Comentários / sugestões são convidados. Feliz codificação ......!

Khuram Shahzad
fonte
-1

Para minha aplicação, também testamos o download de um arquivo minúsculo.

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

Além disso. Alguns ISP podem usar o servidor intermediário para armazenar em cache o arquivo. Adicione um parâmetro aleatório não utilizado, por exemplo. https://www.microsoft.com/favicon.ico?req=random_number Pode impedir o cache.

user282341
fonte
-1

Estou tendo problemas com esse método no meu roteador / modem 3G, porque se a Internet for desconectada, o roteador redireciona a página para sua página de resposta, para que você ainda receba um vapor e seu código pense que existe internet. Maçãs (ou outras) têm uma página de dedução de hot spot que sempre retorna uma certa resposta. O exemplo a seguir retorna a resposta "Sucesso". Assim, você terá exatamente certeza de que poderá conectar a Internet e obter uma resposta real!

public static bool CheckForInternetConnection()
{
    try
    {       
        using (var webClient = new WebClient())
        using (var stream = webClient.OpenRead("http://captive.apple.com/hotspot-detect.html"))
        {
            if (stream != null)
            {
                //return true;
                stream.ReadTimeout = 1000;
                using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line == "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>")
                        {
                            return true;
                        }
                        Console.WriteLine(line);
                    }
                }

            }
            return false;
        }
    }
    catch
    {

    }
    return false;
}
Yusuf GURDAG
fonte
-2

Eu tenho três testes para uma conexão com a Internet.

  • Referência System.NeteSystem.Net.Sockets
  • Adicione as seguintes funções de teste:

Teste 1

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

Teste 2

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

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

Executando os testes

Se você fizer um Dictionaryde Stringe Booleanchamar CheckList, poderá adicionar os resultados de cada teste aoCheckList .

Agora, recorra a cada KeyValuePairum usando umfor...each loop.

Se CheckListcontiver um Valuede true, você saberá que há uma conexão com a Internet.

M. Liviu
fonte
-4
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

Isso funciona

slayerIQ
fonte
46
Se você tiver IP do Google em seu cache DNS, ele não vai enviar um pedido de DNS, para que ele pudesse retornar verdadeiro mesmo se você não estiver conectado
Thomas Levesque