作者: famdestiny ?時間: 2008-09-18 16:59:00
1、在accept函數返回前連接夭折
這種情況發生在TCP 3次握手剛好完成,服務器TCP將連接放入到已經建立好連接隊列中,此時客戶端給一個RST,接下來accept返回,不過這時accept返回的是ECONNECTABORT錯誤.這不是一個致命錯誤。
2、服務器進程終止
過程如下:
a、kill掉服務進程,作為進程善后處理的部分,所有打開的文件描述符被關閉,這導致服務端TCP(注意"服務端"和"服務端TCP"是不同概念)發送FIN給客戶端,客戶端TCP響應以ACK。
b、客戶端此時正阻塞在scanf函數(基于上篇中提到的客戶端模型),這導致客戶端不知道服務端TCP已經關閉連接。
c、客戶端在scanf返回后調用write向服務端發數據,由于服務端已經被kill掉,所以服務端TCP會發送一個RST給客戶端TCP.
d、客戶端在發送完數據后立即調用read讀取數據,由于有第一步的FIN,read立即返回0(表示EOF),然而客戶端希望的是收到剛才發送的數據而不是EOF。如果客戶端接著往服務端發數據,將誘發服務端TCP向服務端發送SIGPIPE信號,因為向接收到RST的套接口寫數據都會收到此信號.
問題的本質在于客戶端同時處理兩個描述字--套接口和用戶輸入,程序被單純地阻塞在一個源上了。這個問題可以通過1、設置非阻塞模式。2、采用select以及epoll處理。
3、服務器主機崩潰
在客戶TCP發送數據后,由于接收不到ACK,它將試圖一直重傳,直到最后放棄,并返回給客戶進程一個出錯信息。ETIMEOUT表示沒有相應,EHOSTUNREACH表示路由器判定主機不可達。
4、服務器崩潰后重啟
由于服務端TCP丟失了以前的連接信息,這將導致服務端發送一個RST,而此時客戶端阻塞在read函數,這將導致返回一個ECONNECTRESET錯誤.
5、服務器關機
服務器關機時init進程會先發送SIGTERM(此信號可捕獲)給所有進程,再過一段時間發送SIGKILL(次信號不可捕獲)給仍然在運行的程序,這時就和服務器進程終止一樣了。
?