套接字的sendTo()不发送任何数据包,除非我明确地睡眠线程

时间:2016-09-08 11:39:28

标签: c# visual-studio sockets udp wireshark

这些天我面临一种非常奇怪的行为。我在Visual Studio 2015上开发了一个C#程序,它将udp帧发送到远程主机。我有以下代码:

Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] char_send = new byte[1] { Convert.ToByte('l') };
soc.SendTo(char_send, send_IPEndPoint);
EndPoint listen_EndPoint = soc.LocalEndPoint;
IPEndPoint listen_IPEndPoint = (IPEndPoint)soc.LocalEndPoint;
soc.Close();

什么都没发生。无法在Wireshark上看到任何内容。

但是,如果我在sendTo()之后立即将线程休眠1ms,则会正确发送帧。

Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] char_send = new byte[1] { Convert.ToByte('l') };
soc.SendTo(char_send, send_IPEndPoint);
Thread.Sleep(1);
EndPoint listen_EndPoint = soc.LocalEndPoint;
IPEndPoint listen_IPEndPoint = (IPEndPoint)soc.LocalEndPoint;
soc.Close();

怎么可能?我显然在这里遗漏了一些东西,我无法弄清楚是什么。 非常感谢。

1 个答案:

答案 0 :(得分:0)

问题是您在致电Socket后正在关闭SendTo()

Socket只是逻辑结构,实际发生的是将要发送的数据复制到系统缓冲区,然后操作系统负责通过网络实际发送这些位。因为你正在关闭{ {1}}处理它并释放非托管资源,告诉操作系统释放与Socket相关的资源,这些资源释放了实际上尚未通过网络发送的数据..

一种解决方法可能是添加确认 - 因此接收方在收到您的数据报后会向您发送一个小数据报 - 然后您可以关闭套接字。事实上,由于UDP不保证交付,你可能还是想要这样做。或者,如果你只是想解雇并忘记Thread.Sleep()也可以。

PS:正确的术语是"数据报"在引用用户的UDP数据包时。 "帧"倾向于用于以太网级别数据包..