Socket 連接錯誤之ECONNABORTED


最近做vue項目用到了axios請求數據,在輪詢請求時經常會出現code:‘ECONNABORTED’。在博主的文章里找到了答案,是三次握手之后客戶TCP的請求已關閉。瞬間淚流滿面。。。

ECONNABORTED

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

 C代碼

/* Linux system */  
  
include/asm-alpha/errno.h:#define ECONNABORTED 53 /* Software caused connection 
abort */  
include/asm-generic/errno.h:#define ECONNABORTED 103 /* Software caused 
connection abort */  
include/asm-mips/errno.h:#define ECONNABORTED 130 /* Software caused connection 
abort */  
 
accept(2) man page 寫道
[ECONNABORTED] A connection arrived, but it was closed while waiting on the listen queue.
連接已到達,但在等待偵聽隊列時已關閉

 

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 選項,或實現某些心跳函數。

 

作者:lzy.je
出處:https://lzy.iteye.com/
本文版權歸作者所有,只允許以摘要和完整全文兩種形式轉載,不允許對文字進行裁剪。未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

 

// 2009.05.20 21:42 添加 ////

 

ENOPROTOOPT

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

 

getsockopt/setsockopt(2) man page 寫道
getsockopt, setsockopt -- get and set options on sockets.

#include <sys/socket.h>

int getsockopt(int socket, int level, int option_name,
void *restrict option_value, socklen_t *restrict option_len);

int setsockopt(int socket, int level, int option_name,
const void *option_value, socklen_t option_len);

Getsockopt() and setsockopt() manipulate the options associated with a socket. Options may exist at multiple protocol levels; they are always present at the 
uppermost "socket" level.

  

 

此外,getsockopt 和 setsockopt 還可能引發以下錯誤:

 

getsockopt/setsockopt(2) man page 寫道
ERRORS

The getsockopt() and setsockopt() system calls will succeed unless:

[EBADF] The argument socket is not a valid file descriptor.
[EFAULT] The address pointed to by option_value is not in a valid part of the process dress space. For getsockopt(), this error may also be returned if option_len is not
in a valid part of the process address space. [EINVAL] The option is invalid at the level indicated. [ENOBUFS]Insufficient memory buffers are available. [ENOPROTOOPT] The option is unknown at the level indicated. [ENOTSOCK] The argument socket is not a socket (e.g., a plain file). The setsockopt() system call will succeed unless: [EDOM] The argument option_value is out of bounds. [EISCONN]socket is already connected and a specified option cannot be set while this is the case.

  

 

// 2009.12.21 16:21 添加 ////

 

          一定要檢查 write 方法的返回值,尤其是服務端程序,當返回 -1 的時候很有可能是“connection reset by peer”(ECONNRESET 104)。如果服務程序沒有處理 SIGPIPE 信號的話,第二次程序在這條已經 close 的 socket 再次 write 時 SIGPIPE 信號就發送到 socket 關聯的 owen 進程,也就是上面說的管道破裂,而該信號的默認處理是結束進程。今天不小心又因為這個浪費了兩小時,在客戶程序連續通信的時候,直接結束客戶進程就造成服務進程也同時退出。開來還是太粗心。

 

  • 大小: 14.1 KB
 
內容來自lzy.je博客,博客鏈接: https://lzy.iteye.com/blog/383884


免責聲明!

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



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