Windows下的UDP爆了10054--远程主机强迫关闭了一个现有的连接

陈惊蛰 2016-06-23

算法 windows 主机 c# 机器人 Socket

故事是这样的。

前几天在网上逛,看到了一个漂亮的坦克模型。

我觉得这个坦克可以做一个游戏,那需要一些服务器代码。

因为是实时对战的,听说TCP有很多不适,选择了UDP。

得知有一种算法可以解决UDP丢包乱序的问题,就封装成了C#,雄赳赳气昂昂准备大搞一番。

然而和客户端一对接,Client发了几个包关闭,天,这就抛了个异常!

10054...远程主机强迫关闭了一个现有的连接

喂喂,不是说好的UDP是无连接的吗?为嘛说连接被强迫关闭了??

不过没关系,不就是10054吗,TCP Socket时候又不是没见过,try catch一下就好了。

那么,try catch(ex){log(ex);} finally{beginReceive();}三步走。

晕!beginReceive()挂了...这都会挂?再加try catch捕获了递归,递归到成功为止!然而怎么救也救不回来/(ㄒoㄒ)/~~

仔细检查一下,发现是对关闭的客户端EndPoint执行了Send,导致Receive那边抛出了异常Σ( ° △ °|||)︴

为嘛是执行Send导致Receive抛出异常,而且导致next Receive救也救不回来?

那么?不Send能救吗?能...可是问题是当Receive异常的时候不知道是哪个客户端断开了呀,如果是Send时候异常还好,跑Receive异常,而且异常时候的EndPoint也是对不上的,关联不上啊(这时候倒是想起无连接了←_←)。

于是请教了谷歌老师。

果然搜出一大堆结果,在筛选掉大量的TCP10054和没有结果没有意义的问答贴和大量转载之后,终于找到了个靠谱的答案,不幸的是文章也是机器人爬来的转载各种广告不忍直视,好在贴出了一个链接:

https://support.microsoft.com/zh-cn/kb/263823

看这个排版,想来也是年代已久,大概意思是windows的一个bug,可以通过加几行代码的方式搞定。

于是加了几行代码:

const uint IOC_IN = 0x80000000;
int IOC_VENDOR = 0x18000000;
int SIO_UDP_CONNRESET = (int)(IOC_IN | IOC_VENDOR | 12);

//因为我使用的是UdpClient, 所以先get出Socket(Client)来。
server.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);

再次执行,OK,说好的无连接UDP回来了!

问题解决。

Linux下无此问题,所以不需要添加上述代码,(添加反而异常)。

 

鉴于网上答案诸多不靠谱,立此贴增加点命中率。

登录 后评论
下一篇
云攻略小攻
882人浏览
2019-10-11
相关推荐
TCP异常关闭研究分析
1109人浏览
2017-10-09 15:44:00
windows下cmd命令
1813人浏览
2016-05-09 18:11:00
Windows CMD命令大全
1075人浏览
2018-09-25 11:54:07
Windows Sockets错误码
893人浏览
2017-10-09 14:36:00
Linux 服务详解
637人浏览
2014-10-08 17:30:24
c#socket编程基础
504人浏览
2015-07-26 18:34:00
关于socket tcp 断线重连
578人浏览
2015-09-17 23:06:00
[转载]CMD网络命令
709人浏览
2017-09-05 15:19:00
Linux 服务详解
526人浏览
2017-11-12 12:43:00
关于socket tcp 断线重连
1343人浏览
2017-11-27 14:09:00
0
0
0
456