小實驗:Broken pipe和Connection Reset by Peer

網絡開發常遇到Broken pipeConnection Reset by Peer兩個錯誤,一直沒有深究其差別,只是籠統的知道是對方關閉了socket,做好異常處理就行.這兩天剛好組員問到,猛地發現我竟無力解釋,決定深究深究

1.基本原理

要說原理嘛,大家都能知道,就是TCP的三次握手四次揮手,關於這個網上圖形解說一大把,隨意搜索,簡述

  • 三次握手

    • client說 SYN, J
    • server說 SYN, ACK J+1, K
    • client說 ACK K+1

    說人話:client發個隨機數J,server返回J+1,並且server發送隨機數K,client返回K+1.

  • 四次揮手

    • client說 FIN M
    • server說 ACK M+1
    • server說 FIN N
    • client說 ACK N+1

    說人話:client說結束,發個隨機數M,server回答可以,回答M+1.此時server已經知道了即將關閉,但是client不知道server收到沒,不會進入關閉動作.爲了防止client傻等,server也會說結束,發個隨機數N,客戶端說太好了,就等你回覆呢,回答N+1

2.reset報文發送場景

  • 嘗試連接未開放的服務器端口,會被直接返回reset
  • 正常交互的雙方,在某個時刻,一方出現異常,會向對方發送reset,通知對方關閉鏈接
  • 收到TCP報文,但不是TCP連接列表可處理的,直接返回reset(可以理解爲直接reset莫名其妙的TCP報文,懶得被幹擾)
  • ack報文丟失,並且重試超過最大嘗試次數,會向對方發送reset,讓對方關閉連接(可以理解爲,網絡太差,我放棄了,你就別掙扎了,咋們斷開連接吧)

3.glibc怎麼說的?

#. TRANS Broken pipe; there is no process reading from the other end of a pipe.
#. TRANS Every library function that returns this error code also generates a
#. TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled
#. TRANS or blocked.  Thus, your program will never actually see @code{EPIPE}
#. TRANS unless it has handled or blocked @code{SIGPIPE}.
#: sysdeps/generic/siglist.h:39 sysdeps/gnu/errlist.c:359
#: sysdeps/unix/siglist.c:39
msgid "Broken pipe"
msgstr "斷開的管道"

#. TRANS A network connection was closed for reasons outside the control of the
#. TRANS local host, such as by the remote machine rebooting or an unrecoverable
#. TRANS protocol violation.
#: sysdeps/gnu/errlist.c:614
msgid "Connection reset by peer"
msgstr ""

4.看不懂glibc,那就動手實驗

寫個socket server, 每次讀取客戶端數據之後,sleep 2秒(時間隨意,別太短,給客戶端留時間關閉連接就行).

寫個socket client,這個client不幹好事,專門向服務器發送一條數據,立即拋異常退出(不走正常的close socket,直接進程退出,故意留給服務器一個壞死的連接)

  • 服務器讀完數據後,繼續讀數據(不斷讀) 此時,拋異常Connection reset by peer

    socket.error: [Errno 104] Connection reset by peer

  • 服務器讀完數據後,連續十次向客戶端寫數據(讀完,就不停寫) 此時,拋異常Broken pipe

    IOError: [Errno 32] Broken pipe

5.結論

對方已經關閉連接(可能意外,也可能正常關閉,總之是關閉了)

  • 嘗試繼續讀取,就會Connection reset by peer
  • 嘗試繼續寫入,就會Broken pipe

若所言有誤,歡迎大神們批評指點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章