不抓包,如何学得了 TCP
Wireshark
本機ip: 192.168.0.72
訪問地址: [http://www.cnblogs.com/tankxiao]()
記錄378,419,427就對應著著名的TCP三次握手
數據幀格式如下
三次握手流程圖
SYN:建立連接
FIN:關閉連接
ACK:響應
PSH:數據傳輸
RST:連接重制
A->B:在嗎?聽的到嗎?
B->A:在啊?你聽得到嗎?(告訴A,通過B的回復來確認,A->B通信正常)
A->B:聽的見(告訴B,通過A的回復來確認,B->A通信正常)
第一次握手
客戶端向服務端建立連接的信號 Syn = 1,seq 為隨機數
圖中 Sequence number: 0 (relative sequence number),反映的是相對seq
真實的 seq 在圖中下部分,用16進制 "532d0c99"表示,轉換成10進制為 "1395461273"
第二次握手
服務端向客戶端發送響應 Ack = seq(來自客戶端,1395461273) + 1,Syn = 1,seq 為隨機數
圖中 Acknowledgment number: 1 (relative ack number),反映的是相對Ack
真實的 ack 在圖中下部分,用16進制"532d0c9a"表示,轉換成10進制為 "1395461274"
同理 seq "96fb78d2" 的10進制為 "2533062866"
第三次握手
客戶端向服務端發送響應 Ack = seq (來自服務端,2533062866) + 1,seq 為隨機數
圖中 Ack 的16進制為"96fb78d3",轉換成10進制為"2533062867"
圖中 seq 的16進制為"532d0c9a",轉換成10進制為"1395461274"
至此以后,客戶端就可以愉快地和服務端通信了
為什么是三次握手
“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段并沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。于是就向client發出確認報文段,同意建立連接。假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由于現在client并沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,并一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由于收不到確認,就知道client并沒有要求建立連接。”摘自謝希仁著《計算機網絡》
傳輸過程
TCP維持數據不丟失的關鍵在于Seq和Ack
在18.443018時,客戶端向服務端發送數據包P1,內容是發送http請求,Seq = 1,Len = 1083,命名為數據包P1
在18.469641時,服務端告訴客戶端數據包P1已經收到, Ack = 數據包P1的Seq + 數據包P1的Len
在18.495616時,服務端向客戶端發送數據包P2,內容是html文檔,Seq = 1, Len = 1452
在18.495617時,服務端向客戶端發送數據包P3,內容仍是html文檔,Seq = 1453,Len = 133
在18.495680時,客戶端告訴服務端數據包P3已經收到,Ack = 數據包P3的Seq + 數據包P3的Len
TCP提供的確認機制,可以在通信過程中可以不對每一個TCP數據包發出單獨的確認包(Delayed ACK機制),而是在傳送數據時,順便把確認信息傳出, 這樣可以大大提高網絡的利用率和傳輸效率。同時,TCP的確認機制,也可以一次確認多個數據報,例如,接收方收到了201,301,401的數據報,則只 需要對401的數據包進行確認即可,對401的數據包的確認也意味著401之前的所有數據包都已經確認,這樣也可以提高系統的效率。
在18.496954-18.496961期間,服務端發送了5個數據包,其中最后一個數據包是響應頭,"HTTP/1.1 200 OK..."
在18.497018-18.499389期間,客戶端對發來的數據包進行確認
Seq 與 Ack 的關系
發送數據包,數據的序號Seq和數據的長度Len
確認包,Ack = 收到的最后的數據包的序號Seq+Len,
同時因為作為確認包,在服務端與客戶端交換數據的過程中,沒有向服務端發送數據,所以 Seq 不變
在某種程度上可以這樣理解Seq和Ack,在發送這個包之前,我已經向對方發送的數據量Seq,我已經接受到的數據量Ack
四次揮手
為什么建立連接協議是三次握手,而關閉連接是四次握手
這是因為服務端的LISTEN狀態下的SOCKET當收到SYN報文的連接請求后,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文里來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之后,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這里的ACK報文和FIN報文多數情況下都是分開發送的。由于TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務后就能發送一個FIN來終止這個方向的連接。收到一個 FIN只意味著這一方向上沒有數據流動,一個TCP連接在收到一個FIN后仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
(1)客戶端A發送一個FIN,用來關閉客戶A到服務器B的數據傳送。
(2)服務器B收到這個FIN,它發回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將占用一個序號。
(3)服務器B關閉與客戶端A的連接,發送一個FIN給客戶端A。
(4)客戶端A發回ACK報文確認,并將確認序號設置為收到序號加1。
A->B:我對你已經沒話說了
B->A:我知道你對我沒話說了
B->A:我對你也沒話說了
A->B:我知道你對我也沒話說了
TCP和UDP的區別
參考資料
- Wireshark基本介紹和學習TCP三次握手
- TCP三次握手四次揮手詳解
總結
以上是生活随笔為你收集整理的不抓包,如何学得了 TCP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WiFi Deauthenticated
- 下一篇: TCP:SEQ号与ACK号