Posted on 2009-04-29 17:52
Prayer 閱讀(935)
評論(0) 編輯 收藏 引用 所屬分類:
SOCKET
當(dāng)一個進(jìn)程向接收了RST的套接口進(jìn)行寫操作時, 內(nèi)核給該進(jìn)程發(fā)一個SIGPIPE信號。
這個信號默認(rèn)操作就是終止進(jìn)程, 一般寫程序的時候都是屏蔽掉這個信號。
下面是我以前總結(jié)的一些:
原文:http://blog.chinaunix.net/u/6593/showart_304065.html
RST的含義為“復(fù)位”,它是TCP在某些錯誤情況下所發(fā)出的一種TCP分節(jié)。有三個條件可以產(chǎn)生RST:
1), SYN到達(dá)某端口但此端口上沒有正在監(jiān)聽的服務(wù)器。
2), TCP想取消一個已有連接
3), TCP接收了一個根本不存在的連接上的分節(jié)。
1. Connect 函數(shù)返回錯誤ECONNREFUSED:
如果對客戶的SYN的響應(yīng)是RST,則表明該服務(wù)器主機(jī)在我們指定的端口上沒有進(jìn)程在等待與之連接(例如服務(wù)器進(jìn)程也許沒有啟動),這稱為硬錯(hard error),客戶一接收到RST,馬上就返回錯誤ECONNREFUSED.
TCP為監(jiān)聽套接口維護(hù)兩個隊(duì)列。兩個隊(duì)列之和不超過listen函數(shù)第二個參數(shù)backlog。
當(dāng)一個客戶SYN到達(dá)時,若兩個隊(duì)列都是滿的,TCP就忽略此分節(jié),且不發(fā)送RST.這個因?yàn)椋哼@種情況是暫時的,客戶TCP將重發(fā)SYN,期望不久就能在隊(duì)列中找到空閑條目。要是TCP服務(wù)器發(fā)送了一個RST,客戶connect函數(shù)將立即發(fā)送一個錯誤,強(qiáng)制應(yīng)用進(jìn)程處理這種情況,而不是讓TCP正常的重傳機(jī)制來處理。還有,客戶區(qū)別不了這兩種情況:作為SYN的響應(yīng),意為“此端口上沒有服務(wù)器”的RST和意為“有服務(wù)器在此端口上但其隊(duì)列滿”的RST.
Posix.1g允許以下兩種處理方法:忽略新的SYN,或?yàn)榇薙YN響應(yīng)一個RST.歷史上,所有源自Berkeley的實(shí)現(xiàn)都是忽略新的SYN。
2.如果殺掉服務(wù)器端處理客戶端的子進(jìn)程,進(jìn)程退出后,關(guān)閉它打開的所有文件描述符,此時,當(dāng)服務(wù)器TCP接收到來自此客戶端的數(shù)據(jù)時,由于先前打開的那個套接字接口的進(jìn)程已終止,所以以RST響應(yīng)。
經(jīng)常遇到的問題:
如果不判斷read , write函數(shù)的返回值,就不知道服務(wù)器是否響應(yīng)了RST, 此時客戶端如果向接收了RST的套接口進(jìn)行寫操作時,內(nèi)核給該進(jìn)程發(fā)一個SIGPIPE信號。此信號的缺省行為就是終止進(jìn)程,所以,進(jìn)程必須捕獲它以免不情愿地被終止。
進(jìn)程不論是捕獲了該信號并從其信號處理程序返回,還是不理會該信號,寫操作都返回EPIPE錯誤。
3. 服務(wù)器主機(jī)崩潰后重啟
如果服務(wù)器主機(jī)與客戶端建立連接后崩潰,如果此時,客戶端向服務(wù)器發(fā)送數(shù)據(jù),而服務(wù)器已經(jīng)崩潰不能響應(yīng)客戶端ACK,客戶TCP將持續(xù)重傳數(shù)據(jù)分節(jié),試圖從服務(wù)器上接收一個ACK,如果服務(wù)器一直崩潰客戶端會發(fā)現(xiàn)服務(wù)器已經(jīng)崩潰或目的地不可達(dá),但可能需要比較長的時間; 如果服務(wù)器在客戶端發(fā)現(xiàn)崩潰前重啟,服務(wù)器的TCP丟失了崩潰前的所有連接信息,所以服務(wù)器TCP對接收的客戶數(shù)據(jù)分節(jié)以RST響應(yīng)。