1. OSI七層網(wǎng)絡(luò)模型
OSI是Open System Interconnection的縮寫,意為開放式系統(tǒng)互聯(lián)。國際標(biāo)準(zhǔn)化組織(ISO)制定了OSI模型,該模型定義了不同計算機(jī)互聯(lián)的標(biāo)準(zhǔn),是設(shè)計和描述計算機(jī)網(wǎng)絡(luò)通信的基本框架。OSI模型把網(wǎng)絡(luò)通信的工作分為7層,分別是物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會話層、表示層和應(yīng)用層。 首先來看看OSI的七層模型:

2.TCP/IP 參考模型
TCP/IP是傳輸控制協(xié)議/網(wǎng)絡(luò)互聯(lián)協(xié)議的簡稱。早期的TCP/IP模型是一個四層結(jié)構(gòu),從下往上依次是網(wǎng)絡(luò)接口層、互聯(lián)網(wǎng)層、傳輸層和應(yīng)用層。后來在使用過程中,借鑒OSI七層參考模型,將網(wǎng)絡(luò)接口層劃分為了物理層和數(shù)據(jù)鏈路層,形成五層結(jié)構(gòu)。

3. 傳輸層
傳輸層是面向連接的、可靠的的進(jìn)程到進(jìn)程通信的協(xié)議。TCP提供全雙工服務(wù),即數(shù)據(jù)可在同一時間雙向傳播。TCP將若干個字節(jié)構(gòu)成一個分組,此分組稱為報文段(Segment)。提供了一種端到端的連接。 傳輸層的協(xié)議主要是TCP ,TCP(Transimision Control Protocal)是一種可靠的、面向連接的協(xié)議,傳輸效率低。
4. TCP格式

- 源端口號和目標(biāo)端口號,計算機(jī)通過端口號識別訪問哪個服務(wù),比如http服務(wù)或ftp服務(wù),發(fā)送方端口號是進(jìn)行隨機(jī)端口,目標(biāo)端口號決定了接收方哪個程序來接收
- 32位序列號 TCP用序列號對數(shù)據(jù)包進(jìn)行標(biāo)記,以便在到達(dá)目的地后重新重裝,假設(shè)當(dāng)前的序列號為 s,發(fā)送數(shù)據(jù)長度為 l,則下次發(fā)送數(shù)據(jù)時的序列號為 s + l。在建立連接時通常由計算機(jī)生成一個隨機(jī)數(shù)作為序列號的初始值
- 確認(rèn)應(yīng)答號 它等于下一次應(yīng)該接收到的數(shù)據(jù)的序列號。假設(shè)發(fā)送端的序列號為 s,發(fā)送數(shù)據(jù)的長度為 l,那么接收端返回的確認(rèn)應(yīng)答號也是 s + l。發(fā)送端接收到這個確認(rèn)應(yīng)答后,可以認(rèn)為這個位置以前所有的數(shù)據(jù)都已被正常接收。
- 首部長度:TCP 首部的長度,單位為 4 字節(jié)。如果沒有可選字段,那么這里的值就是 5。表示 TCP 首部的長度為 20 字節(jié)。
- 控制位 TCP的連接、傳輸和斷開都受這六個控制位的指揮
- PSH(push急迫位) 緩存區(qū)將滿,立刻傳輸速度
- RST(reset重置位) 連接斷了重新連接
- URG(urgent緊急位) 緊急信號
- ACK(acknowledgement 確認(rèn))為1表示確認(rèn)號
- SYN(synchronous建立聯(lián)機(jī)) 同步序號位 TCP建立連接時要將這個值設(shè)為1
- FIN發(fā)送端完成位,提出斷開連接的一方把FIN置為1表示要斷開連接
- 窗口值 說明本地可接收數(shù)據(jù)段的數(shù)目,這個值的大小是可變的。當(dāng)網(wǎng)絡(luò)通暢時將這個窗口值變大加快傳輸速度,當(dāng)網(wǎng)絡(luò)不穩(wěn)定時減少這個值可以保證網(wǎng)絡(luò)數(shù)據(jù)的可靠傳輸。它是來在TCP傳輸中進(jìn)行流量控制的
- 窗口大?。河糜诒硎緩膽?yīng)答號開始能夠接受多少個 8 位字節(jié)。如果窗口大小為 0,可以發(fā)送窗口探測。
- 效驗和: 用來做差錯控制,TCP校驗和的計算包括TCP首部、數(shù)據(jù)和其它填充字節(jié)。在發(fā)送TCP數(shù)據(jù)段時,由發(fā)送端計算校驗和,當(dāng)?shù)竭_(dá)目的地時又進(jìn)行一次檢驗和計算。如果兩次校驗 和一致說明數(shù)據(jù)是正確的,否則 將認(rèn)為數(shù)據(jù)被破壞,接收端將丟棄該數(shù)據(jù)
- 緊急指針:盡在 URG(urgent緊急) 控制位為 1 時有效。表示緊急數(shù)據(jù)的末尾在 TCP 數(shù)據(jù)部分中的位置。通常在暫時中斷通信時使用(比如輸入 Ctrl + C)。
5. 三次握手
TCP是面向連接的,無論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。在TCP/IP協(xié)議中,TCP 協(xié)議提供可靠的連接服務(wù),連接是通過三次握手進(jìn)行初始化的。三次握手的目的是同步連接雙方的序列號和確認(rèn)號 并交換 TCP窗口大小信息。
為了方便描述我們將主動發(fā)起請求的172.16.17.94:8080 主機(jī)稱為客戶端,將返回數(shù)據(jù)的主機(jī)172.16.17.94:8080稱為服務(wù)器,以下也是。
第一次握手: 建立連接。客戶端發(fā)送連接請求,發(fā)送SYN報文,將seq設(shè)置為0。然后,客戶端進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器的確認(rèn)。
第二次握手: 服務(wù)器收到客戶端的SYN報文段。需要對這個SYN報文段進(jìn)行確認(rèn),發(fā)送ACK報文,將ack設(shè)置為1。同時,自己還要發(fā)送SYN請求信息,將seq為0。服務(wù)器端將上述所有信息一并發(fā)送給客戶端,此時服務(wù)器進(jìn)入SYN_RECV狀態(tài)。
-
第三次握手: 客戶端收到服務(wù)器的ACK和SYN報文后,進(jìn)行確認(rèn),然后將ack設(shè)置為1,seq設(shè)置為1,向服務(wù)器發(fā)送ACK報文段,這個報文段發(fā)送完畢以后,客戶端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài),完成TCP三次握手。
6. 數(shù)據(jù)傳輸
tcpdata.png 客戶端先向服務(wù)器發(fā)送數(shù)據(jù),該數(shù)據(jù)報是長度為159的數(shù)據(jù)。
服務(wù)器收到報文后, 也向客戶端發(fā)送了一個數(shù)據(jù)進(jìn)行確認(rèn)(ACK),并且返回客戶端要請求的數(shù)據(jù),數(shù)據(jù)的長度為111,將seq設(shè)置為1,ack設(shè)置為160(1 + 159)。
客戶端收到服務(wù)器返回的數(shù)據(jù)后進(jìn)行確認(rèn)(ACK),將seq設(shè)置為160, ack設(shè)置為112(1 + 111)。
7. 四次揮手

- 第一次揮手:客戶端向服務(wù)器發(fā)送一個FIN報文段,將設(shè)置seq為160和ack為112,;此時,客戶端進(jìn)入 FIN_WAIT_1狀態(tài),這表示客戶端沒有數(shù)據(jù)要發(fā)送服務(wù)器了,請求關(guān)閉連接;
- 第二次揮手:服務(wù)器收到了客戶端發(fā)送的FIN報文段,向客戶端回一個ACK報文段,ack設(shè)置為1,seq設(shè)置為112;服務(wù)器進(jìn)入了CLOSE_WAIT狀態(tài),客戶端收到服務(wù)器返回的ACK報文后,進(jìn)入FIN_WAIT_2狀態(tài);
- 第三次揮手:服務(wù)器會觀察自己是否還有數(shù)據(jù)沒有發(fā)送給客戶端,如果有,先把數(shù)據(jù)發(fā)送給客戶端,再發(fā)送FIN報文;如果沒有,那么服務(wù)器直接發(fā)送FIN報文給客戶端。請求關(guān)閉連接,同時服務(wù)器進(jìn)入LAST_ACK狀態(tài);
- 第四次揮手:客戶端收到服務(wù)器發(fā)送的FIN報文段,向服務(wù)器發(fā)送ACK報文段,將seq設(shè)置為161,將ack設(shè)置為113,然后客戶端進(jìn)入TIME_WAIT狀態(tài);服務(wù)器收到客戶端的ACK報文段以后,就關(guān)閉連接;此時,客戶端等待2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,客戶端也可以關(guān)閉連接了。
注意:在握手和揮手時確認(rèn)號應(yīng)該是對方序列號加1,傳輸數(shù)據(jù)時則是對方序列號加上對方攜帶應(yīng)用層數(shù)據(jù)的長度。
8. 問題
- 為什么需要三次握手? 確保雙方收發(fā)都是正常的
- 為什么需要四次揮手? 雙方數(shù)據(jù)發(fā)送完畢,都認(rèn)為可以斷開
- 為什么需要等待? A向B發(fā)的
FIN可能丟失 - 為什么握手是三次,但揮手卻是四次? 當(dāng)Server端收到FIN報文時,很可能并不會立即關(guān)閉SOCKET
