【理解】 Error 10053和 Error 10054


1. 10053

    這個錯誤碼的意思是:  A established connection was aborted by the software in your host machine, 一個已建立的連接所在主機的軟件中止 

2. 10054

    這個錯誤碼的意思是: Connection closed by peer, 連接已經被對方關閉

 

10053 出現的可能原因是:數據傳輸超時或者協議錯誤。

當主動端發起連接服務器的請求,連接成功之后發送數據請求給服務器,服務器處理時間稍長,導致客戶端超時關閉,等到服務器將數據寫入緩沖區后,TCP協議發現socket已經關閉,所以服務器會出現10053的錯誤碼,這是正常的現象。

 

10054 出現的可能原因是:對端關閉了socket(可能是異常也可能是超時),然而本端還沒有感知到,依舊寫入數據(對端接收緩沖區有數據),對端發現有未處理的數據直接回復RST重置連接標記,表明對端已經關閉了socket

檢測出這個錯誤碼一般是對端發送了RST包給本端,本端接收這個包, 表示對端出現了異常:  四種情況發送RST碼: 

      1. 本端連接對端未打開的端口, 對端發送RST包

      2. 請求超時

      3. 已關閉連接上收到數據: 

    主要出現在連接的關閉過程,當請求關閉連接的一方在兩個MSL后,仍然收到服務機發送來的最后一個FIN,說明其最后發送出的ACK丟包, 服務機又重發了FIN包,而此時客戶機已經不處於TIME_OUT狀態,連接已經徹底不存在,再收到服務機發送來的FIN,就會直接回復一個RST包,讓服務機直接關閉連接,拋棄 緩沖區的所有數據。

    舉一個其他例子: 主動端關閉socket,發送了fin給被動端,此時主動端無法接受和發送數據了,此時如果被動端調用read會收到fin(讀取0),如果被動端write給主動端,主動端會發送rst,但rst不會立即通知到被動段,只有被動端在第二次write時,數據不會發送給主動端而是發出一個SIGPIPE信號而終止被動端(可捕獲忽略該信號)

      4. close連接時, 接收緩沖區還有數據

    如果close連接時,接收緩沖區還有對端發過來的數據,則回一個RST,直接丟棄接收緩沖區的內容

      5. 設置了so_linger選項但是 l_lingertime 為0, close 時會發出RST

 

注意到10053和10054出現的原因有重復,以下是區分他倆的一個文章:

http://www.blogjava.net/pandawang/archive/2013/11/28/406922.html

 

某端出現10053和10054的在於主動端(客戶端)和被動端(服務器)建立連接后,服務器非正常關閉時有沒有關閉socket,這個fin包是不是在rst之前被客戶端收到,fin先於rst,則10053

 

update problem:

今天啟動flask的自帶server,非常簡單,就是一個直接返回字符串(有sleep操作,故意的),發送一個請求給flask,這個請求會超時: 1. 在本機上發,2. 在其他主機上發; 

發現這倆種方法的結果不同,第一種會打印10053的錯誤信息,第二種不會;

經過microsoft message analyzer 抓包工具分析, 第一種操作,數據包是在環路接口流動,socket很快就關閉並回收了,導致server將響應返回時報錯,協議棧認為是自己關閉的所以報的10053,但其實應該是10054.

因為在一個已經關閉的socket寫會引起對端發送rst,連接重置,但因為是回路接口,windows的實現可能認為是自己關閉的,所以錯誤碼才是10053。

第二種因為不再同一個機器,對端關閉不影響,數據發送還是成功的(對端回復了rst),所以沒有報錯。

同樣的實驗在linux下面運行,報的錯是 error 32 broken pipe。這點和Windows不一樣,如果協議棧認為是自己關閉的,在linux上的錯誤應該是 error 53 ECONNABORTED。

所以數據傳輸的錯誤碼,在環路接口上可能與正常的理解不同,同時與系統相關。

以下附上抓包工具的結果:

下圖是client和server在統一機器上的情況:其報錯10053,看右側的第二個框,其響應並沒有寫入完全,就報錯,所以斷定是socket資源已經被銷毀了,但由於是在同一個機器,所以協議層認為是自己斷的,報了10053

ps:環路接口每個syn,fin,ack包都重發一遍了,不知道為啥。。。。

 

下圖是client和server不在同一機器上的情況:其未報10053, 可以看39938消息,數據是寫入緩沖區成功了,發送的時候對端回了rst,參考39950。 flask自帶的server可能處理了這種並沒有打印連接重置的錯誤

 

 

 

ps: 

1. close 是優雅關閉過程,當socket的引用計數減少到0,開始優雅關閉流程,發送fin包,經四次握手關閉

2. shutdown 是直接破壞socket的通信,如果指定關閉WR,則發送fin包給對方

 


免責聲明!

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



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