當前位置:
首頁 > 最新 > 使用Wireshark詳解TCP協議

使用Wireshark詳解TCP協議

首先,對於程序員來說,TCP協議很重要。

但網路協議學習起來總像是紙上談兵,我們常說的TCP三次握手建立連接,但具體細節也並不是每個人都講得清楚。

所以,現在我利用Wireshark(著名網路抓包工具)實踐一下來學習分析下TCP協議,希望對你我都有幫助。

本文的內容會包括下面幾個方面:

TCP基礎知識

首部格式分析

三次握手與四次揮手分析

超時重發機制

滑動窗口機制與流量控制、擁塞控制

TCP基礎知識

首先,在七層網路協議中,TCP屬於傳輸層的協議,該層協議常用還有UDP,傳輸層的上層包含應用層、表示層、會話層(這三層可以統稱為應用層,常用的HTTP協議就屬於應用層),下層是網路層(IP協議屬於這一層)。

傳輸層的作用可以簡單這麼理解,比如一個常見的網路請求http:127.0.0.1:80/ 這個uri指定了使用應用層http協議,ip為127.0.0.1。網路層可以幫我們找到這個ip的機器,但這個請求交給誰處理就是傳輸層的協議指定的。埠號就類似於網路層的ip地址鏈路層的mac地址,它用於標識哪個應用程序來處理這個請求,這個例子中是80對應的應用程序處理。

監聽埠的這些進程稱為守護進程,例如httpd(http守護進程),sshd(ssh守護進程)。在UNIX系統並不需要將這些守護進程都啟動進來,而是會啟動一個可以代表它們的超級守護進程,當接收到請求後系統會創建新的進程並轉換為具體的守護進程。

TCP提供可靠的傳輸,會確保數據不會出現丟失,對應的UDP是不可靠的傳輸協議。我們在使用程序開發時,如java有一系列的api可以發送一個TCP和UDP數據包,原因是操作系統提供了一系列的類庫可供java調用。這一系列API叫做套接字(socket),應用程序利用socket可以設置對端ip,埠實現數據傳輸。

首部格式分析

圖1

對應的使用wrieshark抓取一次請求,看一下對應的TCP協議的欄位。下面中括弧內容忽略,不屬於頭部信息。

圖2

欄位解釋:

源/目標埠號:發送端與接收端的埠號,長度都是16位。如wrieshark中看到的是52817與80.

序列號:32位,是指發送數據的位置,每發送一次就累加一次該數據位元組大小。序列號不會從0或1開始,而是在建立連接時系統產生的隨機數。上面wireshark看到的序列號為0是個相對序列號。通過三次握手的第一次的syn包傳給接收端。建立連接與斷開連接時雖然不攜帶數據,但也會作為一個位元組增加對應的序列號。

確認應答號:32位,是指下一次應該收到的數據的序列號,也表示當前已經收到了應答號減1的數據。上面wrieshark中的應答號為0是因為這是首次建立連接的一次tcp傳輸。

數據偏移:表示傳輸的數據從整個tcp包的哪一位開始計算,單位是4位元組,所以也可以認為是首部的大小,所以在wrieshark中叫做headlength.當前這個請求

頭部有44位元組,按圖1算除options和padding外有20位元組,是因為options有24位元組,如圖2。

保留:4位,用於擴展。在圖2中沒有體現

控制位:常用的有ACK,PSH,RST,SYN,FIN

ACK:為1時確認應答欄位才有效,tcp規定除了最初建連的syn包之外該位須為1,圖2是建連的syn包,所以沒有ACK這個控制位。

PSH:為1時表示將收到的數據立刻傳給上層應用協議,為0不需要立即傳先緩存

RST:為1時表示TCP出現異常必須強制斷開連接。

SYN:用於建立連接,為1表示希望建立連接,將在序列號設置初始值。

FIN:為1表示今後不會再有數據發送,希望斷開連接。

窗口大小:指能夠接收的數據大小,如果窗口為0表示可以發送窗口探測。客戶端到服務端與服務端返回這個值一般是不一樣的。窗口相關的知識後面會介紹

校驗和:這一位是為了校驗通信過程中出現位錯誤,用於判斷首部和數據是否被破壞,可以類比於編程時的簽名。

緊急指針:只有在URG控制位為1時才有效,指定數據部分的首位到緊急指針位為緊急數據,如何處理緊急數據是應用程序的事。如telnet時ctrl+c會出現這種包。

選項:用於提高tcp的傳輸性能,可以在數據偏移進行控制。數據偏移-20位元組就是選項的大小了。例如mss選項可以決定傳輸的最大的段長度。

以上是利用wireshark的一個建立連接的syn包分析了tcp報文的首部欄位。

三次握手與四次揮手分析

圖3

上圖是TCP建立連接與斷開連接的三次握手與四次揮手的過程。在wireshark中捕獲一個http請求,並右鍵選擇追蹤流選擇tcp流,可以看到一次http請求的全過程。

圖4

如上圖在HTTP請求之上有三次數據流,觀察控制位與source和dest,可以看到第一個是請求連接的SYN包,相對序列號為0,窗口大小65535. 然後服務端回包控制位為ACK和SYN,表示確認收到請求,並請求連接客戶端,而且確認號為1,表示希望下個收到的包序列號為1,數據傳輸時這個值就不再確認號就不再是1了而是真正的數據大小,序列號為0。客戶端再交發包,控制位為ACK,而且確認號為1,seq也為1,窗口大小也變化了。這就是一次完整的三次握手過程。後面就開始傳輸數據了。

圖4第四行第一次服務端向客戶端數據傳輸如下圖

圖5

服務端第一次數據傳輸,seq為1,ack為85,因為http請求大小為84,所以希望下面收到的seq為85.大小為1428。

圖6

第二次數據傳輸,seq為1429,因為第一次已經傳了1428,由於客戶端還未回復所以ack還是85,本次數據傳輸大小還是1428.

圖7

圖7對應圖4的第7條,是客戶端向服務端發出的確認包,seq是85,符合服務端對客戶端的期望(即圖5,6的ack值為85),ack為2857,表示已經收到了2856個位元組數據(正好等於兩個包的大小),希望下次是收到的seq是2857。

到些已經分析完TCP的三次握手與數據傳輸的過程。

圖8

圖8是斷開連接的過程,首先客戶端向服務端發起了FIN包(含ACK,除了三次握手第一次沒有ACK控制位外,其它所有包都有ACK控制位的),然後服務端回應FIN與ACK,然後客戶端再回應ACK,完成斷開連接,圖8wireshark的過程中只有三個包,而不是常說的四次揮手,這一點有點奇怪,可能是wireshark做了合併處理,將FIN與ACK合併了?

到此完成TCP連接,傳輸,斷開的全過程。TCP就是通過序列號與確認號不斷的累加為提高連接的可靠性的。

超時重發機制

TCP在一定時間內沒有收到對方傳來的ACK包時(看收到的包的seq是不是剛才自己發出的包的ACK的值)會進行重發。

TCP確定超時的時間是有一定的演算法的,而且這個時間是會不斷變化的,unix系統中超時時間最小單位是0.5秒,所以超時時間是0.5的整數倍。如果重發一定次數還是沒收到確認包,會強制關閉連接並且通知應用通信異常強行終止。

滑動窗口機制

首先,TCP在發送數據時是以段為單位的,這個單位值也稱為最大消息長度MSS,確定好了這個值後每次的包傳輸都不會大於這個值。在建立連接時客戶端就會指定一個MSS,然後服務端也會返回一個MSS,然後會在兩者之間選擇小的那個作為確定的段的長度。如圖4指定的是1460,第二條回包的也是1460,所以確定段長為1460,後面的數據傳輸都是1428。可能和第一建連第一步指定的WS為32有關,1460-1428=32。

以一段為單位每發一個段就需要對端返回一次確認,這樣的傳輸缺點就是往返次數會較多,性能低下。所以發送數據包時需要並行進行發送,這就引入了窗口的概念。在發送一個段時不會等待回包確認而是接著發下一個包。

圖9

從圖9可以看出主機A向主機B連續發了1001到2000個包,主機B應答ACK是2001,表示之前的包也都收到了,主機A不需要重發。

從圖4的wireshark中也可以看到,第5,6條服務端連續向客戶端發了兩次,而客戶端只回一次ACK。

滑動窗口使用的不是上面介紹的超時重發機制,而是另一種再高效的重發機制,而且窗口的大小有可能會變化的,有一種窗口探測的包會判斷對端接收的緩存區的大小從而決定設置窗口大小,動態調整滑動窗口大小就是它的流量控制機制。除了流量控制外,TCP還有擁塞控制的機制來保證數據發送的可靠性,擁塞控制主要是防止通信剛開始時TCP就發送了大量數據進來引發問題,因為窗口的流量控制是在發送之後慢慢調整的,而一開始時可能並不能設置一個合理的值。

這就是滑動窗口機制,用於提高數據的傳輸效率。

以上是我學習《圖解TCP/IP》的學習記錄。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 和陌生人說話 的精彩文章:

TAG:和陌生人說話 |