概述
先描述一下现象,程序使用UDP收发消息,发送频率大概是每秒20次,每次100-200字节。
有两个线程分别负责发送和接收。
发送使用的方法是C# 中UDPClient中的方法:
public int Send(byte[] dgram, int bytes, IPEndPoint endPoint);
接收使用UDPClient中的方法:
public byte[] Receive(ref IPEndPoint remoteEP);
上面的两个IPEndPoint参数都是传入的一个表示服务器监听地址的EndPoint。
发现程序会周期性地发生这样的异常:
System.Net.Sockets.SocketException (0x80004005): Invalid handle at System.Net.Sockets.Socket.SendTo (System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEP)
所谓周期性地,就是说一开始是能正常工作的,但是工作一段时间,就会触发一次上面的异常。网上对Invalid Handle的解释挺少的,对0x80004005号异常的解释倒是不少,有的说可能是发送消息的时候,遭到服务器的主动拒绝;有的说可能是发送缓冲区满,等等。
按照这个思路,我们怀疑是不是消息发的太频繁,过一段事件后被防火墙判定为攻击者了,所以给断开连接了。但是查了防火墙记录,并没有发现任何异常。发送缓冲区满也不太可能,每秒也只有几K字节而已。
经过大半天的排查,最终我们发现的原因是,Receive方法的参数用错了。
最初理解的RemoteEP的意思是接收来自哪个对端的数据,所以把用服务器的监听IP和端口构造的EndPoint传进来了。但是实际上,Receive(ref IPEndPoint remoteEP)方法中,remoteEP中会告诉调用者收到数据的对端来自哪里。结果这里把remoteEP给改了,然后再把同一个参数传给SendTo方法的时候,就可能引发上面的异常。
解决方法也很简单,Reveive的参数改成一个临时参数,不要去修改表示服务器监听地址的EndPoint对象就可以了。
最后
以上就是唠叨香烟为你收集整理的C# UDP发送时发生异常 System.Net.Sockets.SocketException (0x80004005): Invalid handle的全部内容,希望文章能够帮你解决C# UDP发送时发生异常 System.Net.Sockets.SocketException (0x80004005): Invalid handle所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复