在某些计算机上,我会产生奇怪的效果,即在 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
发布评论
评论(1)
好吧,这也与 .NET 和我的软件无关。
病毒扫描程序似乎还扫描完整的网络流量。因此,用于发送 UDP 包的 .NET 库函数实际上确实发送了包,但如果在 Send() 方法之后过早调用 UdpClient.Close() ,则扫描器会丢弃该包。
因此,现在有两种可能的解决方法(对我有用)
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)