1. 程式人生 > >tcp 三次握手和四次斷連深入分析:連線狀態和socket API的關係

tcp 三次握手和四次斷連深入分析:連線狀態和socket API的關係

說到tcp協議,凡是稍微看過的人都能順口說出三次握手和四次斷連,再牛逼的一點的就能夠把每個狀態(SYNC_SENT、CLOSE_WAIT。。。。。。等)都能背出來,

而說道socket程式設計,基本上寫過網路程式設計的人都會熟悉那幾個標準的API:socket、connect、listen、accept。。。。。。等

但是,我敢打賭很少有人明白tcp狀態和socket程式設計API之間的關係。不信? 看看如下幾個問題你是否知道吧:

1)什麼時候客戶端才能夠連線上server端, 是server端呼叫bind後還是listen後還是accept後 ?

2)什麼情況下會出現FIN_WAIT_2狀態

。。。。。。。。。。。。。。。。。。。。。

本週打破砂鍋問到底的精神以及實事求是的精神,我用python指令碼寫了一些指令碼測試這些情況,看完後你一定會大呼過癮,對tcp的協議和socket程式設計的理解又更上層樓。

注:以下測試是在Linux(2.6.18)平臺上用python(2.7)指令碼測試,其它平臺沒有測試,有興趣可以自己測試一下。

【連線過程測試和驗證】

第1種情況:client呼叫connect,server只是呼叫了socket + bind,沒有呼叫listen

tcpdump抓包如下:


抓包結果顯示:server端直接回復了RST包

此時使用netstat或者ss命令去檢視,無論是client還是server,都查不到連線

第2種情況:client呼叫connect,server呼叫了socket + bind + listen


tcpdump抓包如下:


抓包結果顯示:三次握手完成

使用ss工具去檢視,client和server都顯示ESTAB

[[email protected] ~]$ ss  -t -n | grep 50000
ESTAB      0      0                10.1.73.45:55354           10.1.73.76:50000 

第3種情況:client呼叫connect + send,server呼叫了socket + bind + listen + accept + recv + send

tcpdump抓包如下:


抓包結果顯示:三次握手完成,並且雙方都可以傳送和接受資料了

使用ss工具去檢視,client和server都顯示ESTAB

[[email protected] ~]$ ss  -t -n | grep 50000
ESTAB      0      0                10.1.73.45:41363           10.1.73.76:50000 

【連線過程總結】

1)可以看到,只有當server端listen之後,client端呼叫connect才能成功,否則就會返回RST響應拒絕連線

2)只有當accept後,client和server才能呼叫recv和send等io操作

3)socket API呼叫錯誤不會導致client出現SYN_SENT狀態,那麼只能是網路裝置丟包(路由器、防火牆)才會導致SYNC_SENT狀態

【斷連過程測試和總結】

第1種情況:client呼叫close,但server沒有呼叫close

tcpdump抓包如下:


抓包結果顯示:client傳送了fin包,server端應答了ack包

使用ss工具去檢視,client顯示FIN_WAIT_2狀態:

[[email protected] ~]$ ss  -t -n | grep "10.1.73.76:50000"
FIN-WAIT-2 0      0                10.1.73.45:47630           10.1.73.76:50000

server顯示CLOSE-WAIT狀態
[[email protected]_test ~]$ ss  -t -n | grep 50000
CLOSE-WAIT 1      0                10.1.73.76:50000           10.1.73.45:47630 
而且有一個值得注意的現象是:client的連線過一段時間就沒有了,而server的連線一直處於CLOSE_WAIT狀態

原因在於Linux系統核心中有一個引數可以控制FIN_WAIT_2的時間:tcp_fin_timeout

第2種情況:client呼叫close,server呼叫close

tcpdump抓包如下:


抓包結果顯示:熟悉的四次斷連來啦

使用ss工具去檢視,client顯示TIME-WAIT狀態

[[email protected] ipv4]$ ss -a -n | grep 50000
TIME-WAIT  0      0                10.1.73.45:39751           10.1.73.76:50000 
server端使用ss工具去看已經看不到連線了

第3種情況:server端被kill了

tcpdump抓包如下:


抓包結果顯示:熟悉的四次斷連來啦

咦,怎麼會和正常的server close一樣呢?答案就在於作業系統的實現:

close函式其實本身不會導致tcp協議棧立刻傳送fin包,而只是將socket檔案的引用計數減1,當socket檔案的引用計數變為0的時候,作業系統會自動關閉tcp連線,此時才會傳送fin包。

這也是多程序程式設計需要特別注意的一點,父程序中一定要將socket檔案描述符close,否則執行一段時間後就可能會出現作業系統提示too many open files

第4種情況:client端呼叫shutdown操作

shutdown操作有三種關閉方式:SHUT_RD、SHUT_WR、SHUT_RDWR,分別測試後發現有趣的現象。

1)如果是SHUT_RD,則tcpdump抓包發現沒有傳送任何包;

2)如果是SHUT_WR或者SHUT_RDWR,則client會發送FIN包給server,

    若server收到後執行close操作,則server傳送FIN給client,最終連線被關閉。

SHUT_WR或者SHUT_RDWR抓包顯示如下:


使用ss命令檢視,client顯示如下:

[[email protected] ~]$ ss -a | grep 50000
TIME-WAIT  0      0              10.1.73.45:45641           10.1.73.76:50000 

server顯示連線已經被關閉了。

關於shutdown的詳細解釋可以參考:http://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html

歸納一下SHUT_RD的處理:

1)client端不再接收資料,如果有新的資料到來,直接丟棄(reject)

2)沒有傳送任何tcp包,所以server端並不知道這個狀態,server端可以繼續傳送資料,但由於1)的原因,發了也白髮

歸納一下SHUT_WR或者SHUT_RDWR的處理:

1)停止傳送資料(不能再呼叫write操作),丟棄緩衝區中未傳送的資料(已呼叫write但底層tcp協議棧還沒傳送的)

2)停止等待已傳送資料的確認訊息,已傳送未確認的資料不再重發

【斷連過程總結】

1)close只是減少socket檔案的引用計數,當計數減為0後,作業系統執行tcp的斷連操作

2)client端close後server端不close,會導致client端連線狀態為FIN_WAIT_2,server端連線狀態為CLOSE_WAIT

     正常程式設計肯定不會這樣處理,一般都是在異常處理跳轉(C++/JAVA等)導致沒有close,或者整個系統異常導致沒有close(例      如JVM記憶體出現out of memory錯誤)

3)shutdown的處理邏輯比較複雜,非特殊情況不要亂用,很容易出問題

4)程序退出後作業系統會自動回收socket,發起tcp關閉流程操作

相關推薦

tcp 握手深入分析連線狀態socket API關係

說到tcp協議,凡是稍微看過的人都能順口說出三次握手和四次斷連,再牛逼的一點的就能夠把每個狀態(SYNC_SENT、CLOSE_WAIT。。。。。。等)都能背出來,而說道socket程式設計,基本上寫過

網路程式設計之——七層模型與TCP握手斷開

轉載請註明出處:https://blog.csdn.net/l1028386804/article/details/83046311 一、C/S架構 客戶端/服務端架構 二、OSI七層架構 七層模型,亦稱OSI(Open System Interconnection)參考模型,是

tcp協議報文握手揮手

tcp報文 三次握手與四次揮手 tcp11種狀態tcp協議:tcp是面向連接、可靠的進程到進程之間的協議。tcp提供全雙工服務:即:數據可在同一時間雙向傳輸。tcp報文段首部格式:各字段含義:源端口號:16位字段,為發送端進程對應的端口號目標端口:16位字段,為接收端進程對應的端口號,接收方接收到數據

TCP握手端口有限狀態

TCP三次握手、四次端口和有限狀態機1、TCP用三次握手(three-way handshake) 一對終端同時初始化一個它們之間的連接是可能的。但通常是由一端打開一個套接字(socket)然後監聽來自另一方的連接,這就是通常所指的被動打開(passive open)。服務器端被被動打開以後,用戶端就能開始創

TCP協議特點握手揮手

TCP的特性 TCP提供一種面向連線的、可靠的位元組流服務 在一個TCP連線中,僅有兩方進行彼此通訊。廣播和多播不能用於TCP TCP使用校驗和,確認和重傳機制來保證可靠傳輸 TCP給資料分節進行排序,並使用累積確認保證資料的順序不變和非重複 TCP使用滑動視窗機制來實現流量控

【前端面試】OSI七層模型TCP握手揮手

osi七層模型: TCP協議頭部的格式 Source Port和DestinationPort:分別佔用16位,表示源埠號和目的埠號;用於區別主機中的不同程序,而IP地址是用來區分不同的主機的,源埠號和目的埠號配合上IP首部中的源IP地址和目的

第五章 運輸層(UDPTCP握手揮手分析

    序言         通過這章,可以知道其實三次握手和四次揮手其實真的好簡單,通過這章的學習,我相信你也會同樣的認為,以後在也不需要聽到別人問三次握手的過程而自己一臉懵逼了,覺得人家好屌,其實也就是他懂你不懂,僅此而已,不懂就去學。學了你就會覺得其實也就那樣,沒有什麼厲害的,這讓我回想以前剛學習程式設

簡述TCP協議的六個標誌位握手揮手的過程及原理

簡述TCP協議的三次握手與四次揮手的過程及原理        今天,我們來分享一下TCP協議的六個標誌位和三次握手與四次揮手的過程及原理。        先介紹一下TCP中的六個控制位,      

簡單說明TCP狀態握手握手

在TCP層,有個FLAGS欄位,這個欄位有以下幾個標識:SYN, FIN, ACK, PSH, RST, URG. 其中,對於我們日常的分析有用的就是前面的五個欄位。  它們的含義是: SYN表示建立連線, FIN表示關閉連線, ACK表示響應, PSH表示有 DATA資料傳輸, RST表示連線重置。  其

TCP握手揮手重要的細節—乾貨滿滿,建議細讀

最近把個人部落格搭建好了,連結在這裡:tobe的囈語,文章會先在部落格和公眾號更新~ 大家多多收藏啊 上一次講了 UDP 協議,從這次開始,就要講 TCP 協議了,因為 TCP 協議涉及到的東西很多,一篇文章概括不完,所以我把 TCP 協議的內容分成好幾個部分,逐個擊破。 TCP 報文段結構 一談到 TCP

簡析TCP握手分手

丟包 現在 流量 tcp連接 首部 都是 字節序 鏈接 暫時 具體的關於TCP是什麽,我不打算詳細的說了;當你看到這篇文章時,我想你也知道TCP的概念了,想要更深入的了解TCP的工作,我們就繼續。它只是一個超級麻煩的協議,而它又是互聯網的基礎,也是每個程序員必備的基本功。首

TCP握手分手

int 有效 tcp三次握手 osi height -1 rcv time 就會 三次握手 解釋:客戶端A和服務器B剛開始處於CLOSED狀態,兩者之間沒有任何聯系,A主動打開,B被動打開由 CLOSED進入LISTEN狀態,這是A發送一個SYN=1的標

TCP協議握手揮手通俗解析

再次 方式 32位 sent 時間 應用層 系統 socket編程 檢測 TCP/IP協議三次握手與四次握手流程解析 一、TCP報文格式 TCP/IP協議的詳細信息參看《TCP/IP協議詳解》三卷本。下面是TCP報文格式圖: 圖1 TCP報文格式 上圖中

如何應對考官的TCP握手&揮手提問?

tcp三次握手&四次揮手 提問 簡述TCP三次握手:簡短回答: 首先A向B發送同步請求SYN, 然後B回復A同步請求應答SYN+ACK, 最後A回復BACK確認。 詳細回答:首先A向B發

TCP握手揮手詳解

socket 抓包 掉線 syn 還要 就是 創建 iss closed TCP三次握手與四次揮手詳解 @(TCP/IP) [TOC] 1.TCP報文格式 TCP(Transmission Control Protocol) 傳輸控制協議。TCP是主機對主機層的傳輸控制協議

TCP握手握手

如果 就是 三次 應用程序 產生 通知 的確 計時器 同時  前言   TCP用於應用程序之間的通信。當應用程序希望通過TCP與另一個應用程序通信時,它會發送一個通信請求。這個請求必須被送到一個確切的地址。在雙方“握手”之後,TCP將在兩個應用程序之間建立一個全雙工的通信

理解TCP/IP握手揮手的正確姿勢

ron eight AI 主動 ddos攻擊 ID set 什麽 方案 背景 和女朋友異地戀一年多,為了保持感情我提議每天晚上視頻聊天一次。 從好上開始,到現在,一年多也算堅持下來了。 問題 有時候聊天的過程中,我的網絡或者她的網絡可能會不好,視頻就會卡住,聽不到對方的聲音

以女朋友為例講解 TCP/IP 握手揮手

seq 關於 轉載 向上 情況 日常 socket 標示 但是 背景 和女朋友異地戀一年多,為了保持感情我提議每天晚上視頻聊天一次。 從好上開始,到現在,一年多也算堅持下來了。 問題 有時候聊天的過程中,我的網絡或者她的網絡可能會不好,視頻就會卡住,聽不到對方的聲音

TCP握手揮手過程

結束 傳輸 tro img 連接 回復 重新 選擇 主動斷開 TCP連接的建立(三次握手) 首先,客戶端與服務器均處於未連接狀態,並且是客戶端主動向服務器請求建立連接:   客戶端將報文段中的SYN=1(同步位),並選擇一個seq=x,(即該請求報文的序號為x) 將這

TCP握手揮手

序號 img 因此 連接重置 .com 也不會 tcp標誌位 失效 gem TCP是主機對主機層的傳輸控制協議,提供可靠的連接服務,采用三次握手確認建立一個連接: 位碼即tcp標誌位,有6種表示: SYN(synchronous建立連接) ACK(acknowledgeme