Hora de cierre del socket IP inalcanzable en el sistema operativo Windows

Estos códigos proporcionan datos de envío a través del Protocolo de Datagtwig de Usuario. Hay dos códigos a continuación. Cuando uso el primer código para la dirección IP inalcanzable, obtuve el retraso de tres segundos.


Por favor, mira el nuevo título de resultados


Simplemente abra la aplicación C # CONSOLE y pegue estos códigos en ella. (PRIMER CÓDIGO)

using System; using System.Net; using System.Net.Sockets; namespace Test { class Program { static void Main(string[] args) { byte[] data = { 1, 20, 60, 44, 244 }; while (true) { Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); try { using (var client = new UdpClient()) { // Please check IP Address, It must be unreachable... // IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.1.141"), 55600); // client.Connect(ep); client.Send(data, data.Length, "192.168.1.141" , 55600); } Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); Console.WriteLine(" "); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } } 

Prueba 1 (con usar) : IP accesible
Prueba 2 (con usar) : IP inalcanzable
Salida:
Test1 label1 —> h: mm: ss label2 —> h: mm: ss (Mismo Tiempo)
Test2 label1 —> h: mm: ss label2 —> h: mm: ss +3 segundo
(Sin excepción)

Resultados de WireShark:
Prueba 1 (con el uso) : Ip accesible -> Los datos se capturan, se ven.
Prueba 2 (con el uso) : IP inalcanzable-> No hay datos.

Cuando uso sin “usar” bloques, no obtuve el retraso de tres segundos.

Simplemente abra la aplicación C # CONSOLE y pegue estos códigos en ella. (SEGUNDO CÓDIGO)

 using System; using System.Net; using System.Net.Sockets; namespace Test { class Program { static void Main(string[] args) { byte[] data = { 1, 20, 60, 44, 244 }; while (true) { Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); try { var client = new UdpClient(); //Please check IP address, It must be unreachable... // IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.1.41"), 5600); // client.Connect(ep); client.Send(data, data.Length, "192.168.1.141", 55600); Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); } catch (Exception xe) { Console.WriteLine(xe.ToString()); } Console.WriteLine(" "); System.Threading.Thread.Sleep(1000); } } } } 

Prueba 1 (sin usar) : Ip alcanzable
Prueba 2 (sin usar) : Ip inalcanzable

Salida:
Test1 label1 —> h: mm: ss (Same Time) label2 —> h: mm: ss (Same Time)
Test2 label1 —> h: mm: ss (Same Time) label2 —> h: mm: ss (Same Time)
(Sin excepción)

Resultados de WireShark:
Prueba 1 (sin usar) : Ip accesible -> Los datos se capturan, se ven.
Prueba 2 (sin usar) : IP inalcanzable-> No hay datos.

¿Cuál es la media de ese retraso de tres segundos?
No estoy seguro, pero creo que tengo que usar bloques “utilizando” porque si no utilizo los bloques, el uso de la memoria boostá en un nivel muy alto. ¿Cuál es la diferencia entre ambos códigos? ¿Cuál es más confiable? ¿Hay alguna forma mejor? No quiero el retraso de tres segundos.

¿Cómo disminuir la demora de tres segundos a cero?

Gracias por adelantado…


NUEVOS RESULTADOS

He intentado cerrar / Eliminar zócalo para IP inalcanzable con Python Programming Language en el sistema operativo Windows. Obtuve el mismo resultado, es decir, una demora de tres segundos para la IP inalcanzable. Pero cuando bash el mismo código Python en Ubuntu 15.10, no obtuve el retraso de tres segundos.

 import socket import datetime IPADDR = '192.168.1.141' PORTNUM = 5600 PACKETDATA = "f1a525da11f6".encode() while(True): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) s.connect((IPADDR, PORTNUM)) s.send(PACKETDATA) print(datetime.datetime.now()) s.close() 

Tu UdpClient es un objeto desechable. Deberías tirarlo, antes de volver a conectarte.

  using (var client = new UdpClient()){ //Please check IP address, It must be unreachable... IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.1.41"), 5600); client.Connect(ep); client.Send(data, data.Length); } 

o mueva la conexión fuera de su bucle para reutilizar la misma conexión.

La diferencia real es que el método Dispose() no se invoca en el client en SECOND CODE. Pero se llama a Dispose() en PRIMER CÓDIGO using (var client = new UdpClient()) . El método Dispose() toma 3 segundos de tiempo adicional cuando se le llama después de un bash de conectar direcciones IP inalcanzables.

Puede SEGUIR CÓDIGO SEGUNDO como se indica a continuación para notar el retraso en la impresión de la última etiqueta. El retraso es causado por Dispose . El client debe declarar el bloque de prueba anterior para utilizarlo en el bloque final.

 finally { if (client != null) ((IDisposable)client).Dispose(); } Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); 

También he notado que el retraso no se produce si la dirección IP inalcanzable está fuera del dominio. Por ejemplo, si la IP de mi PC es 192.168.1.20 y trato de acceder a 202.22.1.88 , no se ve el retraso.

La conclusión es: el retraso es causado por Dispose() . Pero el comportamiento de Dispose() debe ser investigado más a fondo.

Disminuya la demora de tres segundos a cero Solución 1 (uso con ThreadPool):


 while (true) { Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); try { ThreadPool.QueueUserWorkItem(state => { using (var client = new UdpClient()) { client.Send(data, data.Length, "192.168.1.145", 55600); } }); Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); Console.WriteLine(" "); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } System.Threading.Thread.Sleep(1000); // to see easily } 

Disminuya la demora de tres segundos a cero Solución 1 (cliente = nulo):


 while (true) { Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); try { var client = new UdpClient(); client.Send(data, data.Length, "192.168.1.145", 55600); client = null; Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt")); Console.WriteLine(" "); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } System.Threading.Thread.Sleep(1000); // to see easily }