zoukankan      html  css  js  c++  java
  • Windows下的UDP爆了10054--远程主机强迫关闭了一个现有的连接

    故事是这样的。

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

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

    因为是实时对战的,听说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下无此问题,所以不需要添加上述代码,(添加反而异常)。

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

  • 相关阅读:
    在LINUX中添加按键的驱动并编译进入内核
    什么是Dojo
    Dojo EnhancedGrid Pagination
    再Repeater模板中,如何获取里面的控件 客户端ID ??
    需求分析的大道理
    PL/SQL块结构和组成元素
    ORACLE SQL:经典查询练手第二篇
    企业信息化的定义、内涵
    背景需要需求规格
    asp.net(c#)两时间段每天是星期几,周几(时间段日历显示)的问题解
  • 原文地址:https://www.cnblogs.com/pasoraku/p/5612105.html
Copyright © 2011-2022 走看看