web-dev-qa-db-fra.com

Le moyen le plus rapide de tester la connexion Internet

C # 2008 SP1

J'utilise ce code pour me connecter au site Web de notre client. Ceci est pour une application de téléphone logiciel. Avant que l'utilisateur ne passe un appel, le softphone doit vérifier s'il existe une connexion Internet active. 

Donc, ce que j’ai fait est d’utiliser la classe httpWebRequest pour se connecter au site Web de nos clients. Si la réponse est correcte, la connexion Internet peut continuer. 

Cependant, j'ai remarqué que la réponse prenait trop de temps. Je ne sais pas si ce n'est pas un moyen très efficace de tester. 

Cependant, lorsque je navigue sur leur site Web, le chargement de la page prend moins d'une seconde. Mais prend trop de temps lorsque j'utilise la classe HttpWebRequest

Donc, les exigences pour cela sont:

Parfois, un proxy sera utilisé au bureau du client. To je ne peux pas utiliser la classe TCPClient (ne possède pas de propriété proxy).

Le proxy ne supporte pas SOCKS et ne peut donc pas utiliser la classe Sockets.

J'ai besoin d'utiliser une propriété de délai d'attente. Donc, ne peut pas utiliser la classe WebClient. En effet, le softphone gèlerait jusqu'à ce qu'une réponse soit renvoyée. Donc, le délai d'attente après quelques secondes.

Donc, le seul auquel je peux penser est la classe HttpWebRequest.

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.xxxxxxxxx.com");
            request.Timeout = 5000;
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                Console.WriteLine("IsSIPServerAvailable: " + response.StatusCode);
                isAvailable = true;
            }

======== Editez en utilisant p\Invoke ====

 [DllImport("wininet.dll", CharSet = CharSet.Auto)]
    private extern static bool InternetGetConnectedState(ref InternetConnectionState_e lpdwFlags, int dwReserved);

 [Flags]
    enum InternetConnectionState_e : 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
    }

 // In function for checking internet
 InternetConnectionState_e flags = 0;          
 bool isConnected = InternetGetConnectedState(ref flags, 0);
22
ant2009

Essayez d’utiliser P/Invoke pour appeler InternetGetConnectedState . Cela devrait vous dire si vous avez ou non une connexion configurée. Vous pouvez ensuite essayer de vérifier la connexion spécifique à votre service en utilisant InternetCheckConnection . C'est (parfois) plus rapide que de connecter directement la connexion, mais je le testerais pour voir si c'était mieux que de simplement établir une connexion complète à l'avant.

16
Reed Copsey

Dans une situation similaire, nous allions appeler un client de la WCF et cela prendrait trop de temps si le client n'était pas joignable (pour une raison quelconque). Ce que j'ai fait, c'est ouvrir un socket TCP brut à l'adresse du client ... Cela échoue rapidement si le client n'écoute pas sur le port (dans votre cas, le port 80) et y parvient rapidement.

Cela m'a donné la réponse la plus rapide et la plus précise pour déterminer si je serais capable de communiquer avec le point final que j'essayais d'atteindre. Le seul inconvénient est que vous devez gérer vous-même le délai d'attente sur le socket, car seules les options pour les délais d'attente d'envoi et de réception ne sont pas connectées. 

Ca fait plutot comme ca...

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

    try
    {
         IAsyncResult result = socket.BeginConnect("www.xxxxxxxxx.com", 80, null, null );
         //I set it for 3 sec timeout, but if you are on an internal LAN you can probably 
         //drop that down a little because this should be instant if it is going to work
         bool success = result.AsyncWaitHandle.WaitOne( 3000, true );

         if ( !success )
         {
                throw new ApplicationException("Failed to connect server.");
         }

         // Success
         //... 
    }
    finally
    {
         //You should always close the socket!
         socket.Close();
    }

Je n'ai pas le code que j'ai utilisé devant moi, mais cela devrait vous mettre sur la voie générale.

6
Brian ONeil

Vous pouvez référencer l'espace de noms Microsoft.VisualBasic.Devices pour utiliser le délégué NetworkAvailableEventHandler et la classe Network. J'utilise la propriété Network.IsAvailable et l'événement Network.NetworkAvailabilityChanged pour vérifier que le réseau existe (ou est affecté ultérieurement), puis effectue un HTTP GET sur mon serveur pour voir si le serveur est présent.

Cela aide à signaler le problème un peu plus précisément, au lieu de "ne peut pas voir le réseau".

2
Richard Watson

Une meilleure option consiste à ajouter une référence à Microsoft.VisualBasic et à ajouter une instruction using Microsoft.VisualBasic.Device. Vous pouvez ensuite utiliser la ligne de code suivante pour vérifier la connexion à un réseau.

public static bool isConnectedToNetwork {
   get {
      Network network = new Network();
      return network.IsAvailable;
   }
}
1
Enyo Ginger

request.GetResponse() lui-même vous donnera une exception si le nom de l'hôte ne peut pas être résolu. Vous voudrez peut-être mettre un try-catch autour de cela, catch System.Net.WebException et vérifier son statut d'erreur dans la propriété Status. Je ne suis toutefois pas sûr de savoir quels statuts indiqueraient exactement l'absence d'Internet; la plupart des réponses pourraient tout aussi bien être dues à dns ou à d'autres problèmes de connexion.

0
Nyerguds