TCP客戶端與服務器函數調用過程及特殊情況

基本結構如下圖所示:

一般而言服務器是被動建立連接,服務器調用socket創建套接字,bind給socket分配具體的ip地址以及端口號,再調用listen函數將剛創建好的socket放入監聽隊列,之後調用accept等待指定地址(協議)的客戶端的連接。

客戶端調用socket創建套接字,隨後connect來建立連接,客戶端的socket的bind操作在connect中隱藏完成。

調用connect之後發生“三次握手”建立TCP連接,隨後客戶端與服務器之間開始傳輸數據;

客戶端調用close(),發生“四次揮手”撤銷TCP連接。

特殊情況:

1、在accept返回之前連接終止

由於系統中斷或客戶端傳入RST,解決辦法:再次調用accept即可。因爲TCP連接是在內核之中完成的,與accept函數執行並未干係。

2、服務器進程崩潰(子進程終止)

服務器主動發送FIN關閉TCP連接的服務器端,但實際上是服務器的進程都kill掉了,於是客戶端繼續發送數據,這時候服務器只能響應一個RST,客戶端有可能選擇忽視掉RST信號,而繼續接收數據(例如立刻調用別的讀取數據函數),此時就會返回一個錯誤。

3、服務器主機崩潰(斷網)

一般情況下會一直由TCP重傳機制來不斷重傳,直到超出TCP重傳定時器所設時限。視爲放棄連接,返回服務器不可達錯誤;

也可以使用keep-alive策略;

keepalive,是在TCP中一個可以檢測死連接的機制。

1).如果主機可達,對方就會響應ACK應答,就認爲是存活的。

2).如果可達,但應用程序退出,對方就發RST應答,發送TCP撤消連接。

3).如果可達,但應用程序崩潰,對方就發FIN消息。

4).如果對方主機不響應ack, rst,繼續發送直到超時,就撤消連接。默認兩個小時。

4、服務器主機崩潰後重啓

如果不採用keepalive策略,則重啓後的主機對客戶端發來的數據回報以RST,則跟上述一樣,會得到一個錯誤;

5、服務器主機關機

同;

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