网上其他人有类似的问题,我也碰到了,没有很好的解决方案。这个问题是Winsock所特有的(最起码所有的问题都是在Windows平台下)。一般在使用UDP Socket时,我们发出去数据,是不管它到不到达的,而且UDP并不是面向连接的,所以在收到这个错误时,会感觉很奇怪:“连接被重置10054”。
在UDP通信过程中,如果客户端中途断开,服务器会收到一个错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。这个问题可是太严重了。
都知道,UDP是无连接的,怎么会出现这个异常呢?
有人是这么描述的:http://www.cnblogs.com/Lotrix/archive/2011/05/06/2038666.html
这个错误一般是使用UDP Socket接受时收到(不管你用C#、Python还是C,在Windows下都会有类似的问题,只要你调用类似ReceiveFrom函数)。这是上一次Send操作向一个地址发送,但是那个地址没有Socket监听(例如对等体崩溃),那么ICMP控制协议会向我们发送一个Port Unreachable错误,当然这个错误应该包含对方的详细地址等信息,但是Winsock把这个错误转化为Connection Reset,在你下一次调用读操作的时候,引发异常,却没把详细信息给你——例如用C#接受到的对方地址是0.0.0.0。

而这个问题最要命的是,如果你不采取措施,每次调用读操作都会引发该异常!唯一恢复正常的办法就是把Socket关掉,重开。这就非常要命:你要实现一个UDP服务器,把收到的音频发给所有的客户,如果某个客户崩溃了或者网络不好,你的Send不会出问题,但是你Receive的时候却出了问题!好吧,你捕获了异常,重新Receive,还是异常!好吧,你关掉Socket重新建立,但是因为不知道是哪个客户出了问题,所以不能及时把他的地址从发送列表里去除(即使使用心跳检测也要等几秒种),下次Send还是这样,你就不停地关闭创建Socket。

网络上的讨论,最后要么说这是一个bug,要么使用如下代码:

const int SIP_UDP_CONNRESET=-1744830452;
socket.IOControl(SIP_UDP_CONNRESET, new byte[] {0, 0, 0, 0}, null);

而使用这段代码,设置这个选项忽略那个Reset错误,这样不用重建Socket,只不过每次Socket都会向一些已经关闭的客户发包,浪费了服务器资源;
客户端可以接收到服务器发送到消息,但在有连接被重置的消息之后,就无法接收客户端的消息了;
只能通过其他机制确定客户端已经断开,延迟一段时间后才能确定哪个客户端出问题。

要不就在出问题的地方抛出异常,不然的话把详细错误给了,再不行不要强制出一个错误整个Socket就毁了,然而一个都没做到,默认的行为不是正常的UDP行为,还改错误类型。

我查了下微软里是这样说的:
1551496343(1).png
1551496391(1).png