你知道嗎?如何學(xué)習(xí)TCP協(xié)議
TCP協(xié)議目前是事實上的網(wǎng)絡(luò)基礎(chǔ)。許多更高層的應(yīng)用協(xié)議HTTP,FTP都基于TCP。
TCP協(xié)議的學(xué)習(xí)可以說枯燥無比,尤其是學(xué)生階段,根本不知道用在什么地方,根本不知道重要性是什么。事實上是,基于目前的網(wǎng)絡(luò)發(fā)展和分布式發(fā)展,TCP簡直就是基礎(chǔ)中的基礎(chǔ)。許多網(wǎng)絡(luò)的問題,配置,入侵,防御乃至架構(gòu),都涉及到TCP的具體應(yīng)用及機制。
以下是我總結(jié)的TCP學(xué)習(xí)過程,
1、了解學(xué)習(xí)TCP協(xié)議的重要性和必要性,了解TCP協(xié)議為什么被發(fā)展出來
2、學(xué)習(xí)TCP協(xié)議的三次握手以及四次揮手,重點了解為什么要三次握手,為什么要四次揮手,在整個過程中狀態(tài)是如何變遷的。(經(jīng)典的狀態(tài)圖以及握手揮手圖)
a、為什么要三次握手?不是一次,兩次或者四次。我們來論證一下,如果只有一次會發(fā)生什么情況,a向b發(fā)起連接請求,假設(shè)b沒收到,則b其實完全不知道a發(fā)起了請求,而a也完全不知道b收沒收到,所以一次握手是不可靠的;如果兩次握手呢,a向b發(fā)起連接請求,b收到a的請求給a回復(fù)一個請求,假設(shè)此時a收到了b的回復(fù),a知道了b已經(jīng)ready了,可b完全不知道a是否ready,有可能a并沒有收到b的請求,也有可能收到了,但這些b都完全不知道,所以只是單向的建立了連接;如果是四次握手呢,其實第2次讓a知道b ready了,第三次讓b知道a也ready了,第四次完全就是多余了,會浪費網(wǎng)絡(luò)資源。
b、為什么要四次揮手?不是3次?實際上兩邊連接完全可以分開看,用2次揮手?jǐn)嚅_其中一邊連接,用另外2次揮手?jǐn)嚅_另一邊的連接,最終完成整個連接關(guān)閉。之所以這樣設(shè)計,是因為有可能某一邊數(shù)據(jù)還未傳輸完,連接還未關(guān)閉。因為TCP被設(shè)計為全雙工協(xié)議,可以任何一邊單向發(fā)送數(shù)據(jù)。
1、握手及揮手過程
2、TCP的狀態(tài)轉(zhuǎn)換圖
3、學(xué)習(xí)TCP協(xié)議是如何保持可靠性設(shè)計的。
主要目的是用來參考,以便在其他通信場合時用作架構(gòu)和設(shè)計的參考
1)包應(yīng)答序列號及包重組。
面臨的問題:網(wǎng)絡(luò)傳輸中,會出現(xiàn)數(shù)據(jù)的破壞,丟包,重復(fù),分片混亂等問題。
本質(zhì)上,要想保證傳輸?shù)目煽啃裕瑒t需要對傳輸?shù)膬?nèi)容進行驗證。
a、對于網(wǎng)絡(luò)數(shù)據(jù)的破壞(比如宇宙射線影響偷笑導(dǎo)致發(fā)射火箭的數(shù)據(jù)中某一位從0變?yōu)?),采取的策略是丟棄重新發(fā)送,以確保不會出現(xiàn)致命的錯誤。TCP在自身協(xié)議中單獨劃了一塊checksum用于這種校驗,校驗算法本質(zhì)上是將整塊數(shù)據(jù)通過某個函數(shù)映射到16位的校驗位上(比如用字符相加的和來校驗)
b、對于數(shù)據(jù)傳輸正確,但是分片亂序,重復(fù)等問題,或是丟包,采取的策略并非丟棄而是自行進行包重組。
考慮兩種情況:第一種情況是某個包缺少了,導(dǎo)致整個數(shù)據(jù)中間缺了一段1000字節(jié),那么如何通知到對方自己少了哪一段數(shù)據(jù);另一種情況是由于網(wǎng)絡(luò)或者重發(fā)機制的原因?qū)е履骋粋€包收到多次,如何把多余的包都排除掉,僅保留已有數(shù)據(jù)。
TCP在設(shè)計時候充分考慮這點,其中SYN和ACK就是用來確保這個過程的,SYN發(fā)送的是字節(jié)順序,ACK則應(yīng)答收到的字節(jié)序加1。這樣,無論是發(fā)送方還是接收方,都可以準(zhǔn)確的維護一張發(fā)送接收字節(jié)的列表。從而可以知道對方還需要哪些字節(jié),或自己已經(jīng)接收了哪些字節(jié)。
2)重發(fā)機制
a、超時重發(fā)
為了保證數(shù)據(jù)一定被接收到,就必須妥善處理超時,對于超時沒得到響應(yīng),則最好的辦法是重新發(fā)送。
首先將數(shù)據(jù)拷貝到發(fā)送緩沖區(qū),每個包在發(fā)送時都會啟動一個定時器,如果定時器超時前收到了對方應(yīng)答,則發(fā)送成功,清除緩沖區(qū),否則重傳數(shù)據(jù)包,直到達到最大次數(shù)。
TCP在每次發(fā)包時都會計算往返時間極其偏差,通過這個記錄可以大致判斷雙方的網(wǎng)絡(luò)情況從而確定超時時間。通常剛開始超時時間較長(如6s),而后可能到0.5s這樣較小的時間。
b、高速重發(fā)
比起超時才重新發(fā)送,TCP還設(shè)計了更為巧妙的方式來做重發(fā)。稱為快速重發(fā)。即目標(biāo)主機在確認(rèn)時總是確認(rèn)排在最先的缺失包,當(dāng)發(fā)送方發(fā)現(xiàn)連續(xù)收到3個同樣的ack時,則表明該包已經(jīng)丟了,需要快速重新發(fā)送,這樣能否避免要等到超時才能重發(fā)。
3)流量控制(滑動窗口)
a、滑動窗口協(xié)議
滑動窗口本質(zhì)上是為了在通信過程中同步收發(fā)雙方的速率。通過發(fā)送端的發(fā)送窗口和接收端的接收窗口來保證發(fā)送的可靠性,同時協(xié)調(diào)發(fā)送的速度。
對于發(fā)送端來說,整個窗口分為下面四段,一是已經(jīng)發(fā)送也收到確認(rèn)回復(fù)的;二是已經(jīng)發(fā)送但尚未收到回復(fù)的;三是還沒有發(fā)送但即將發(fā)送的(接收方有空間,只是發(fā)送方尚未發(fā)送而已);四是沒發(fā)送,但是接收方已經(jīng)沒空間的
同理,對于接收方來說,整個窗口分為三段,一是已經(jīng)接收并且已經(jīng)回復(fù)ACK的;二是已經(jīng)接收的;三是為接收也沒準(zhǔn)備接收的
而所謂的滑動,則是將窗口從上一次收到的連續(xù)ACK的位置整個劃到下一次收到連續(xù)ACK的位置而已。注意連續(xù)二字,不連續(xù)則不能算作已經(jīng)接收完畢。
b、滑動窗口的收縮與擴張
滑動窗口最牛逼的地方在于動態(tài)的調(diào)整收發(fā)雙方的窗口大小,以便使得收發(fā)雙方通信同步而不僅僅是對于發(fā)送接收字節(jié)的管理。
在TCP協(xié)議中,有16個字節(jié)專門用來放window大小,是接收端主機向發(fā)送方主機通知自己可以接納的數(shù)據(jù)大小,而發(fā)送方會根據(jù)該窗口數(shù)據(jù)發(fā)送不超過這個限度的數(shù)據(jù)。接收方可以根據(jù)自己的處理能力不斷的增大或者縮小這個值,而發(fā)送方主機則只要保持與之同步即可。
當(dāng)收縮到最小(即0窗口)時,按照約定發(fā)送方不能再給接收方發(fā)送數(shù)據(jù)了,那豈不是陷入死局,大家從此斷開?實際上發(fā)送方會一段時間后重試,如果還不行拉長一段時間后再重試,直到達到最大重試次數(shù)。
4)擁塞控制
擁塞控制的起因是,作為TCP本身雖然已經(jīng)有了各種校驗和檢測方法保證通信雙方能否互相通信并且能夠同步雙方的情況了。但是它還忽略了一個關(guān)鍵因素—網(wǎng)絡(luò)狀況。網(wǎng)絡(luò)是通路,如果這個通路太擁擠,應(yīng)該適當(dāng)減少發(fā)送,而如果這個通路比較寬松,則可以適當(dāng)增加發(fā)送。
TCP的擁塞控制包括:慢啟動,擁塞避免,擁塞發(fā)生,快速恢復(fù)。
慢啟動每次將擁塞窗口的大小設(shè)置為1個數(shù)據(jù)段,之后每次收到確認(rèn)應(yīng)答則擁塞窗口加1
由于這很容易造成指數(shù)級的增長放大,于是又引入一個慢啟動閾值的概念,即當(dāng)tcp通信開始時,網(wǎng)絡(luò)吞吐會急劇上升,當(dāng)?shù)竭_一個閾值之后,則開始下降然后緩慢上升。
4.TCP中的各種異常攻擊情況
- SYN攻擊。主要是建聯(lián)時攻擊。攻擊方發(fā)起SYN請求,被攻擊方收到請求后回應(yīng)ACK,此時攻擊方本應(yīng)當(dāng)回應(yīng)此ACK使得被攻擊方變?yōu)閑stablish狀態(tài),然而攻擊方此時不做回應(yīng),使得被攻擊方維護的未連接隊列中該記錄存活時間因為超時重試而增加,而短期大量該類型攻擊淹沒可使得被攻擊方未連接隊列不斷增長,讓系統(tǒng)響應(yīng)變慢,網(wǎng)絡(luò)擁堵甚至系統(tǒng)崩潰。
- RST攻擊。RST復(fù)位主要是通信任何一方認(rèn)為異常的連接則可以清除該連接的緩沖區(qū),并向?qū)Ψ桨l(fā)送RST標(biāo)志強制關(guān)閉連接。RST攻擊主要是用來斷一個已有連接的,比如A與B連接中,此時C冒出來偽裝成A向B發(fā)送一個帶RST位的請求,則B將清除所有與A的“記憶”,下次A再來時,B將不認(rèn)識A;當(dāng)然了,如果C冒充A向B發(fā)送一個SYN請求,則B會主動發(fā)起RST復(fù)位。這類攻擊主要用來癱瘓重要連接,從而趁虛而入。













































