C#:UdpClient 在调用 close() 时不发送数据

发布于 2024-12-10 01:33:23 字数 1166 浏览 0 评论 0 原文

在某些计算机上,我会产生奇怪的效果,即在 UdpClient.Send() 之后过早调用 UdpClient.Close() 时,UdpClient 将不会发送数据。 我使用 .NET 4.0 和 WireShark 来验证数据包丢失情况。

编码的基本部分是:

UdpClient sender = new UdpClient();
sender.Connect( new IPEndPoint( this.ipAddress, this.Port ) );
int bytesSent = sender.Send( data, data.Length );
sender.Close();

奇怪的是:

  • 在大多数计算机上,数据将毫无问题地发送
  • 即使没有发送数据包,也不存在异常或其他错误
  • bytesSent 将始终等于 data.Length
  • 在不发送数据包的计算机上 Thread.Sleep( 250 )在调用 sender.Close() 之前将解决问题!

那么,即使在 UdpClient.Send() 报告了正确的字节数之后,什么才能取消数据包的发送呢?为什么这仅在某些机器上出现?这可能是某些网络驱动程序、防病毒软件等的不同行为吗?

我还尝试显式设置 LingerOptions ,这应该是不必要的,因为默认情况下是在关闭底层套接字之前发送所有挂起的数据。但是,在执行 sender.Client.LingerState = new LingerOption( true, 10 ) 时(如 http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.lingerstate.aspx) 我知道

 SocketException (0x80004005): An unknown, invalid, or unsupported option 
 or level was specified in a getsockopt or setsockopt call.

发生了什么事吗?

问候, 七

On some computers I have the strange effect that UdpClient will not send data when UdpClient.Close() is called too soon after a UdpClient.Send().
I'm using .NET 4.0 and WireShark to verify the packet-loss.

The essential part of the coding is:

UdpClient sender = new UdpClient();
sender.Connect( new IPEndPoint( this.ipAddress, this.Port ) );
int bytesSent = sender.Send( data, data.Length );
sender.Close();

Weired is:

  • On most Computers data will be sent without problems
  • There is no exception or other error even if no packet was sent
  • bytesSent will always equal data.Length
  • On computers not sending packets a Thread.Sleep( 250 ) right before calling sender.Close() will fix the problem!

So, what could cancel the sending of packets, even after UdpClient.Send() reported the correct amount of bytes? Why is this manifesting only on certain machines? Could this be a different behaviour of some network drivers, anti-virus software or the like?

I also tried to set LingerOptions explicitly which should be unneccessary as the default is to send all pending data before closing the underlying socket. However, when doing a sender.Client.LingerState = new LingerOption( true, 10 ) (as descibed in http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.lingerstate.aspx) I get

 SocketException (0x80004005): An unknown, invalid, or unsupported option 
 or level was specified in a getsockopt or setsockopt call.

Any ideas what's going on?

Regards,
Seven

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我太投入 2024-12-17 01:33:23

好吧,这也与 .NET 和我的软件无关。
病毒扫描程序似乎还扫描完整的网络流量。因此,用于发送 UDP 包的 .NET 库函数实际上确实发送了包,但如果在 Send() 方法之后过早调用 UdpClient.Close() ,则扫描器会丢弃该包。

因此,现在有两种可能的解决方法(对我有用)

  1. 在调用 UdpClient.Close() 之前引入一点睡眠(大约 4 毫秒就足够了)
  2. 删除病毒扫描程序并尝试另一个(Microsoft Security Essentials 未显示此效果) )

OK, this has nothing to do with .NET and my software either.
It seems that the virus scanner also scans the complete network trafic. And so .NET library functions for sending UDP packages actially did send the package, but the scanner discards it if UdpClient.Close() was called too soon after the Send() method.

So, there are two possible work-arounds now (that worked for me)

  1. Introduce a little sleep before calling UdpClient.Close() (about 4ms are sufficient)
  2. Remove the virus scanner and try another one (Microsoft Security Essentials does not show this effect)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文