一.基本概念
參考:TCP/IP詳解學(xué)習(xí)筆記(1)-基本概念 - 一塊積木 - CSDN博客
參考:全面了解linux TCP/IP協(xié)議棧 - 消磨時間的博客 - CSDN博客
·概念
TCP/IP不是一個協(xié)議,而是一個協(xié)議族的統(tǒng)稱。里面包括了IP協(xié)議,ICMP協(xié)議,TCP協(xié)議,以及我們更加熟悉的http、ftp、pop3協(xié)議等等。
·TCP/IP協(xié)議分層
數(shù)據(jù)鏈路層+網(wǎng)絡(luò)層+傳輸層+應(yīng)用層

二.數(shù)據(jù)鏈路層
參考:TCP/IP詳解學(xué)習(xí)筆記(2)-數(shù)據(jù)鏈路層 - 一塊積木 - CSDN博客
·數(shù)據(jù)鏈路層有三個目的
為IP模塊發(fā)送和 接收IP數(shù)據(jù)報。
為ARP(地址解析協(xié)議)模塊發(fā)送ARP請求和接收ARP應(yīng)答。
為RARP(逆地址解析協(xié)議)發(fā)送RARP請 求和接收RARP應(yīng)答。
·協(xié)議包括
以太網(wǎng)協(xié)議(eth)、令牌環(huán)、PPP、loopback(lo)協(xié)議等。
·關(guān)于MTU
每一種數(shù)據(jù)鏈路層協(xié)議,都有一個MTU(最大傳輸單元)定義。如果IP數(shù)據(jù)報過大,則要進行分片(fragmentation),使得每片都小于MTU。
·關(guān)于環(huán)回接口(loopback)
傳給環(huán)回地址(一般是127.0.0.1)的任何數(shù)據(jù)均作為IP輸入。
傳給廣播地址或多播地址的數(shù)據(jù)報復(fù)制一份傳給環(huán)回接口,然后送到以太網(wǎng)上。這是 因為廣播傳送和多播傳送的定義包含主機本身。
任何傳給該主機IP地址的數(shù)據(jù)均送到環(huán)回接口。
三.IP協(xié)議,ARP協(xié)議,RARP協(xié)議
參考:TCP/IP詳解學(xué)習(xí)筆記(3)-IP協(xié)議,ARP協(xié)議,RARP協(xié)議 - 一塊積木 - CSDN博客
·IP協(xié)議
IP協(xié)議沒有提供一種數(shù)據(jù)未傳達以后的處理機制,是不可靠的。

TTL字段:規(guī)定該數(shù)據(jù)包在穿過多少個路由之后才會被拋棄(這里就體現(xiàn)出來IP協(xié)議包的不可靠性,它不保證數(shù)據(jù)被送達),某個ip數(shù)據(jù)包每穿過一個路由器,該數(shù)據(jù)包的TTL數(shù)值就會減少1,當(dāng)該數(shù)據(jù)包的TTL成為零,它就會被自動拋棄。
·IP路由選擇
最特殊的情況是目的主機和主機直連,那么主機根本不用尋找路由,直接把數(shù)據(jù)傳遞過去就可以了。至于是怎么直接傳遞的,這就要靠ARP協(xié)議了,后面會講到。
稍微一般一點的情況是,主機通過若干個路由器(router)和目的主機連接。那么路由器就要通過ip包的信息來為ip包尋找到一個合適的目標(biāo)來進行傳遞,比如合適的主機,或者合適的路由。路由器或者主機將會用如下的方式來處理某一個IP數(shù)據(jù)包
? ? 如果IP數(shù)據(jù)包的TTL(生命周期)以到,則該IP數(shù)據(jù)包就被拋棄。
? ? 搜索路由表,優(yōu)先搜索匹配主機,如果能找到和IP地址完全一致的目標(biāo)主機,則將該包發(fā)向目標(biāo)主機
? ? 搜索路由表,如果匹配主機失敗,則匹配同子網(wǎng)的路由器,這需要“子網(wǎng)掩碼(1.3.)”的協(xié)助。如果找到路由器,則將該包發(fā)向路由器。
? ? 搜索路由表,如果匹配同子網(wǎng)路由器失敗,則匹配同網(wǎng)號(第一章有講解)路由器,如果找到路由器,則將該包發(fā)向路由器。
? ? 搜索陸游表,如果以上都失敗了,就搜索默認(rèn)路由,如果默認(rèn)路由存在,則發(fā)包
? ? 如果都失敗了,就丟掉這個包。
這再一次證明了,ip包是不可靠的。因為它不保證送達。
·子網(wǎng)尋址
IP地址的定義是網(wǎng)絡(luò)號+主機號。但是現(xiàn)在所有的主機都要求子網(wǎng)編址,也就是說,把主機號在細(xì)分成子網(wǎng)號+主機號。最終一個IP地址就成為 網(wǎng)絡(luò)號碼+子網(wǎng)號+主機號。例如一個B類地址:210.30.109.134。一般情況下,這個IP地址的紅色部分就是網(wǎng)絡(luò)號,而藍色部分就是子網(wǎng)號,綠色部分就是主機號。至于有多少位代表子網(wǎng)號這個問題上,這沒有一個硬性的規(guī)定,取而代之的則是子網(wǎng)掩碼,校園網(wǎng)相信大多數(shù)人都用過,在校園網(wǎng)的設(shè)定里面有一個255.255.255.0的東西,這就是子網(wǎng)掩碼。子網(wǎng)掩碼是由32bit的二進制數(shù)字序列,形式為是一連串的1和一連串的0,例如:255.255.255.0(二進制就是11111111.11111111.11111111.00000000)對于剛才的那個B類地址,因為210.30是網(wǎng)絡(luò)號,那么后面的109.134就是子網(wǎng)號和主機號的組合,又因為子網(wǎng)掩碼只有后八bit為0,所以主機號就是IP地址的后八個bit,就是134,而剩下的就是子網(wǎng)號碼--109。
·ARP協(xié)議
本來主機是完全不知道這個IP對應(yīng)的是哪個主機的哪個接口,當(dāng)主機要發(fā)送一個IP包的時候,會首先查一下自己的ARP高速緩存(就是一個IP-MAC地址對應(yīng)表緩存),如果查詢的IP-MAC值對不存在,那么主機就向網(wǎng)絡(luò)發(fā)送一個ARP協(xié)議廣播包,這個廣播包里面就有待查詢的IP地址,而直接收到這份廣播的包的所有主機都會查詢自己的IP地址,如果收到廣播包的某一個主機發(fā)現(xiàn)自己符合條件,那么就準(zhǔn)備好一個包含自己的MAC地址的ARP包傳送給發(fā)送ARP廣播的主機,而廣播主機拿到ARP包后會更新自己的ARP緩存(就是存放IP-MAC對應(yīng)表的地方)。發(fā)送廣播的主機就會用新的ARP緩存數(shù)據(jù)準(zhǔn)備好數(shù)據(jù)鏈路層的的數(shù)據(jù)包發(fā)送工作。
這樣的高速緩存是有時限的,一般是20分鐘(伯克利系統(tǒng)的衍生系統(tǒng))。
四.ICMP協(xié)議,ping和Traceroute
參考:TCP/IP詳解學(xué)習(xí)筆記(4)-ICMP協(xié)議,ping和Traceroute - 一塊積木 - CSDN博客
·ICMP協(xié)議
當(dāng)傳送IP數(shù)據(jù)包發(fā)生錯誤--比如主機不可達,路由不可達等等,ICMP協(xié)議將會把錯誤信息封包,然后傳送回給主機。給主機一個處理錯誤的機會,這 也就是為什么說建立在IP層以上的協(xié)議是可能做到安全的原因。ICMP數(shù)據(jù)包由8bit的錯誤類型和8bit的代碼和16bit的校驗和組成。而前 16bit就組成了ICMP所要傳遞的信息。
盡管在大多數(shù)情況下,錯誤的包傳送應(yīng)該給出ICMP報文,但是在特殊情況下,是不產(chǎn)生ICMP錯誤報文的。如下
? ? ICMP差錯報文不會產(chǎn)生ICMP差錯報文(出IMCP查詢報文)(防止IMCP的無限產(chǎn)生和傳送)
? ? 目的地址是廣播地址或多播地址的IP數(shù)據(jù)報。
? ? 作為鏈路層廣播的數(shù)據(jù)報。
? ? 不是IP分片的第一片。
? ? 源地址不是單個主機的數(shù)據(jù)報。這就是說,源地址不能為零地址、環(huán)回地址、廣播地 址或多播地址。
雖然里面的一些規(guī)定現(xiàn)在還不是很明白,但是所有的這一切規(guī)定,都是為了防止產(chǎn)生ICMP報文的無限傳播而定義的。
ICMP協(xié)議大致分為兩類,一種是查詢報文,一種是差錯報文。其中查詢報文有以下幾種用途:
? ? ping查詢(不要告訴我你不知道ping程序)
? ? 子網(wǎng)掩碼查詢(用于無盤工作站在初始化自身的時候初始化子網(wǎng)掩碼)
? ? 時間戳查詢(可以用來同步時間)
·ICMP的應(yīng)用--ping
ping這個單詞源自聲納定位,而這個程序的作用也確實如此,它利用ICMP協(xié)議包來偵測另一個主機是否可達。原理是用類型碼為0的ICMP發(fā)請 求,受到請求的主機則用類型碼為8的ICMP回應(yīng)。ping程序來計算間隔時間,并計算有多少個包被送達。用戶就可以判斷網(wǎng)絡(luò)大致的情況。
ping還給我們一個看主機到目的主機的路由的機會。這是因為,ICMP的ping請求數(shù)據(jù)報在每經(jīng)過一個路由器的時候,路由器都會把自己的ip放到該數(shù) 據(jù)報中。而目的主機則會把這個ip列表復(fù)制到回應(yīng)icmp數(shù)據(jù)包中發(fā)回給主機。但是,無論如何,ip頭所能紀(jì)錄的路由列表是非常的有限。
·ICMP的應(yīng)用--Traceroute
Traceroute是用來偵測主機到目的主機之間所經(jīng)路由情況的重要工具,也是最便利的工具。前面說到,盡管ping工具也可以進行偵測,但是,因為ip頭的限制,ping不能完全的記錄下所經(jīng)過的路由器。所以Traceroute正好就填補了這個缺憾。
Traceroute的原理是非常非常的有意思,它受到目的主機的IP后,首先給目的主機發(fā)送一個TTL=1(還記得TTL是什么嗎?)的UDP(后面就 知道UDP是什么了)數(shù)據(jù)包,而經(jīng)過的第一個路由器收到這個數(shù)據(jù)包以后,就自動把TTL減1,而TTL變?yōu)?以后,路由器就把這個包給拋棄了,并同時產(chǎn)生 一個主機不可達的ICMP數(shù)據(jù)報給主機。主機收到這個數(shù)據(jù)報以后再發(fā)一個TTL=2的UDP數(shù)據(jù)報給目的主機,然后刺激第二個路由器給主機發(fā)ICMP數(shù)據(jù) 報。如此往復(fù)直到到達目的主機。這樣,traceroute就拿到了所有的路由器ip。從而避開了ip頭只能記錄有限路由IP的問題。
有人要問,我怎么知道UDP到?jīng)]到達目的主機呢?這就涉及一個技巧的問題,TCP和UDP協(xié)議有一個端口號定義,而普通的網(wǎng)絡(luò)程序只監(jiān)控少數(shù)的幾個號碼較 小的端口,比如說80,比如說23,等等。而traceroute發(fā)送的是端口號>30000(真變態(tài))的UDP報,所以到達目的主機的時候,目的 主機只能發(fā)送一個端口不可達的ICMP數(shù)據(jù)報給主機。主機接到這個報告以后就知道,主機到了,所以,說Traceroute是一個騙子一點也不為過
五.IP選路,動態(tài)選路,和一些細(xì)節(jié)
參考: TCP/IP詳解學(xué)習(xí)筆記(5)-IP選路,動態(tài)選路,和一些細(xì)節(jié) - 一塊積木 - CSDN博客
六.UDP協(xié)議
參考: TCP/IP詳解學(xué)習(xí)筆記(6)-UDP協(xié)議 - 一塊積木 - CSDN博客
·UDP簡要介紹
UDP是傳輸層協(xié)議,和TCP協(xié)議處于一個分層中,但是與TCP協(xié)議不同,UDP協(xié)議并不提供超時重傳,出錯重傳等功能,也就是說其是不可靠的協(xié)議。?
·UDP協(xié)議頭

UDP可以很長很長,可以有65535字節(jié)那么長。但是一般網(wǎng)絡(luò)在傳送的時候,一次一般傳送不了那么長的協(xié)議(涉及到MTU的問題),就只好對數(shù)據(jù)分片,當(dāng)然,這些是對UDP等上級協(xié)議透明的,UDP不需要關(guān)心IP協(xié)議層對數(shù)據(jù)如何分片。
·IP分片
IP在從上層接到數(shù)據(jù)以后,要根據(jù)IP地址來判斷從那個接口發(fā)送數(shù)據(jù)(通過選路),并進行MTU的查詢,如果數(shù)據(jù)大小超過MTU就進行數(shù)據(jù)分片。數(shù)據(jù)的分片是對上層和下層透明,而數(shù)據(jù)也只是到達目的地還會被重新組裝,不過不用擔(dān)心,IP層提供了足夠的信息進行數(shù)據(jù)的再組裝。
在IP頭里面,16bit識別號唯一記錄了一個IP包的ID,具有同一個ID的IP片將會被重新組裝;而13位片偏移則記錄了某IP片相對整個包的位置;而這兩個表示中間的3bit標(biāo)志則標(biāo)示著該分片后面是否還有新的分片。這三個標(biāo)示就組成了IP分片的所有信息,接受方就可以利用這些信息對IP數(shù)據(jù)進行重新組織(就算是后面的分片比前面的分片先到,這些信息也是足夠了)。
因為分片技術(shù)在網(wǎng)絡(luò)上被經(jīng)常的使用,所以偽造IP分片包進行流氓攻擊的軟件和人也就層出不窮。
可以用Trancdroute程序來進行簡單的MTU偵測。
※IP協(xié)議報文可參考上面第三章。
·UDP和ARP之間的交互式用
當(dāng)ARP緩存還是空的時候。UDP在被發(fā)送之前一定要發(fā)送一個ARP請求來獲得目的主機的MAC地址,如果這個UDP的數(shù)據(jù)包足夠大,大到IP層一定要對其進行分片的時候,想象中,該UDP數(shù)據(jù)包的第一個分片會發(fā)出一個ARP查詢請求,所有的分片都輝等到這個查詢完成以后再發(fā)送。事實上是這樣嗎?
結(jié)果是,某些系統(tǒng)會讓每一個分片都發(fā)送一個ARP查詢,所有的分片都在等待,但是接受到第一個回應(yīng)的時候,主機卻只發(fā)送了最后一個數(shù)據(jù)片而拋棄了其他,這實在是讓人匪夷所思。這樣,因為分片的數(shù)據(jù)不能被及時組裝,接受主機將會在一段時間內(nèi)將永遠(yuǎn)無法組裝的IP數(shù)據(jù)包拋棄,并且發(fā)送組裝超時的ICMP報文(其實很多系統(tǒng)不產(chǎn)生這個差錯),以保證接受主機自己的接收端緩存不被那些永遠(yuǎn)得不到組裝的分片充滿。
·ICMP源站抑制差錯
當(dāng)目標(biāo)主機的處理速度趕不上數(shù)據(jù)接收的速度,因為接受主機的IP層緩存會被占滿,所以主機就會發(fā)出一個“我受不了”的一個ICMP報文。
·UDP服務(wù)器設(shè)計
UDP協(xié)議的某些特性將會影響我們的服務(wù)器程序設(shè)計,大致總結(jié)如下:
? ? 關(guān)于客戶IP和地址:服務(wù)器必須有根據(jù)客戶IP地址和端口號判斷數(shù)據(jù)包是否合法的能力(這似乎要求每一個服務(wù)器都要具備)
? ? 關(guān)于目的地址:服務(wù)器必須要有過濾廣播地址的能力。
? ? 關(guān)于數(shù)據(jù)輸入:通常服務(wù)器系統(tǒng)的每一個端口號都會和一塊輸入緩沖區(qū)對應(yīng),進來的輸入根據(jù)先來后到的原則等待服務(wù)器的處理,所以難免會出現(xiàn)緩沖區(qū)溢出的問題,這種情況下,UDP數(shù)據(jù)包可能會被丟棄,而應(yīng)用服務(wù)器程序本身并不知道這個問題。
? ? 服務(wù)器應(yīng)該限制本地IP地址,就是說它應(yīng)該可以把自己綁定到某一個網(wǎng)絡(luò)接口的某一個端口上。
七.????廣播和多播,IGMP協(xié)議
參考:TCP/IP詳解學(xué)習(xí)筆記(7)-廣播和多播,IGMP協(xié)議 - 一塊積木 - CSDN博客
八.DNS域名系統(tǒng)
參考:TCP/IP詳解學(xué)習(xí)筆記(8)-DNS域名系統(tǒng) - 一塊積木 - CSDN博客
九.TCP協(xié)議概述
參考: TCP/IP詳解學(xué)習(xí)筆記(9)-TCP協(xié)議概述 - 一塊積木 - CSDN博客
TCP和UDP處在同一層---運輸層,但是TCP和UDP最不同的地方是,TCP提供了一種可靠的數(shù)據(jù)傳輸服務(wù),TCP是面向連接的。所以TCP要比UDP可靠的多,UDP是把數(shù)據(jù)直接發(fā)出去,而不管對方是不是在收信,就算是UDP無法送達,也不會產(chǎn)生ICMP差錯報文。
TCP保證可靠性的簡單工作原理摘抄如下
? ? 應(yīng)用數(shù)據(jù)被分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊。這和UDP完全不同,應(yīng)用程序產(chǎn)生的數(shù)據(jù)報長度將保持不變。由TCP傳遞給IP的信息單位稱為報文段或段( segment)。
? ? 當(dāng)TCP發(fā)出一個段后,它啟動一個定時器,等待目的端確認(rèn)收到這個報文段。如果不能及時收到一個確認(rèn),將重發(fā)這個報文段。
? ? 當(dāng)TCP收到發(fā)自TCP連接另一端的數(shù)據(jù),它將發(fā)送一個確認(rèn)。這個確認(rèn)不是立即發(fā)送,通常將推遲幾分之一秒。
? ? TCP將保持它首部和數(shù)據(jù)的檢驗和。這是一個端到端的檢驗和,目的是檢測數(shù)據(jù)在傳輸 過程中的任何變化。如果收到段的檢驗和有差錯, TCP將丟棄這個報文段和不確認(rèn)收到此報文段(希望發(fā)端超時并重發(fā))。
? ? 既然TCP報文段作為IP數(shù)據(jù)報來傳輸,而IP數(shù)據(jù)報的到達可能會失序,因此TCP報文段 的到達也可能會失序。如果必要, TCP將對收到的數(shù)據(jù)進行重新排序,將收到的數(shù)據(jù)以正確的順序交給應(yīng)用層。
? ? TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機致使較慢主機的緩沖區(qū)溢出。
TCP中保持可靠性的方式就是超時重發(fā),這是有道理的,雖然TCP也可以用各種各樣的ICMP報文來處理這些,但是這也不是可靠的,最可靠的方式就是只要不得到確認(rèn),就重新發(fā)送數(shù)據(jù)報,直到得到對方的確認(rèn)為止。
可以想象一個TCP數(shù)據(jù)的發(fā)送應(yīng)該是如下的一個過程。
? ? 雙方建立連接(三次握手)
? ? 發(fā)送方給接受方TCP數(shù)據(jù)報,然后等待對方的確認(rèn)TCP數(shù)據(jù)報,如果沒有,就重新發(fā),如果有,就發(fā)送下一個數(shù)據(jù)報。
? ? 接受方等待發(fā)送方的數(shù)據(jù)報,如果得到數(shù)據(jù)報并檢驗無誤,就發(fā)送ACK(確認(rèn))數(shù)據(jù)報,并等待下一個TCP數(shù)據(jù)報的到來。直到接收到FIN(發(fā)送完成數(shù)據(jù)報)
? ? 中止連接(四次揮手)
可以想見,為了建立一個TCP連接,系統(tǒng)可能會建立一個新的進程(最差也是一個線程),來進行數(shù)據(jù)的傳送。

參考:TCP三次握手及四次揮手詳解及常見面試題 - ZWE7616175的博客 - CSDN博客
1. 源端口號:表示發(fā)送端端口號,字段長為16位。
2. 目標(biāo)端口號:表示接收端口號,字段長為16位。
3. 序列號:表示發(fā)送數(shù)據(jù)的位置,字段長為32位。每發(fā)送一次數(shù)據(jù),就累加一次該數(shù)據(jù)字節(jié)數(shù)的大小。
注意:序列號不會從0或1開始,而是在建立連接時由計算機生成的一個隨機數(shù)作為其初始值,通過SYN包發(fā)送給接收端主機。然后再將每轉(zhuǎn)發(fā)過去的字節(jié)數(shù)累加到初始值上表示數(shù)據(jù)的位置。
4. 確認(rèn)應(yīng)答號:表示下一次應(yīng)該收到的數(shù)據(jù)的序列號,字段長為32字節(jié)。發(fā)送端收到這個確認(rèn)應(yīng)答以后可以認(rèn)為在這個序號以前的數(shù)據(jù)都已經(jīng)被正常接收。
序號的優(yōu)點:
(1)保證報文按序到達。
(2)保證可靠性。
(3)保證效率。
(4)精準(zhǔn)的報告哪些報文已經(jīng)收到,哪些需要重傳。
首部長度:該字段長度為4位,單位為4字節(jié)(32位)。TCP首部長度不包括選項的話,是20個字節(jié),20/4=5,5的二進制序列:0101,報頭長度也叫數(shù)據(jù)偏移,所以該字段可以設(shè)置為5,選項字段最大的是40字節(jié),所以,TCP首部長度為最大為20+40=60字節(jié),該字段可以設(shè)置的最大長度為60/4=15。
保留:該字段主要是為了以后擴展時使用,其長度為4位。一般設(shè)置為0,即使收到的包在該字段不為0,此包也不會丟棄。
控制位:字段長為6,每一位從左到右分別為:URG、ACK、PSH、RST、SYN、FIN。當(dāng)對應(yīng)的值為1,表示有具體含義。

8. 窗口大?。航邮站彌_區(qū)的大小,TCP不允許發(fā)送超過此處所示大小的數(shù)據(jù)。
9. 校驗和:發(fā)送端填充,CRC校驗,接收校驗不通過,則認(rèn)為數(shù)據(jù)有問題。和UDP的區(qū)別是,UDP校驗的是數(shù)據(jù)本身,TCP校驗的不僅包含TCP首部,而且包含TCP數(shù)據(jù)部分。
10. 緊急指針:只有在URG為1時有效,該字段為1表示本報文的段中的緊急數(shù)據(jù)的指針。
11. 選項:用于提高TCP的傳輸性能。需要根據(jù)首部長度進行控制,其最大長度為40字節(jié)。
十.TCP連接的建立與中止
參考:TCP三次握手及四次揮手詳解及常見面試題 - ZWE7616175的博客 - CSDN博客
參考:Socket 之a(chǎn)ccept與三次握手的關(guān)系 - 水果刀的專欄 - CSDN博客
1. 序列號seq
占4個字節(jié),用來標(biāo)記數(shù)據(jù)段的順序,TCP把連接中發(fā)送的所有數(shù)據(jù)字節(jié)都編上一個序號,第一個字節(jié)的編號由本地隨機產(chǎn)生,給字節(jié)編上序號后,就給每一個報文段指派一個序號,序列號seq就是這個報文段中的第一個字節(jié)的數(shù)據(jù)編號。
2. 確認(rèn)號ack
占4個字節(jié),期待收到對方下一個報文段的第一個數(shù)據(jù)字節(jié)的序號,序列號表示報文段攜帶數(shù)據(jù)的第一個字節(jié)的編號,而確認(rèn)號指的是期望接受到下一個字節(jié)的編號,因此擋墻報文段最后一個字節(jié)的編號+1即是確認(rèn)號。
3. 確認(rèn)ACK
占1個比特位,僅當(dāng)ACK=1,確認(rèn)號字段才有效。ACK=0,確認(rèn)號無效。
4. 同步SYN
連接建立時用于同步序號。當(dāng)SYN=1,ACK=0表示:這是一個連接請求報文段。若同意連接,則在響應(yīng)報文段中使用SYN=1,ACK=1.因此,SYN=1表示這是一個連接請求,或連接接收報文,SYN這個標(biāo)志位只有在TCP建立連接才會被置為1,握手完成后SYN標(biāo)志位被置為0.
5. 終止FIN
用來釋放一個 TCP三次握手以及四次揮手的過程

三次握手的過程
step1:第一次握手
建立連接時,客戶端發(fā)送SYN包到服務(wù)器,其中包含客戶端的初始序號seq=x,并進入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn)。(其中,SYN=1,ACK=0,表示這是一個TCP連接請求數(shù)據(jù)報文;序號seq=x,表明傳輸數(shù)據(jù)時的第一個數(shù)據(jù)字節(jié)的序號是x)。
step2:第二次握手
服務(wù)器收到請求后,必須確認(rèn)客戶的數(shù)據(jù)包。同時自己也發(fā)送一個SYN包,即SYN+ACK包,此時服務(wù)器進入SYN_RECV狀態(tài)。(其中確認(rèn)報文段中,標(biāo)識位SYN=1,ACK=1,表示這是一個TCP連接響應(yīng)數(shù)據(jù)報文,并含服務(wù)端的初始序號seq(服務(wù)器)=y,以及服務(wù)器對客戶端初始序號的確認(rèn)號ack(服務(wù)器)=seq(客戶端)+1=x+1)。
step3:第三次握手
客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送一個序列號(seq=x+1),確認(rèn)號為ack(客戶端)=y+1,此包發(fā)送完畢,客戶端和服務(wù)器進入ESTAB_LISHED(TCP連接成功)狀態(tài),完成三次握手。
未連接隊列
在三次握手協(xié)議中,服務(wù)器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設(shè)一個條目,該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認(rèn),正在等待客戶的確認(rèn)包時,刪除該條目,服務(wù)器進入ESTAB_LISHED狀態(tài)。
三次握手與socket的accept的關(guān)系
服務(wù)器調(diào)用listen進行監(jiān)聽
客戶端調(diào)用connect來發(fā)送syn報文
服務(wù)器協(xié)議棧負(fù)責(zé)三次握手的交互過程。連接建立后,往listen隊列中添加一個成功的連接,直到隊列的最大長度
服務(wù)器調(diào)用accept從listen隊列中取出一條成功的tcp連接,listen隊列中的連接個數(shù)就少一個
四次揮手的過程
step1:第一次揮手
首先,客戶端發(fā)送一個FIN,用來關(guān)閉客戶端到服務(wù)器的數(shù)據(jù)傳送,然后等待服務(wù)器的確認(rèn)。其中終止標(biāo)志位FIN=1,序列號seq=u。
step2:第二次揮手
服務(wù)器收到這個FIN,它發(fā)送一個ACK,確認(rèn)ack為收到的序號加一。
step3:第三次揮手
關(guān)閉服務(wù)器到客戶端的連接,發(fā)送一個FIN給客戶端。
step4:第四次揮手
客戶端收到FIN后,并發(fā)回一個ACK報文確認(rèn),并將確認(rèn)序號seq設(shè)置為收到序號加一。首先進行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方執(zhí)行被動關(guān)閉。
客戶端發(fā)送FIN后,進入終止等待狀態(tài),服務(wù)器收到客戶端連接釋放報文段后,就立即給客戶端發(fā)送確認(rèn),服務(wù)器就進入CLOSE_WAIT狀態(tài),此時TCP服務(wù)器進程就通知高層應(yīng)用進程,因而從客戶端到服務(wù)器的連接就釋放了。此時是“半關(guān)閉狀態(tài)”,即客戶端不可以發(fā)送給服務(wù)器,服務(wù)器可以發(fā)送給客戶端。
此時,如果服務(wù)器沒有數(shù)據(jù)報發(fā)送給客戶端,其應(yīng)用程序就通知TCP釋放連接,然后發(fā)送給客戶端連接釋放數(shù)據(jù)報,并等待確認(rèn)??蛻舳税l(fā)送確認(rèn)后,進入TIME_WAIT狀態(tài),但是此時TCP連接還沒有釋放,然后經(jīng)過等待計時器設(shè)置的2MSL后,才進入到CLOSE狀態(tài)。
關(guān)于2MSL時間?
首先,MSL即Maximum Segment Lifetime,就是最大報文生存時間,是任何報文在網(wǎng)絡(luò)上的存在的最長時間,超過這個時間報文將被丟棄?!禩CP/IP詳解》中是這樣描述的:MSL是任何報文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長時間。RFC 793中規(guī)定MSL為2分鐘,實際應(yīng)用中常用的是30秒、1分鐘、2分鐘等。
TCP的TIME_WAIT需要等待2MSL,當(dāng)TCP的一端發(fā)起主動關(guān)閉,三次揮手完成后發(fā)送第四次揮手的ACK包后就進入這個狀態(tài),等待2MSL時間主要目的是:防止最后一個ACK包對方?jīng)]有收到,那么對方在超時后將重發(fā)第三次握手的FIN包,主動關(guān)閉端接到重發(fā)的FIN包后可以再發(fā)一個ACK應(yīng)答包。在TIME_WAIT狀態(tài)時兩端的端口不能使用,要等到2MSL時間結(jié)束才可以繼續(xù)使用。當(dāng)連接處于2MSL等待階段時任何遲到的報文段都將被丟棄。
11種狀態(tài)遷移


十一.TCP交互數(shù)據(jù)流,成塊數(shù)據(jù)流
參考: TCP/IP詳解學(xué)習(xí)筆記(11)-TCP交互數(shù)據(jù)流,成塊數(shù)據(jù)流 - 一塊積木 - CSDN博客
參考:TCP滑動窗口與擁塞窗口 - Android developer. - CSDN博客

十二.TCP的超時與重傳
參考: TCP/IP詳解學(xué)習(xí)筆記(12)-TCP的超時與重傳 - 一塊積木 - CSDN博客
參考:TCP超時重傳、滑動窗口、擁塞控制、快重傳和快恢復(fù) - 紫魔戒 - CSDN博客
超時重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的另一個重要機制,其原理是在發(fā)送某一個數(shù)據(jù)以后就開啟一個計時器,在一定時間內(nèi)如果沒有得到發(fā)送的數(shù)據(jù)報的ACK報文,那么就重新發(fā)送數(shù)據(jù),直到發(fā)送成功為止。
計時器的使用
一個連接中,有且僅有一個測量定時器被使用。也就是說,如果TCP連續(xù)發(fā)出3組數(shù)據(jù),只有一組數(shù)據(jù)會被測量。
ACK數(shù)據(jù)報不會被測量,原因很簡單,沒有ACK的ACK回應(yīng)可以供結(jié)束定時器測量。
TCP超時重傳
原理是在發(fā)送某一個數(shù)據(jù)以后就開啟一個計時器,在一定時間內(nèi)如果沒有得到發(fā)送的數(shù)據(jù)報的ACK報文,那么就重新發(fā)送數(shù)據(jù),直到發(fā)送成功為止。
影響超時重傳機制協(xié)議效率的一個關(guān)鍵參數(shù)是重傳超時時間(RTO,Retransmission TimeOut)。RTO的值被設(shè)置過大過小都會對協(xié)議造成不利影響。
?。?)RTO設(shè)長了,重發(fā)就慢,沒有效率,性能差。
?。?)RTO設(shè)短了,重發(fā)的就快,會增加網(wǎng)絡(luò)擁塞,導(dǎo)致更多的超時,更多的超時導(dǎo)致更多的重發(fā)。
連接往返時間(RTT,Round Trip Time),指發(fā)送端從發(fā)送TCP包開始到接收它的立即響應(yīng)所消耗的時間。
TCP滑動窗口
作用:(1)提供TCP的可靠性;(2)提供TCP的流控特性

TCP的滑動窗口的可靠性也是建立在“確認(rèn)重傳”基礎(chǔ)上的。
發(fā)送窗口只有收到對端對于本段發(fā)送窗口內(nèi)字節(jié)的ACK確認(rèn),才會移動發(fā)送窗口的左邊界。
接收端可以根據(jù)自己的狀況通告窗口大小,從而控制發(fā)送端的接收,進行流量控制。
TCP擁塞控制
擁塞控制是一個全局性的過程;? 流量控制是點對點通信量的控制
TCP擁塞控制4個核心算法:慢開始(slow start)、擁塞避免(Congestion Avoidance)、快速重傳(fast retransmit)、快速回復(fù)(fast recovery)
擁塞窗口(cwnd,congestion window),其大小取決于網(wǎng)絡(luò)的擁塞程度,并且動態(tài)地在變化。
慢開始算法的思路就是,不要一開始就發(fā)送大量的數(shù)據(jù),先探測一下網(wǎng)絡(luò)的擁塞程度,也就是說由小到大逐漸增加擁塞窗口的大小。
為了防止cwnd增長過大引起網(wǎng)絡(luò)擁塞,還需設(shè)置一個慢開始門限ssthresh狀態(tài)變量。ssthresh的用法如下:?
當(dāng)cwnd < ssthresh時,使用慢開始算法。?
當(dāng)cwnd > ssthresh時,改用擁塞避免算法。?
當(dāng)cwnd = ssthresh時,慢開始與擁塞避免算法任意。
擁塞避免算法讓擁塞窗口緩慢增長,即每經(jīng)過一個往返時間RTT就把發(fā)送發(fā)的擁塞窗口cwnd加1,而不是加倍。
無論是在慢開始階段還是在擁塞避免階段,只要發(fā)送方判斷網(wǎng)絡(luò)出現(xiàn)擁塞,就把慢開始門限設(shè)置為出現(xiàn)擁塞時的發(fā)送窗口大小的一半。然后把擁塞窗口設(shè)置為1,執(zhí)行慢開始算法。如下圖:

擁塞控制的具體過程如下:
(1)TCP連接初始化,將擁塞窗口設(shè)置為1
(2)執(zhí)行慢開始算法,cwnd按指數(shù)規(guī)律增長,直到cwnd=ssthresh時,開始執(zhí)行擁塞避免算法,cwnd按線性規(guī)律增長
(3)當(dāng)網(wǎng)絡(luò)發(fā)生擁塞,把ssthresh值更新為擁塞前ssthresh值的一半,cwnd重新設(shè)置為1,按照步驟(2)執(zhí)行
快重傳和快恢復(fù)
快速重傳(Fast retransmit)要求接收方在收到一個失序的報文段后就立即發(fā)出重復(fù)確認(rèn)(為的是使發(fā)送方及早知道有報文段沒有到達對方),而不要等到自己發(fā)送數(shù)據(jù)時捎帶確認(rèn)。
快重傳算法規(guī)定,發(fā)送方只要一連收到3個重復(fù)確認(rèn)就應(yīng)當(dāng)立即重傳對方尚未收到的報文段,而不必繼續(xù)等待設(shè)置的重傳計數(shù)器時間到期。
快速恢復(fù)(Fast Recovery)
?。?)當(dāng)發(fā)送方連續(xù)收到三個重復(fù)確認(rèn),就執(zhí)行“乘法減小”算法,把慢開始門限ssthresh減半。這是為了預(yù)防網(wǎng)絡(luò)發(fā)生擁塞。請注意:接下去不執(zhí)行慢開始算法。
? (2)由于發(fā)送方現(xiàn)在認(rèn)為網(wǎng)絡(luò)很可能沒有發(fā)生擁塞,因此與慢開始不同之處是現(xiàn)在不執(zhí)行慢開始算法(即擁塞窗口cwnd現(xiàn)在不設(shè)置為1),而是把cwnd值設(shè)置為慢開始門限ssthresh減半后的數(shù)值,然后開始執(zhí)行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。
發(fā)送方窗口的上限值 = Min [ rwnd, cwnd ]
當(dāng)rwnd (接收窗口)< cwnd 時,是接收方的接收能力限制發(fā)送方窗口的最大值。
當(dāng)cwnd < rwnd 時,則是網(wǎng)絡(luò)的擁塞限制發(fā)送方窗口的最大值。
ICMP會引起重新傳遞么?
答案是:不會,TCP會堅持用自己的定時器,但是TCP會保留下ICMP的錯誤并且通知用戶。
重新分組
TCP為了提高自己的效率,允許再重新傳輸?shù)臅r候,只要傳輸包含重傳數(shù)據(jù)報文的報文就可以,而不用只重傳需要傳輸?shù)膱笪摹?/p>
十三.TCP堅持定時器,TCP?;疃〞r器
參考: TCP/IP詳解學(xué)習(xí)筆記(13)-TCP堅持定時器,TCP保活定時器 - 一塊積木 - CSDN博客
參考:解讀TCP 四種定時器 - 孟環(huán)標(biāo) - 博客園
對于每個連接,TCP 管理著四個不同的定時器:重傳定時器、堅持定時器、?;疃〞r器 以及 2MSL 定時器。
堅持定時器
堅持定時器的原理是簡單的,當(dāng)TCP服務(wù)器收到了客戶端的0滑動窗口報文的時候,就啟動一個定時器來計時,并在定時器溢出的時候向向客戶端查詢窗口是否已經(jīng)增大,如果得到非零的窗口就重新開始發(fā)送數(shù)據(jù),如果得到0窗口就再開一個新的定時器準(zhǔn)備下一次查詢。通過觀察可以得知,TCP的堅持定時器使用1,2,4,8,16……64秒這樣的普通指數(shù)退避序列來作為每一次的溢出時間。
當(dāng)堅持計時器截止期到時,發(fā)送端就發(fā)送一個特殊的報文段,叫探測報文段,這個報文段只有一個字節(jié)的數(shù)據(jù)。探測報文段有序號,但序號永遠(yuǎn)不需要確認(rèn),甚至在計算對其他部分?jǐn)?shù)據(jù)的確認(rèn)時這個序號也被忽略。探測報文段提醒接收端,確認(rèn)已丟失,必須重傳。
糊涂窗口綜合癥
TCP的窗口協(xié)議,會引起一種通常叫做糊涂窗口綜合癥的問題,具體表現(xiàn)為,當(dāng)客戶端通告一個小的非零窗口時,服務(wù)器立刻發(fā)送小數(shù)據(jù)給客戶端并充滿其緩沖區(qū),一來二去就會讓網(wǎng)絡(luò)中充滿小TCP數(shù)據(jù)報,從而影響網(wǎng)絡(luò)利用率。對于發(fā)送方和接收端的這種糊涂行為。TCP給出了一些建議(或者是規(guī)定)。
接收方不通告小窗口。通常的算法是接收方不通告一個比當(dāng)前窗口大的窗口(可以為0),除非窗口可以增加一個報文段大小(也就是將要接收的MSS)或者可以增加接收方緩存空間的一半,不論實際有多少。
? ? 發(fā)送方避免出現(xiàn)糊涂窗口綜合癥的措施是只有以下條件之一滿足時才發(fā)送數(shù)據(jù): ( a )可以發(fā)送一個滿長度的報文段; ( b )可以發(fā)送至少是接收方通告窗口大小一半的報文段; ( c )可以發(fā)送任何數(shù)據(jù)并且不希望接收ACK(也就是說,我們沒有還未被確認(rèn)的數(shù)據(jù))或者該連接上不能使用Nagle算法。
ok,現(xiàn)在我們回憶一下,可以發(fā)現(xiàn)TCP的很多規(guī)定都是為了在一次傳送中發(fā)送盡量多的數(shù)據(jù),例如捎帶ACK數(shù)據(jù)報文的策略,Nagle算法,重傳時發(fā)送包含原數(shù)據(jù)報文的策略,等等。
?;疃〞r器
保活定時器是為了應(yīng)對 TCP 連接雙方出現(xiàn)長時間的沒有數(shù)據(jù)傳輸?shù)那闆r。如果客戶端與服務(wù)器建立了 TCP 連接之后,客戶端由于某種原因?qū)е轮鳈C故障,則服務(wù)器就不能收到來自客戶端的數(shù)據(jù),而服務(wù)器不可能一直處于等待狀態(tài),?;疃〞r器就是用來解決這個問題的。服務(wù)器每收到一次客戶端的數(shù)據(jù),就重新設(shè)置?;疃〞r器,通常為 2 小時,如果 2 小時沒有收到客戶端的數(shù)據(jù),服務(wù)端就發(fā)送一個探測報文,以后每隔75秒發(fā)送一次,如果連續(xù)發(fā)送10次探測報文段后仍沒有收到客戶端的響應(yīng),服務(wù)器就認(rèn)為客戶端出現(xiàn)了故障,就可以終止這個連接。
2MSL 定時器
2MSL 定時器主要是解決以下兩種情況:
TIME_WAIT 確保有足夠的時間讓對端收到了ACK,如果被動關(guān)閉的那方?jīng)]有收到 ACK,就會觸發(fā)被動端重發(fā) FIN。因為最后一次確認(rèn)應(yīng)答 ACK 報文段很有可能丟失,因而使被動關(guān)閉方處于在LIST_ACK 狀態(tài)的,此時被動關(guān)閉方會重發(fā)這個 FIN+ACK 報文段,在這等待的 2MSL 時間內(nèi)主動關(guān)閉方重新收到這個被動關(guān)閉方重發(fā)的 FIN+ACK 報文段,因此,主動關(guān)閉方會重新發(fā)送確認(rèn)應(yīng)答信息,從而重新啟動 2MSL 計時器,直到通信雙方都進入 CLOSED 狀態(tài)。如果主動關(guān)閉方在 TIME_WAIT 狀態(tài)不等待一段時間就直接釋放連接并進入 CLOSED 狀態(tài),那么主動關(guān)閉方無法收到來自被動關(guān)閉方重發(fā)的 FIN+ACK 報文段,也就不會再發(fā)送一次確認(rèn) ACK 報文段,因此被動關(guān)閉方就無法正常進入CLOSED 狀態(tài)。
有足夠的時間讓這個連接不會跟后面的連接混在一起。防止已失效的請求連接出現(xiàn)在本連接中。在連接處于 2MSL 等待時,任何遲到的報文段將被丟棄,因為處于 2MSL等待的、由該插口(插口是IP和端口對的意思,socket)定義的連接在這段時間內(nèi)將不能被再用,這樣就可以使下一個新的連接中不會出現(xiàn)這種舊的連接之前延遲的報文段。
十四.TCP連接的未來和性能
參考: TCP/IP詳解學(xué)習(xí)筆記(14)-TCP連接的未來和性能(未寫完) - 一塊積木 - CSDN博客
十五.TCP與UDP的區(qū)別
參考:TCP和UDP的區(qū)別和優(yōu)缺點 - xiaobangkuaipao的博客 - CSDN博客
TCP與UDP區(qū)別總結(jié)
TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發(fā)送數(shù)據(jù)之前不需要建立連接
TCP提供可靠的服務(wù)。也就是說,通過TCP連接傳送的數(shù)據(jù),無差錯,不丟失,不重復(fù),且按序到達;UDP盡最大努力交付,即不保證可靠交付
UDP具有較好的實時性,工作效率比TCP高,適用于對高速傳輸和實時性有較高的通信或廣播通信。
每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信
TCP對系統(tǒng)資源要求較多,UDP對系統(tǒng)資源要求較少。
為什么UDP有時比TCP更有優(yōu)勢?
UDP以其簡單、傳輸快的優(yōu)勢,在越來越多場景下取代了TCP,如實時游戲。
(1)網(wǎng)速的提升給UDP的穩(wěn)定性提供可靠網(wǎng)絡(luò)保障,丟包率很低,如果使用應(yīng)用層重傳,能夠確保傳輸?shù)目煽啃浴?/p>
(2)TCP為了實現(xiàn)網(wǎng)絡(luò)通信的可靠性,使用了復(fù)雜的擁塞控制算法,建立了繁瑣的握手過程,由于TCP內(nèi)置的系統(tǒng)協(xié)議棧中,極難對其進行改進。
采用TCP,一旦發(fā)生丟包,TCP會將后續(xù)的包緩存起來,等前面的包重傳并接收到后再繼續(xù)發(fā)送,延時會越來越大,基于UDP對實時性要求較為嚴(yán)格的情況下,采用自定義重傳機制,能夠把丟包產(chǎn)生的延遲降到最低,盡量減少網(wǎng)絡(luò)問題對游戲性造成影響。