这些代码通过用户数据报协议提供发送数据。 下面有两个代码。 当我使用第一个代码不可达的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
(没有例外)
- 最安全的方法来停止节点实例
- 如何通过套接字nginx代理url
- Nginx + uWsgi + Django'连接上行时拒绝权限(套接字)
- socket.io nginxconfigurationWebSocket握手期间出现错误:“连接”标题值不是“升级”:keep-alive
- uwsgi协议比http协议快吗?
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 }