EINTR:
阻塞的操做被取消阻塞的調用打斷。如設置了發送接收超時,就會遇到這種錯誤。
只能針對阻塞模式的socket。讀,寫阻塞的socket時,-1返回,錯誤號爲INTR。另外,若是出現EINTR即errno爲4,錯誤描述Interrupted system call,操做也應該繼續。若是recv的返回值爲0,那代表鏈接已經斷開,接收操做也應該結束。
ETIMEOUT:
一、操做超時。通常設置了發送接收超時,遇到網絡繁忙的狀況,就會遇到這種錯誤。
二、服務器作了讀數據作了超時限制,讀時發生了超時。
三、錯誤被描述爲「connect time out」,即「鏈接超時」,這種狀況通常發生在服務器主機崩潰。此時客戶 TCP 將在必定時間內(依具體實現)持續重發數據分節,試圖從服務 TCP 得到一個 ACK 分節。當最終放棄嘗試後(此時服務器未從新啓動),內核將會向客戶進程返回 ETIMEDOUT 錯誤。若是某個中間路由器斷定該服務器主機已經不可達,則通常會響應「destination unreachable」-「目的地不可達」的ICMP消息,相應的客戶進程返回的錯誤是 EHOSTUNREACH 或ENETUNREACH。當服務器從新啓動後,因爲 TCP 狀態丟失,以前全部的鏈接信息也不存在了,此時對於客戶端發來請求將回應 RST。若是客戶進程對檢測服務器主機是否崩潰頗有必要,要求即便客戶進程不主動發送數據也能檢測出來,那麼須要使用其它技術,如配置 SO_KEEPALIVE Socket 選項,或實現某些心跳函數。
EAGAIN:
一、Send返回值小於要發送的數據數目,會返回EAGAIN和EINTR。
二、recv 返回值小於請求的長度時說明緩衝區已經沒有可讀數據,但再讀不必定會觸發EAGAIN,有可能返回0表示TCP鏈接已被關閉。
三、當socket是非阻塞時,如返回此錯誤,表示寫緩衝隊列已滿,能夠作延時後再重試.
四、在Linux進行非阻塞的socket接收數據時常常出現Resource temporarily unavailable,errno代碼爲11(EAGAIN),代表在非阻塞模式下調用了阻塞操做,在該操做沒有完成就返回這個錯誤,這個錯誤不會破壞socket的同步,不用管它,下次循環接着recv就能夠。對非阻塞socket而言,EAGAIN不是一種錯誤。
EWOULDBLOCK:EAGAIN (POSIX.1-2001 allows)
資源暫時不可用。這個錯誤是從對非阻塞socket進行的不能當即結束的操做返回的,如當沒有數據在隊列中能夠讀時,調用recv。並非fatal錯誤,稍後操做能夠被重複。調用在一個非阻塞的SOCK_STREAM socket 上調用connect時會產生這個錯誤,由於有時鏈接創建必須消耗必定的時間。
EPIPE:
一、Socket 關閉,可是socket號並無置-1。繼續在此socket上進行send和recv,就會返回這種錯誤。這個錯誤會引起SIGPIPE信號,系統會將產生此EPIPE錯誤的進程殺死。因此,通常在網絡程序中,首先屏蔽此消息,以避免發生不及時設置socket進程被殺死的狀況。
二、write(..) on a socket that has been closed at the other end will cause a SIGPIPE.
三、錯誤被描述爲「broken pipe」,即「管道破裂」,這種狀況通常發生在客戶進程不理會(或未及時處理)Socket 錯誤,繼續向服務 TCP 寫入更多數據時,內核將向客戶進程發送 SIGPIPE 信號,該信號默認會使進程終止(此時該前臺進程未進行 core dump)。結合上邊的 ECONNRESET 錯誤可知,向一個 FIN_WAIT2 狀態的服務 TCP(已 ACK 響應 FIN 分節)寫入數據不成問題,可是寫一個已接收了 RST 的 Socket 則是一個錯誤。
ECONNREFUSED:
一、拒絕鏈接。通常發生在鏈接創建時。
拔服務器端網線測試,客戶端設置keep alive時,recv較快返回0, 先收到ECONNREFUSED (Connection refused)錯誤碼,其後都是ETIMEOUT。
二、an error returned from connect(), so it can only occur in a client (if a client is defined as the party that initiates the connection
ECONNRESET:
一、在客戶端服務器程序中,客戶端異常退出,並無回收關閉相關的資源,服務器端會先收到ECONNRESET錯誤,而後收到EPIPE錯誤。
二、鏈接被遠程主機關閉。有如下幾種緣由:遠程主機中止服務,從新啓動;當在執行某些操做時遇到失敗,由於設置了「keep alive」選項,鏈接被關閉,通常與ENETRESET一塊兒出現。
三、遠程端執行了一個「hard」或者「abortive」的關閉。應用程序應該關閉socket,由於它再也不可用。當執行在一個UDP socket上時,這個錯誤代表前一個send操做返回一個ICMP「port unreachable」信息。
四、若是client關閉鏈接,server端的select並不出錯(不返回-1,使用select對惟一一個socket進行non- blocking檢測),可是寫該socket就會出錯,用的是send.錯誤號:ECONNRESET.讀(recv)socket並無返回錯誤。
五、該錯誤被描述爲「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」-「服務器過早終止」錯誤。
ECONNABORTED:
一、軟件致使的鏈接取消。一個已經創建的鏈接被host方的軟件取消,緣由多是數據傳輸超時或者是協議錯誤。
二、該錯誤被描述爲「software caused connection abort」,即「軟件引發的鏈接停止」。緣由在於當服務和客戶進程在完成用於 TCP 鏈接的「三次握手」後,客戶 TCP 卻發送了一個 RST (復位)分節,在服務進程看來,就在該鏈接已由 TCP 排隊,等着服務進程調用 accept 的時候 RST 卻到達了。POSIX 規定此時的 errno 值必須 ECONNABORTED。源自 Berkeley 的實現徹底在內核中處理停止的鏈接,服務進程將永遠不知道該停止的發生。服務器進程通常能夠忽略該錯誤,直接再次調用accept。
當TCP協議接收到RST數據段,表示鏈接出現了某種錯誤,函數read將以錯誤返回,錯誤類型爲ECONNERESET。而且之後全部在這個套接字上的讀操做均返回錯誤。錯誤返回時返回值小於0。 服務器
(1) 若是客戶機TCP協議沒有接收到對它的SYN數據段的確認,函數以錯誤返回,錯誤類型爲ETIMEOUT。一般TCP協議在發送SYN數據段失敗以後,會屢次發送SYN數據段,在全部的發送都高中失敗以後,函數以錯誤返回。
注:SYN(synchronize)位:請求鏈接。TCP用這種數據段向對方TCP協議請求創建鏈接。在這個數據段中,TCP協議將它選擇的初始序列號通知對方,而且與對方協議協商最大數據段大小。SYN數據段的序列號爲初始序列號,這個SYN數據段可以被確認。當協議接收到對這個數據段的確認以後,創建TCP鏈接。
(2) 若是遠程TCP協議返回一個RST數據段,函數當即以錯誤返回,錯誤類型爲ECONNREFUSED。當遠程機器在SYN數據段指定的目的端口號處沒有服務進程在等待鏈接時,遠程機器的TCP協議將發送一個RST數據段,向客戶機報告這個錯誤。客戶機的TCP協議在接收到RST數據段後再也不繼續發送SYN數據段,函數當即以錯誤返回。
注:RST(reset)位:表示請求重置鏈接。當TCP協議接收到一個不能處理的數據段時,向對方TCP協議發送這種數據段,表示這個數據段所標識的鏈接出現了某種錯誤,請求TCP協議將這個鏈接清除。有3種狀況可能致使TCP協議發送RST數據段:(1)SYN數據段指定的目的端口處沒有接收進程在等待;(2)TCP協議想放棄一個已經存在的鏈接;(3)TCP接收到一個數據段,可是這個數據段所標識的鏈接不存在。接收到RST數據段的TCP協議當即將這條鏈接非正常地斷開,並嚮應用程序報告錯誤。
(3) 若是客戶機的SYN數據段致使某個路由器產生「目的地不可到達」類型的ICMP消息,函數以錯誤返回,錯誤類型爲EHOSTUNREACH或ENETUNREACH。一般TCP協議在接收到這個ICMP消息以後,記錄這個消息,而後繼續幾回發送SYN數據段,在全部的發送都告失敗以後,TCP協議檢查這個ICMP消息,函數以錯誤返回。
注:ICMP:Internet 消息控制協議。Internet的運行主要是由Internet的路由器來控制,路由器完成IP數據包的發送和接收,若是發送數據包時發生錯誤,路由器使用 ICMP協議來報告這些錯誤。
調用函數connect的過程當中,當客戶機TCP協議發送了SYN數據段的確認以後,TCP狀態由CLOSED狀態轉爲SYN_SENT狀態,在接收到對 SYN數據段的確認以後,TCP狀態轉換成ESTABLISHED狀態,函數成功返回。若是調用函數connect失敗,應該用close關閉這個套接字描述符,不能再次使用這個套接字描述符來調用函數connect。
connect函數的出錯處理:
(1)ETIMEOUT-connection timed out 目的主機不存在,沒有返回任何相應,例如主機關閉
(2)ECONNREFUSED-connection refused(硬錯)到達目的主機後,因爲各類緣由創建不了鏈接,主機返回RST(復位)響應,例如主機監聽進程未啓用,tcp取消鏈接等
(3)EHOSTTUNREACH-no route to host(軟錯)路由上引起了一個目的地不可達的ICMP錯誤
其中(1)(3),客戶端會進行定時屢次重試,必定次數後才返回錯誤。另外,當connect鏈接失敗時,sockfd套接口不可用,必須關閉後從新socket分配才行。 網絡