Windows操作系统中无法访问的IP Socketclosures时间

这些代码通过用户数据报协议提供发送数据。 下面有两个代码。 当我使用第一个代码不可达的IP地址,我得到了三秒的延迟。


请看新的结果标题


只需打开新的C#控制台应用程序并粘贴这些代码。 (第一个代码)

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

testing1(使用) :可达IP
testing2(使用) :无法访问的IP
输出:
Test1 label1 —> h:mm:ss label2 —> h:mm:ss(同一时间)
Test2 label1 —> h:mm:ss label2 —> h:mm:ss +3 second
(没有例外)

WireShark结果:
testing1(使用) :可达IP – >数据被捕获,看到。
testing2(使用中) :无法访问IP->无数据。

当我没有“使用”块时,我没有得到三秒延迟。

只需打开新的C#控制台应用程序并粘贴这些代码。 (第二个代码)

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

testing1(不使用) :可达IP
testing2(不使用) :无法到达的IP

输出:
Test1 label1 —> h:mm:ss(同一时间)label2 —> h:mm:ss(同一时间)
Test2 label1 —> h:mm:ss(同一时间)label2 —> h:mm:ss(同一时间)
(没有例外)

WireShark结果:
testing1(不使用) :可达IP – >数据被捕获,看到。
testing2(不使用) :无法访问IP->无数据。

这三秒延迟的意思是什么?
我不知道,但我认为我必须使用“使用”块,因为如果我没有使用块内存的使用将增加非常高的阶段。 这两个代码有什么区别? 哪一个更可靠? 有没有更好的办法? 我不想要三秒钟的延迟。

如何减less三秒延迟到零?

提前致谢…


新的结果

我已经尝试过在Windows操作系统中使用Python编程语言的无法访问IP的套接字Close / Dispose。 我得到了相同的结果,即不可达IP的三秒延迟。 但是,当我在Ubuntu 15.10中尝试相同的Python代码时,我没有得到三秒的延迟。

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

你的UdpClient是一个可丢弃的对象。 在重新连接之前,您应该处置它。

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

或者将循环外部的连接移到重用相同的连接。

实际的区别在于,在SECOND CODE中client上不调用Dispose()方法。 但是using (var client = new UdpClient())在第一个代码中调用Dispose() using (var client = new UdpClient()) 。 当尝试连接不可达IP地址后, Dispose()方法需要额外3秒的时间。

您可以按如下所示注意延迟打印最后一个标签。 延迟是由Dispose引起的。 client必须在上面声明try块才能在finally块中使用它。

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

我也注意到,如果不可达IP地址不在域中,则不会导致延迟。 例如,如果我的个人电脑的IP是192.168.1.20 ,我试图访问202.22.1.88那么看不到延迟。

结论是:延迟是由Dispose()造成的。 但是Dispose()行为应该进一步调查。

将三秒延迟减至零解决方案1(与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 } 

将三秒延迟减至零解决方案1(客户端=空):


 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 }