1. TCP定義:
網絡七層模型當中傳輸層的協議主要是TCP ,由IETF的RFC 793定義,TCP(Transimision Control Protocal)是一種可靠的、面向鏈接、基於字節流的通訊協議,傳輸效率低。而傳輸層位於七層模型的中間,下面是網絡層,上面的話有應用層,承上啓下,地位仍是很重要的。在傳輸層中還有一種協議udp(無鏈接、不保證可靠性)。相比較來講tcp有如下特色:html
- 傳輸可靠,數據丟失有重傳機制
- 數據分段打包傳輸,對每一個數據編號,控制順序
- 流量控制,避免擁塞,由於TCP連接雙方有固定大小緩衝空間。TCP的接收端只容許另外一端發送接收端緩衝區所能接納的數據
- TCP提供全雙工服務,即數據可在同一時間雙向傳播。
- TCP將若干個字節構成一個分組,此分組稱爲報文段(Segment)。提供了一種端到端的鏈接。
2. TCP數據包格式
- 源端口號(source port) 和目標端口號(destination port)都是16位,計算機經過端口號識別訪問哪一個服務,好比http服務或ftp服務,其中發送方端口號是是隨機的,而目標端口號決定接受方由那個程序來接受而且由於是16位,因此說程序的最大端口號65535
- 32位序列號(sequence Number) TCP用序列號對數據包進行標記,以便在到達目的地後從新重裝,假設當前的序列號爲 s,發送數據長度爲 l,則下次發送數據時的序列號爲 s + l。在創建鏈接時一般由計算機生成一個隨機數做爲序列號的初始值
- 確認應答號(acknowledgement number) 它等於下一次應該接收到的數據的序列號。假設發送端的序列號爲 s,發送數據的長度爲 l,那麼接收端返回的確認應答號也是 s + l。發送端接收到這個確認應答後,能夠認爲這個位置之前全部的數據都已被正常接收。
- 首部長度(header length):TCP 首部的長度,單位爲 4 字節。若是沒有可選字段,那麼這裏的值就是 5。表示 TCP 首部的長度爲 20 字節。
- 控制位 TCP的鏈接、傳輸和斷開都受這六個控制位的指揮
- PSH(push急迫位) 緩存區將滿,馬上傳輸速度,表示有 DATA數據傳輸
- RST(reset重置位) 鏈接斷了從新鏈接
- URG(urgent緊急位) 緊急信號
- ACK(acknowledgement 確認)爲1表示確認號
- SYN(synchronous創建聯機,在創建TCP鏈接的時候使用) 同步序號位 TCP創建鏈接時要將這個值設爲1
- FIN發送端完成位,表示沒有數據須要發送了,提出斷開鏈接的一方把FIN置爲1表示要斷開鏈接
- 窗口值 說明本地可接收數據段的數目,這個值的大小是可變的。當網絡通暢時將這個窗口值變大加快傳輸速度,當網絡不穩定時減小這個值能夠保證網絡數據的可靠傳輸。它是來在TCP傳輸中進行流量控制的
- 窗口大小(windows):表示接收緩衝區的空閒空間,16位,用來告訴TCP連接另外一端本身可以接收的最大數據長度,流量控制的機制就基於此。
- 效驗和(checksum): 用來作差錯控制,TCP校驗和的計算包括TCP首部、數據和其它填充字節。在發送TCP數據段時,由發送端計算校驗和,當到達目的地時又進行一次檢驗和計算。若是兩次校驗 和一致說明數據是正確的,不然 將認爲數據被破壞,接收端將丟棄該數據
- 緊急指針(urgent):16位,盡在 URG(urgent緊急) 控制位爲 1 時有效。表示緊急數據的末尾在 TCP 數據部分中的位置。一般在暫時中斷通訊時使用(好比輸入 Ctrl + C)。
3. 三次握手
爲了方便描述咱們將主動發起請求的172.16.17.94:8080 主機稱爲客戶端,將返回數據的主機172.16.17.94:8080稱爲服務器,如下也是。windows
- 第一次握手: 創建鏈接。客戶端發送鏈接請求,發送SYN報文,將seq設置爲0。而後,客戶端進入SYN_SEND狀態,等待服務器的確認。
- 第二次握手: 服務器收到客戶端的SYN報文段。須要對這個SYN報文段進行確認,發送ACK報文,將ack設置爲1。同時,本身還要發送SYN請求信息,將seq爲0。服務器端將上述全部信息一併發送給客戶端,此時服務器進入SYN_RECV狀態。
- 第三次握手: 客戶端收到服務器的ACK和SYN報文後,進行確認,而後將ack設置爲1,seq設置爲1,向服務器發送ACK報文段,這個報文段發送完畢之後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。
序列號seq由雙方隨機生成,默認是0;ack = 對方序列號 + 1;seq = 對方的ack 。
緩存
三次握手是爲了確認客戶端和服務器的收發功能都是正常的。第一次確認:客戶端能發;第二次確認:服務器能收能發;第三次確認:客戶端能收。服務器
4. 數據傳輸
- 客戶端先向服務器發送數據,該數據報是長度爲159的數據。
- 服務器收到報文後, 也向客戶端發送了一個數據進行確認(ACK),而且返回客戶端要請求的數據,數據的長度爲111,將seq設置爲1,ack設置爲160(1 + 159)。
- 客戶端收到服務器返回的數據後進行確認(ACK),將seq設置爲160, ack設置爲112(1 + 111)。
ack = 對方的序列號 + 發送的數據長度 ; seq = 對方的ack 。網絡
5. 四次揮手
- 第一次揮手:客戶端向服務器發送一個FIN報文段,將設置seq爲160和ack爲112,;此時,客戶端進入 FIN_WAIT_1狀態,這表示客戶端沒有數據要發送服務器了,請求關閉鏈接;
- 第二次揮手:服務器收到了客戶端發送的FIN報文段,向客戶端回一個ACK報文段,ack設置爲1,seq設置爲112;服務器進入了CLOSE_WAIT狀態,客戶端收到服務器返回的ACK報文後,進入FIN_WAIT_2狀態;
- 第三次揮手:服務器會觀察本身是否還有數據沒有發送給客戶端,若是有,先把數據發送給客戶端,再發送FIN報文;若是沒有,那麼服務器直接發送FIN報文給客戶端。請求關閉鏈接,同時服務器進入LAST_ACK狀態;
- 第四次揮手:客戶端收到服務器發送的FIN報文段,向服務器發送ACK報文段,將seq設置爲161,將ack設置爲113,而後客戶端進入TIME_WAIT狀態;服務器收到客戶端的ACK報文段之後,就關閉鏈接;此時,客戶端等待2MSL後依然沒有收到回覆,則證實Server端已正常關閉,客戶端也能夠關閉鏈接了。
注意:在握手和揮手時確認號應該是對方序列號加1,傳輸數據時則是對方序列號加上對方攜帶應用層數據的長度。 session
6. 問題
- 爲何須要三次握手? 確保雙方收發都是正常的
- 爲何須要四次揮手? 雙方數據發送完畢,都認爲能夠斷開
- 爲何須要等待? A向B發的
FIN
可能丟失
- 爲何握手是三次,但揮手倒是四次? 當Server端收到FIN報文時,極可能並不會當即關閉SOCKET
wireshark抓包工具安裝
wireshark下載地址https://www.wireshark.org/download.html併發
注意:本機訪問本機的服務,wireshark是捕獲不到的。tcp
第一次用wireshark出現這個報錯是由於wireshark沒有裝全,記得裝wincap。工具
wireshark抓包開始
三次握手
172.18.254.177爲客戶 111.13.2.158爲服務端大數據
一、主動打開。發送SYN,協商window size 、TCP MSS seq=0 len=0 MSS=1460 win=65535最大窗口大小
客戶端爲syn_sent
服務端爲syn_recv
二、接收到syn。回覆syn ack seq=0 ack=1=0+1 確認本身的最大win=14480 MSS=1460
客戶端爲established
服務端爲syn_recv
三、接到到syn 回覆ack seq=1 ack=1=0+1 至此三次握手成功創建。
客戶端爲established
服務端爲established
四次斷開
一、主動關閉,發送fin。Seq=328
服務端狀態爲fin_wait1
客戶端狀態爲closed_wait
二、客戶端發送確認ack ack=329=328+1
服務端狀態爲fin_wait2
三、客戶端發送fin seq=133
客戶端狀態爲last_ack
服務端狀態爲time_wait
四、服務端發送ack ack=134=133+1
客戶端狀態closed
服務端狀態closed
數據包ACK=segment len+seq = 下一個要接收的數據包的seq
圖1
圖2
圖3
由圖1 數據包狀況能夠看出 359 seq=1441 segment len=1440 因此下一個回包的ack=1441+1440=2881 從圖2中能夠確認ack確實爲2881.
圖2 數據包狀況能夠看出 360 seq=349 segment len=0 因此下一個回包的ack=349+0=349,從圖3能夠確認ack確實爲349.
圖1 359 的ack=349 則圖2 350 的seq=349 ack=2881 推斷圖3 361的seq=2881 .
一條完整會話(session)指的是,相同的傳輸協議中兩個不一樣IP之間的兩個不一樣端口的互相通訊,若是IP或端口變化剛屬於不一樣的會話,其seq和ack也是相互獨立的,沒有任何關聯。
win 65535:窗口大小是65535字節。窗口大小指的是對方在同一時間點內可以接收到的字節數,網絡帶寬越大窗口越大,能發送的數據就越大。網絡帶寬越小窗口越小,能發送的數據就越小。http協議是83字節。TCP segment len == http len。