La forma más rápida de probar la conexión a internet

C # 2008 SP1

Estoy usando este código para conectarme al sitio web de nuestro cliente. Esto es para una aplicación de teléfono softphone. Antes de que el usuario haga una llamada, el softphone debe probar si hay una conexión a Internet activa.

Por lo tanto, quiero que lo haya hecho se utiliza la clase httpWebRequest para conectarse al sitio web de nuestros clientes. Si la respuesta es correcta, entonces la conexión a Internet puede continuar.

Sin embargo, me he dado cuenta de que la respuesta tarda demasiado en responder. No estoy seguro de si esta no es una forma muy eficiente de probar.

Sin embargo, cuando navego a su sitio web, toma menos de un segundo cargar la página. Pero lleva demasiado tiempo cuando utilizo la clase HttpWebRequest

Entonces los requisitos para esto son:

En algún momento se usará un proxy en la oficina del cliente. A No puedo usar la clase TCPClient (no tiene una propiedad de proxy).

El proxy no es compatible con SOCKS, por lo que no puede usar la clase Sockets.

Necesito usar una propiedad de tiempo de espera. Entonces no puedo usar la clase de WebClient. Esto se debe a que el softphone se congelará hasta que se devuelva una respuesta. Así que agote el tiempo después de unos segundos.

Entonces, el único en el que puedo pensar es en la clase 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; } 

======== Editar usando 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); 

Intenta usar P / Invoke para llamar a InternetGetConnectedState . Eso debería decirle si tiene o no una conexión configurada. Luego puede intentar verificar la conexión específica a su servicio usando InternetCheckConnection . Esto es (a veces) más rápido que conectar la conexión directamente, pero lo probaría para ver si es mejor que simplemente hacer una conexión completa por adelantado.

¿Qué va a usar el softphone para su comunicación real? ¿Esto pasa por HTTP / HTTPS al mismo sitio web? Si es así, es absolutamente el camino correcto, el siguiente paso es averiguar por qué tarda tanto.

¿La conexión de red está definitivamente activa antes de que usted pueda solicitarla? ¿Definitivamente no estás haciendo ninguna solicitud de antemano? Lo pregunto porque me doy cuenta de que no está deshaciéndose de la respuesta; si eso sucede también en otros lugares, es posible que encuentre que está corriendo contra el grupo de conexiones y que solo le da un par de conexiones a un servidor en particular. La moraleja es poner siempre HttpWebResponse s en una statement de using . Por supuesto, ese puede no ser el problema en su caso, pero vale la pena intentarlo.

Si su aplicación real se conectará en otro lugar, entonces es allí donde su prueba también debería verificar. Básicamente, hágalo lo más real posible.

Por interés, dices que es una aplicación de “softphone”: ¿se está ejecutando realmente en un teléfono de alguna descripción, usando el marco compacto, o es una aplicación de escritorio?

Tuve una situación similar en la que íbamos a hacer una llamada de WCF a un cliente y tomaría demasiado tiempo si el cliente no era accesible (por la razón que sea). Lo que hice fue abrir un socket TCP sin procesar a la dirección del cliente … Esto falla rápidamente si el cliente no está escuchando en el puerto (en su caso, el puerto 80) y lo hace rápidamente si están allí.

Esto me dio la respuesta más rápida y precisa para determinar si sería capaz de comunicarme con el punto final que estaba tratando de alcanzar. El único inconveniente de esto es que tiene que administrar el tiempo de espera en el socket porque solo hay opciones para los tiempos de espera de envío y recepción que no se conectan.

Es algo parecido a esto…

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

No tengo el código real que utilicé frente a mí, pero esto debería ponerlo en la ruta general.

Puede hacer referencia al espacio de nombres Microsoft.VisualBasic.Devices para usar el delegado NetworkAvailableEventHandler y la clase de red. Uso la propiedad Network.IsAvailable y el evento Network.NetworkAvailabilityChanged para verificar que la red esté allí (o se vea afectada posteriormente), y luego realizo un HTTP GET en mi servidor para ver si el servidor está allí.

Esto ayuda a informar el problema un poco más específicamente, en lugar de “no se puede ver la red”.

Una mejor opción es agregar una referencia a Microsoft.VisualBasic y agregar una statement using Microsoft.VisualBasic.Device, luego puede usar la siguiente línea de código para verificar la conexión a cualquier red.

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

request.GetResponse() sí mismo le dará una excepción si el nombre de host no se puede resolver, por lo que es posible que desee poner un try-catch alrededor de eso, atrapar System.Net.WebException , y verificar su estado de error en el Propiedad del Status Sin embargo, no estoy seguro de qué estados indicarían exactamente que no hay internet; la mayoría de las respuestas podrían ser debidas a dns u otros problemas de conexión.