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下無此問題,所以不需要添加上述代碼,(添加反而異常)。

 

鑒於網上答案諸多不靠譜,立此貼增加點命中率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM