TCP的多次連線

2021-09-02 03:40:06 字數 2473 閱讀 1127

在謝希仁著《計算機網路》第四版中講「三次握手」的目的是「為了防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤」。在另一部經典的《計算機網路》一書中講「三次握手」的目的是為了解決「網路中存在延遲的重複分組」的問題。這兩種不用的表述其實闡明的是同乙個問題。

謝希仁版《計算機網路》中的例子是這樣的,「已失效的連線請求報文段」的產生在這樣一種情況下:client發出的第乙個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是乙個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的乙個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用「三次握手」,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。」。主要目的防止server端一直等待,浪費資源。

為什麼需要「四次揮手」

那可能有人會有疑問,在tcp連線握手時為何ack是和syn一起傳送,這裡ack卻沒有和fin一起傳送呢。原因是因為tcp是全雙工模式,接收到fin時意味將沒有資料再發來,但是還是可以繼續傳送資料。

握手,揮手過程中各狀態介紹:

3次握手過程狀態:

listen: 這個也是非常容易理解的乙個狀態,表示伺服器端的某個socket處於監聽狀態,可以接受連線了。

syn_sent: 當客戶端socket執行connect連線時,它首先傳送syn報文,因此也隨即它會進入到了syn_sent狀態,並等待服務端的傳送三次握手中的第2個報文。syn_sent狀態表示客戶端已傳送syn報文。(傳送端)

syn_rcvd: 這個狀態與syn_sent遙想呼應這個狀態表示接受到了syn報文,在正常情況下,這個狀態是伺服器端的socket在建立tcp連線時的三次握手會話過程中的乙個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了乙個客戶端測試程式,故意將三次tcp握手過程中最後乙個 ack報文不予傳送。因此這種狀態時,當收到客戶端的ack報文後,它會進入到established狀態。(伺服器端)

established:這個容易理解了,表示連線已經建立了。

image

fin_wait_1: 這個狀態要好好解釋一下,其實fin_wait_1和fin_wait_2狀態的真正含義都是表示等待對方的fin報文。而這兩種狀態的區別是:fin_wait_1狀態實際上是當socket在established狀態時,它想主動關閉連線,向對方傳送了fin報文,此時該socket即進入到fin_wait_1狀態。而當對方回應ack報文後,則進入到fin_wait_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ack報文,所以fin_wait_1狀態一般是比較難見到的,而fin_wait_2狀態還有時常常可以用netstat看到。(主動方)

fin_wait_2:上面已經詳細解釋了這種狀態,實際上fin_wait_2狀態下的socket,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ack資訊),稍後再關閉連線。(主動方)

time_wait: 表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果fin_wait_1狀態下,收到了對方同時帶fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態。(主動方)

closing(比較少見): 這種狀態比較特殊,實際情況中應該是很少見,屬於一種比較罕見的例外狀態。正常情況下,當你傳送fin報文後,按理來說是應該先收到(或同時收到)對方的 ack報文,再收到對方的fin報文。但是closing狀態表示你傳送fin報文後,並沒有收到對方的ack報文,反而卻也收到了對方的fin報文。什麼情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close乙個socket的話,那麼就出現了雙方同時傳送fin報文的情況,也即會出現closing狀態,表示雙方都正在關閉socket連線。

close_wait: 這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close乙個socket後傳送fin報文給自己,你系統毫無疑問地會回應乙個ack報文給對方,此時則進入到close_wait狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個socket,傳送fin報文給對方,也即關閉連線。所以你在close_wait狀態下,需要完成的事情是等待你去關閉連線。(被動方)

last_ack: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送fin報文後,最後等待對方的ack報文。當收到ack報文後,也即可以進入到closed可用狀態了。(被動方)

closed: 表示連線中斷。

Android Http連線和TCP連線的區別

最近看到 裡提到某個架構選用tcp連線而不是http連線,意識到自己不知道這兩者的區別,遂查資料補一下知識。再用自己的話總結提煉一下 題目是android http連線和tcp連線的區別,因為我關注的使用場景是android環境,其實不管是android還是pc,應該都是一樣的。http是應用層協議...

TCP連線的實質

三次握手成功後,server端會建立乙個新的socket 包含客戶端ip位址和埠號等資訊 並通過該socket讀取或向client傳送資料。是為建立乙個連線。當斷開連線時,server釋放掉建立的socket資料結構。下次再通訊時,需重新從三次握手開始。所謂長連線,應該也是server端長時間維護該...

tcp的連線斷開

tcp的斷開連線是需要主機完成四次揮手的過程的,並不是斷網了就表示斷開連線了。假如雙方已經建立起了連線,突然一方斷網 比如突然停電,或者網線突然被拔了 對於另一方來講他並不會知道這個情況,他依然認為連線是沒有斷開的。四次揮手的過程是由系統完成的。如果要斷開連線,要麼是程序發起系統呼叫。或者,這個程序...