1.TCP和UDP的區(qū)別
(1)TCP
TCP 提供面向連接的服務(wù):在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送結(jié)束后要釋放連接又碌。
TCP 具有可靠性:傳遞數(shù)據(jù)之前有三次握手來建立連接绊袋,而且在數(shù)據(jù)傳遞時有窗口癌别、重傳、擁塞控制機(jī)制展姐,在數(shù)據(jù)傳完后需要斷開連接用來節(jié)約系統(tǒng)資源圾笨。因此,TCP可以提供可靠的面向連接服務(wù)土铺,但是這些操作增加了許多開銷板鬓,例如流量控制、計時器镀迂、連接管理等唤蔗。TCP 一般用于文件傳輸妓柜、發(fā)送和接收郵件、遠(yuǎn)程登錄等場景棍掐。
(2)UDP
UDP 不具有可靠性作煌。UDP 在傳遞數(shù)據(jù)之前不需要先建立連接赚瘦,遠(yuǎn)地主機(jī)在收到 UDP 報文后奏寨,不需要給出任何確認(rèn)病瞳。UDP 一般用于即時通信,例如: QQ 語音亲善、 QQ 視頻 逗柴、直播等等。
2.UDP 首部格式
UDP 首部字段只有 8 個字節(jié)掘而,包括源端口、目的端口知染、長度控淡、檢驗和。12 字節(jié)的偽首部是為了計算檢驗和臨時添加的辫诅。
3.TCP 首部格式
①源端口:本端口號涧狮,即發(fā)起請求的端口號者冤;
②目的端口:接收請求的端口號;
③序號?:報文段的編號邢滑,即字節(jié)流的編號愿汰。例如:序號為 301表示第一個字節(jié)的編號為 301乐纸,如果攜帶的數(shù)據(jù)長度為 100 字節(jié)锯仪,那么下一個報文段的序號應(yīng)為 401趾盐;
④確認(rèn)號?:期望收到下一個報文段的序號。例如: B 正確收到 A 發(fā)送來的一個報文段久窟,序號為 501本缠,攜帶的數(shù)據(jù)長度為 200 字節(jié)丹锹,因此 B 期望下一個報文段的序號為 701,B 發(fā)送給 A 的確認(rèn)報文段中確認(rèn)號就為 701匾灶;
⑤數(shù)據(jù)偏移?:數(shù)據(jù)部分與報文段起始處的偏移量租漂,實際上指的是首部的長度;
⑥同步 SYN?:在連接建立時用來同步序號秃踩。當(dāng) SYN=1业筏,ACK=0 時表示這是一個連接請求報文段蒜胖。若對方同意建立連接,則響應(yīng)報文中 SYN=1妖啥,ACK=1对碌;
⑦確認(rèn) ACK?:當(dāng) ACK=1 時確認(rèn)號字段有效,否則無效怀读。TCP 規(guī)定,在連接建立后所有傳送的報文段都必須把 ACK 置 1苍糠;
⑧終止 FIN?:當(dāng) FIN=1 時啤誊,表示發(fā)送方的數(shù)據(jù)已發(fā)送完畢蚊锹,并要求釋放連接;
⑨窗口?:窗口值是發(fā)送窗口的大小姚炕。發(fā)送方根據(jù)接收方的窗口值丢烘,設(shè)置發(fā)送窗口的大小播瞳。
4.TCP 的三次握手
說明:SYN表示建立連接(0/1),ACK表示確認(rèn)(0/1)痒给,seq是指本端的確認(rèn)序號骏全,ack是指對端的確認(rèn)序號+1
① 服務(wù)端 B 處于LISTEN監(jiān)聽狀態(tài)姜贡,等待客戶端 A 的請求棺棵。
②?客戶端?A 向 服務(wù)端?B 發(fā)送建立連接的請求報文烛恤,SYN=1,本端確認(rèn)序號seq=x苹熏;客戶端 A 進(jìn)入SYN_SENT狀態(tài)。
③?服務(wù)端?B 接收到第一次握手的請求報文袱耽。如果同意建立連接干发,則向 A 發(fā)送連接確認(rèn)報文:SYN=1枉长,ACK=1,本端確認(rèn)序號seq=y洪唐,對端確認(rèn)序號ack=x+1自点;服務(wù)端 B 進(jìn)入SYN_SENT狀態(tài)。
④ 客戶端?A 接收到第二次握手的連接確認(rèn)報文功炮,并向 B 發(fā)送報文:ACK=1术唬,?本端確認(rèn)序號seq=x+1粗仓,對端確認(rèn)序號ack=y+1;客戶端 A 進(jìn)入ESTAB_LISHED狀態(tài)塘淑。
⑤?服務(wù)端?B 接收第三次握手的確認(rèn)報文后蚂斤,連接建立曙蒸;服務(wù)端 B 也進(jìn)入ESTAB_LISHED狀態(tài)。
(1)CLOSED狀態(tài)
CLOSED是初始狀態(tài)肖油,表示TCP連接是“關(guān)閉著的”或”未打開的”臂港。
(2)LISTEN狀態(tài)
LISTEN表示服務(wù)器端的某個SOCKET處于監(jiān)聽狀態(tài),可以接受客戶端的連接 凶朗。
(3)SYN_SENT狀態(tài)
SYN_SENT是客戶端第一次發(fā)給服務(wù)端的時候設(shè)置成的狀態(tài)显拳。
(4)SYN_RCVD狀態(tài)
SYN_RCVD是TCP三次握手的中間狀態(tài),是服務(wù)端收到SYN包并發(fā)送[SYN宛畦,ACK]包后所處的狀態(tài)次和。
SYN攻擊:利用TCP協(xié)議缺陷那伐,通過發(fā)送大量的半連接請求,耗費服務(wù)器CPU和內(nèi)存資源畅形。SYN_RCVD很短暫日熬,但是遇到SYN攻擊時肾胯,會出現(xiàn)大量的這種狀態(tài),即收不到三次握手最后一個客戶端發(fā)來的ACK毕荐,所以一直是這個狀態(tài)东跪,不會轉(zhuǎn)換到ESTAB_LISHED狀態(tài)鹰溜。
(5)ESTAB_LISHED狀態(tài)
ESTAB_LISHED表示TCP連接已經(jīng)成功建立曹动,開始傳輸數(shù)據(jù)牲览。
問題1:TCP三次握手中為什么客戶端最后還要發(fā)送一次確認(rèn)?(?即TCP為什么需要三次握手)
防止已經(jīng)失效的連接請求報文突然又傳送到了服務(wù)器贡必,讓服務(wù)器錯誤打開連接仔拟。
如果使用的是兩次握手建立連接。假設(shè)有這樣一種場景:客戶端發(fā)送第一握手請求并且沒有丟失科侈。網(wǎng)絡(luò)問題導(dǎo)致TCP的客戶端遲遲沒有收到客戶端返回的第二次握手請求炒事。因此挠乳,客戶端重新向服務(wù)端發(fā)送第一次握手請求,此后客戶端和服務(wù)端經(jīng)過兩次握手完成連接盟蚣,傳輸數(shù)據(jù)威蕉,然后關(guān)閉連接韧涨。此時此前滯留的那一次請求連接,網(wǎng)絡(luò)通暢了到達(dá)了服務(wù)端如孝,這個報文本該是失效的娩贷,但是兩次握手的機(jī)制將會讓客戶端和服務(wù)器再次建立連接彬祖,這將導(dǎo)致不必要的錯誤和資源的浪費。
如果采用的是三次握手甜熔,就算是那一次失效的報文傳送過來了突倍,服務(wù)端接受到了那條失效報文并且回復(fù)了確認(rèn)報文,但是客戶端不會再次發(fā)出確認(rèn)淡喜。由于服務(wù)器收不到確認(rèn)诵闭,就知道客戶端并沒有請求連接涂圆。
問題2:第2次握手傳回了ACK,為什么還要傳回SYN模狭?
第2次握手的時候踩衩,服務(wù)端返回ACK給客戶端驱富,目的是告訴客戶端:服務(wù)端確實收到客戶端第一次握手的信號,表明客戶端到服務(wù)端的通訊是正常的线脚』虢模回傳SYN的目的:建立并確認(rèn)服務(wù)端到客戶端的通信晰绎。
SYN 是 TCP/IP 建立連接時使用的握手信號荞下。在客戶端和服務(wù)端之間建立正常的 TCP 網(wǎng)絡(luò)連接時,客戶端首先發(fā)出一個 SYN 消息仰税,服務(wù)端使用 SYN-ACK 應(yīng)答表示接收到了這個消息肖卧,最后客戶端再以 ACK 消息響應(yīng)掸鹅。這樣在客戶機(jī)和服務(wù)器之間才能建立起可靠的 TCP 連接巍沙,數(shù)據(jù)才可以在客戶機(jī)和服務(wù)器之間傳遞。
5.TCP 的四次揮手
說明:FIN表示關(guān)閉連接(0/1)
① 客戶端 A 和服務(wù)端 B 都處于ESTAB_LISHED數(shù)據(jù)傳輸狀態(tài)榔幸。
②?客戶端?A 向?服務(wù)端?B 發(fā)送確認(rèn)的請求報文:FIN=1削咆,本端確認(rèn)序號seq=u拨齐;客戶端 A 進(jìn)入FIN_WAIT_1狀態(tài)昨寞。
③?服務(wù)端?B 接收到第一次揮手的請求報文援岩。如果同意關(guān)閉連接,則向 A 發(fā)送連接確認(rèn)報文:ACK=1羽峰,本端確認(rèn)序號seq=v梅屉,對端確認(rèn)序號ack=u+1仰坦;服務(wù)端 B 進(jìn)入CLOSE_WAIT狀態(tài)。
④?客戶端?A 接收到第二次揮手的請求報文玫霎;客戶端 A 進(jìn)入FIN_WAIT_2狀態(tài)庶近。
⑤?服務(wù)端?B 向客戶端 A 發(fā)送關(guān)閉連接的請求報文:FIN=1眷蚓,ACK=1沙热,本端確認(rèn)序號seq=w罢缸,對端確認(rèn)序號ack=u+1枫疆;服務(wù)端 B 進(jìn)入LAST_ACK狀態(tài)敷鸦。
⑥ 客戶端 A 接收到第三次揮手的請求報文扒披,并向服務(wù)端 A 發(fā)送報文:ACK=1值依,seq=u+1,ack=w+1碟案;客戶端 A 進(jìn)入TIME_WAIT狀態(tài)愿险,等待2MSL后進(jìn)入CLOSED狀態(tài)。
⑦ 服務(wù)端 B 接收到第四次揮手的請求報文蟆淀;服務(wù)端 B?進(jìn)入CLOSED狀態(tài)拯啦。
(1)FIN_WAIT_1 狀態(tài)
FIN_WAIT_1表示客戶端第一次等待服務(wù)端ACK的確認(rèn)請求報文。當(dāng)客戶端主動關(guān)閉連接時熔任,向服務(wù)端發(fā)送FIN報文褒链,此時客戶端進(jìn)入FIN_WAIT_1的狀態(tài)疑苔。當(dāng)服務(wù)端回復(fù)ACK甫匹,確認(rèn)關(guān)閉后,則客戶端進(jìn)入FIN_WAIT_2的狀態(tài)惦费。因此兵迅,客戶端只有在沒有收到服務(wù)端ACK的情況下,才會處于FIN_WAIT_1狀態(tài)薪贫。
(2)CLOSE_WAIT 狀態(tài)
CLOSED_WAIT表示服務(wù)端正在等待關(guān)閉恍箭。該狀態(tài)主要目的是讓服務(wù)端發(fā)送還未傳送完畢的數(shù)據(jù),傳送完畢之后服務(wù)端才會向客戶端發(fā)送FIN的關(guān)閉確認(rèn)報文瞧省。
(3)FIN_WAIT_2 狀態(tài)
FIN_WAIT_2表示客戶端第二次等待服務(wù)端的FIN關(guān)閉請求報文扯夭。
(4)LAST_ACK 狀態(tài)
LAST_ACK表示服務(wù)端等待最后的關(guān)閉確認(rèn)報文“柏遥客戶端向客戶端發(fā)送FIN的關(guān)閉請求報文后交洗,等待最后的關(guān)閉確認(rèn)報文。
(5)TIME_WAIT 狀態(tài)
TIME_WAIT表示客戶端最后定時關(guān)閉的狀態(tài)橡淑」谷客戶端接收到FIN后,從FIN_WAIT_2狀態(tài)進(jìn)入到TIME_WAIT狀態(tài),直到定時時間到后置森,進(jìn)入CLOSED狀態(tài)斗埂。
問題1:TCP為什么要四次揮手?
客戶端發(fā)送 FIN 連接關(guān)閉的請求報文之后暇藏,服務(wù)端收到了該報文進(jìn)入了CLOSE-WAIT狀態(tài)蜜笤。CLOSE-WAIT狀態(tài)主要是為了讓服務(wù)端發(fā)送還未傳送完畢的數(shù)據(jù),傳送完畢之后服務(wù)端才會向客戶端發(fā)送FIN連接關(guān)閉的確認(rèn)報文盐碱。
問題2:TCP四次揮手中為什么客戶端最后還要等待2MSL?
客戶端接收到服務(wù)端的 FIN 報文后進(jìn)入TIME_WAIT狀態(tài)沪伙,而不是直接進(jìn)入CLOSED狀態(tài)瓮顽,還需要等待一個時間計時器設(shè)置的時間2MSL。理由如下:
①?確保最后一個確認(rèn)報文能夠到達(dá)围橡。如果服務(wù)端沒收到客戶端發(fā)送來的確認(rèn)報文暖混,那么就會重新發(fā)送FIN連接請求報文,客戶端等待一段時間就是為了處理這種情況的發(fā)生翁授。
②?讓本次關(guān)閉連接的持續(xù)時間內(nèi)所產(chǎn)生的所有報文都從網(wǎng)絡(luò)中消失拣播,使得下一個新的連接不會出現(xiàn)舊的連接請求報文。
問題3:TCP三次揮手和四次揮手的抓包數(shù)據(jù)是怎樣的收擦?
6.TCP 的可靠性傳輸
(1)校驗和
TCP首部有16byte的校驗和字段贮配,校驗內(nèi)容包括TCP首部和數(shù)據(jù)部分。計算方法為:客戶端將整個報文段分為多個16位的段塞赂,然后將所有段進(jìn)行反碼相加泪勒,將結(jié)果存放在檢驗和字段中;服務(wù)端采用相同的方法進(jìn)行計算宴猾,如果最終結(jié)果為校驗和字段所有位是全1則正確圆存,否則存在錯誤。
(2)序列號和確認(rèn)應(yīng)答機(jī)制
TCP中每條數(shù)據(jù)都有編號仇哆,即序列號沦辙。
TCP的首部中有一個確認(rèn)字段ACK,此標(biāo)志位表示確認(rèn)號是否有效讹剔,即確認(rèn)之前的數(shù)據(jù)都按序達(dá)到油讯。例如:ACK=1、ack=1001表示確認(rèn)有效辟拷,將要發(fā)送的報文序號是1001
(3)超時重傳機(jī)制
如果一個已經(jīng)發(fā)送的報文段在超時時間內(nèi)沒有收到確認(rèn)撞羽,那么就重傳這個報文段(通常情況發(fā)送方在發(fā)出報文段后啟動定時器,如果到點了還沒有收到響應(yīng)報文衫冻,則進(jìn)行重傳)诀紊。
①情況一:發(fā)送方的報文丟失
② 響應(yīng)的ACK丟失
問題1:如何識別出重復(fù)的數(shù)據(jù)?
使用序列號判斷是否重復(fù)隅俘。當(dāng)接收方接收到重復(fù)的數(shù)據(jù)時就將其丟掉邻奠,重新發(fā)送ACK笤喳。
問題2:如何確定重傳時間?
報文段發(fā)出到收到應(yīng)答中間有一個報文段的往返時間RTT碌宴,超時重傳時間RTO大于RTT杀狡。TCP根據(jù)網(wǎng)絡(luò)情況動態(tài)的計算RTT,即RTO是不斷變化的贰镣。在Linux中呜象,超時以500ms為單位進(jìn)行控制,每次判定超時重發(fā)的超時時間都是500ms的整數(shù)倍碑隆。規(guī)律為:如果重發(fā)一次仍得不到應(yīng)答恭陡,就等待2500ms后再進(jìn)行重傳,如果仍然得不到應(yīng)答就等待4500ms后重傳上煤,依次類推休玩,以指數(shù)形式遞增,重傳次數(shù)累計到一定次數(shù)后劫狠,TCP認(rèn)為網(wǎng)絡(luò)或?qū)Χ酥鳈C(jī)出現(xiàn)異常拴疤,就會強(qiáng)行關(guān)閉連接。
(4)連接管理
連接管理機(jī)制:TCP建立連接時的三次握手独泞、TCP斷開連接時的四次揮手呐矾。
(5)流量控制
如下?7.TCP 的滑動窗口和流量控制
(6)阻塞控制
如下?8.TCP 的擁塞控制
7.TCP 的窗口機(jī)制和流量控制
TCP 利用滑窗口實現(xiàn)流量控制。流量控制的目的是控制發(fā)送方發(fā)送速率阐肤,保證接收方來得及接收凫佛。
TCP報文段首部有16位窗口字段,當(dāng)接收方收到發(fā)送方的數(shù)據(jù)后孕惜,ACK響應(yīng)報文中就將自身緩沖區(qū)的剩余大小設(shè)置到放入16位窗口字段愧薛。該窗口字段值是隨網(wǎng)絡(luò)傳輸?shù)那闆r變化的,窗口越大衫画,網(wǎng)絡(luò)吞吐量越高毫炉。如果緩沖區(qū)滿,就將窗口置為0削罩,發(fā)送方收到后就不再發(fā)送數(shù)據(jù)瞄勾,但是需要定期發(fā)送一個窗口探測數(shù)據(jù)段,使得發(fā)送方知道接收方的窗口大小弥激。
發(fā)送窗口內(nèi)的字節(jié)都允許被發(fā)送,接收窗口內(nèi)的字節(jié)都允許被接收微服。如果發(fā)送窗口左部的字節(jié)已經(jīng)發(fā)送并且收到了確認(rèn)趾疚,那么就將發(fā)送窗口向右滑動一定距離,直到左部第一個字節(jié)不是已發(fā)送并且已確認(rèn)的狀態(tài);接收窗口的滑動類似糙麦,接收窗口左部字節(jié)已經(jīng)發(fā)送確認(rèn)并交付主機(jī)辛孵,就向右滑動接收窗口。
TCP窗口的數(shù)據(jù)交互流程如下:
8.TCP 的擁塞控制
網(wǎng)絡(luò)擁塞可能導(dǎo)致分組丟失赡磅。發(fā)送方會繼續(xù)重傳魄缚,從而導(dǎo)致網(wǎng)絡(luò)擁塞程度更高。因此焚廊,當(dāng)網(wǎng)絡(luò)擁塞時冶匹,應(yīng)該控制發(fā)送方的速率(這一點與流量控制類似,但是出發(fā)點不同:流量控制是為了讓接收方能來得及接收咆瘟,而擁塞控制是為了降低整個網(wǎng)絡(luò)的擁塞程度)徙硅。
TCP協(xié)議主要通過四個算法來進(jìn)行擁塞控制:慢開始、擁塞避免搞疗、快重傳、快恢復(fù)须肆。