TCP連線 ESTALISHED 後的各種情況

2021-07-14 21:30:04 字數 1854 閱讀 5124

tcp 資料傳輸過程圖

參考:執行服務端(為每個客戶端fork子程序服務) 和 乙個客戶端,可以看到 服務端的父程序和子程序

如下圖,找到服務端子程序的pid, 直接kill掉

kill 子程序後,子程序相關的開啟描述符都會被關閉,這就導致向客戶端傳送乙個fin, 而客戶tcp則響應以乙個ack, 這是tcp連線終止(四次握手)的前半部分。

在服務端,設定了程序kill掉的訊號,當$kill後,會立即看到

signal傳送給服務端父程序,得到正確處理(可以看到child terminated 被列印出來)

服務端主動關閉連線,會向客戶端傳送乙個fin, 客戶端接收來自服務端的fin並響應乙個ack, 但自己是阻塞在fgets呼叫上,此時客戶端還沒有傳送fin。

john@ubuntu

:~$ netstat -a | grep 9877

tcp 0

0 *:

9877 *:*

listen

tcp 0

0localhost:

9877

localhost:

59644

fin_wait2

tcp 1

0localhost:

59644

localhost:

9877

close_wait

服務端子程序 fin_wait2(主動關閉的一方收到對方的ack後,等待對方傳送fin)

客戶端 close_wait (被動關閉的一方,傳送了fin後處於 close_wait 狀態,等待關閉連線)

客戶端仍在執行阻塞在fgets上,我們接著輸入一段文字,給服務端,發現接收不到任何結果了

sudo tcpdump -i lo # tcpdump檢視資料報

在完成tcp結束連線(四次握手)的前半部分後,客戶端可以繼續傳送資料(而此時服務端已經結束)因為客戶端收到服務端傳送過來的fin後,服務端並沒有告訴客戶端自己已經終止了, 所以客戶端可以傳送資料,只是得不到響應而已。

所以我們想要的是:一旦伺服器程序死掉了,客戶端應該立刻收到fin,並且自己不再傳送資料

服務端和客戶端成功連線,能相互傳送資料,此時若伺服器突然不可達(如網路中斷了)。這時客戶端傳送資料,將阻塞在read呼叫(一直等待服務端應答。。。)上。

客戶tcp持續重傳資料分節,源自berkeley的實現重傳該資料分節12次,共等待約9分鐘後,才放棄重傳。

客戶端最終知道 伺服器不可達,顯然9分鐘比較長,我們可以在read呼叫設定乙個超時。

當然如果客戶端沒有給伺服器傳送資料,怎麼知道伺服器已經不可達了呢?so_keepalive套接字?

unix系統關機 會產生訊號,伺服器主機會關閉其所有開啟描述符,其所有子程序也將關閉。這樣之後的情況將如同tcp伺服器程序突然終止一樣,我們仍然需要使得伺服器程序的終止一旦發生,客戶端能夠立刻檢測到

關閉tcp連線

luolei localhost sudo netstat a grep ssh tcp 0 0 192.168.1.10 40278 com ssh established unix 2 acc stream listening 7565 tmp ssh uyvolk4882 agent.4882...

TCP長短連線

tcp 長短連線 1 什麼是 tcp長連線 從應用層來看,就是 client 到server 建立一次連線,傳送多個資料報,直到不再與 server 通訊時關閉連線。connect send recv send recv close。從傳輸層來看,使用的是 keep alive timer 實現 t...

Tcp 斷開連線

tcp協議規定,對於已經建立的連線,網路雙方要進行四次握手才能成功斷開連線,如果缺少了其中某個步驟,將會使連線處於假死狀態,連線本身占用的資源不會被釋放。網路伺服器程式要同時管理大量連線,所以很有必要保證無用連線完全斷開,否則大量僵死的連線會浪費許多伺服器資源。在眾多tcp狀態中,最值得注意的狀態有...