Socket 連接錯誤及原因


ECONNABORTED  

  該錯誤被描述為“software caused connection abort”,即“軟件引起的連接中止”。原因在於當服務和客戶進程在完成用於 TCP 連接的“三次握手”后,客戶 TCP 卻發送了一個 RST (復位)分節,
在服務進程看來,就在該連接已由 TCP 排隊,等着服務進程調用 accept 的時候 RST 卻到達了。POSIX 規定此時的 errno 值必須 ECONNABORTED。
源自 Berkeley 的實現完全在內核中處理中止的連接,服務進程將永遠不知道該中止的發生。服務器進程一般可以忽略該錯誤,直接再次調用accept。

ECONNRESET

該錯誤被描述為“connection reset by peer”,即“對方復位連接”,這種情況一般發生在服務進程較客戶進程提前終止。
當服務進程終止時會向客戶 TCP 發送 FIN 分節,客戶 TCP 回應 ACK,服務 TCP 將轉入 FIN_WAIT2 狀態。此時如果客戶進程沒有處理該 FIN (如阻塞在其它調用上而沒有關閉 Socket 時),
則客戶 TCP 將處於 CLOSE_WAIT 狀態。當客戶進程再次向 FIN_WAIT2 狀態的服務 TCP 發送數據時,則服務 TCP 將立刻響應 RST。
一般來說,這種情況還可以會引發另外的應用程序異常,客戶進程在發送完數據后,往往會等待從網絡IO接收數據,很典型的如 read 或 readline 調用,
此時由於執行時序的原因,如果該調用發生在 RST 分節收到前執行的話,那么結果是客戶進程會得到一個非預期的 EOF 錯誤。
此時一般會輸出“server terminated prematurely”-“服務器過早終止”錯誤。

EPIPE

  錯誤被描述為“broken pipe”,即“管道破裂”,這種情況一般發生在客戶進程不理會(或未及時處理)Socket 錯誤,繼續向服務 TCP 寫入更多數據時,內核將向客戶進程發送 SIGPIPE 信號,
該信號默認會使進程終止(此時該前台進程未進行 core dump)。結合上邊的 ECONNRESET 錯誤可知,向一個 FIN_WAIT2 狀態的服務 TCP(已 ACK 響應 FIN 分節)寫入數據不成問題,
但是寫一個已接收了 RST 的 Socket 則是一個錯誤。

ETIMEDOUT
  錯誤被描述為“connect time out”,即“連接超時”,這種情況一般發生在服務器主機崩潰。此時客戶 TCP 將在一定時間內(依具體實現)持續重發數據分節,
試圖從服務 TCP 獲得一個 ACK 分節。當最終放棄嘗試后(此時服務器未重新啟動),內核將會向客戶進程返回 ETIMEDOUT 錯誤。
如果某個中間路由器判定該服務器主機已經不可達,則一般會響應“destination unreachable”-“目的地不可達”的ICMP消息,
相應的客戶進程返回的錯誤是 EHOSTUNREACH 或ENETUNREACH。當服務器重新啟動后,由於 TCP 狀態丟失,之前所有的連接信息也不存在了,
此時對於客戶端發來請求將回應 RST。如果客戶進程對檢測服務器主機是否崩潰很有必要,要求即使客戶進程不主動發送數據也能檢測出來,
那么需要使用其它技術,如配置 SO_KEEPALIVE Socket 選項,或實現某些心跳函數。

ENOPROTOOPT
  該錯誤不是一個 Socket 連接相關的錯誤。errno 給出該值可能由於,
通過 getsockopt 系統調用來獲得一個套接字的當前選項狀態時,如果發現了系統不支持的選項參數就會引發該錯誤。


免責聲明!

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



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