1 什么是三次握手呢德谅?
參考:簡述TCP的三次握手過程
三次握手指建立一個TCP連接時,需要客戶端和服務端總共發(fā)送3個包以確認連接的建立萨螺。在socket編程中窄做,這一過程由客戶端執(zhí)行connect來觸發(fā),整個流程如下圖所示:
備注:ACK起應答作用慰技,而SYN起同步作用
(1)第一次握手:Client將標志位SYN置為1椭盏,隨機產(chǎn)生一個值seq=J,并將該數(shù)據(jù)包發(fā)送給Server吻商,Client進入SYN_SENT狀態(tài)掏颊,等待Server確認。
(2)第二次握手:Server收到數(shù)據(jù)包后由標志位SYN=1知道Client請求建立連接,Server將標志位SYN和ACK都置為1乌叶,確認序列號ack=J+1盆偿,隨機產(chǎn)生一個值seq=K,并將該數(shù)據(jù)包發(fā)送給Client以確認連接請求准浴,Server進入SYN_RCVD狀態(tài)事扭。
(3)第三次握手:Client收到確認后,檢查確認序列號ack是否為J+1兄裂,ACK是否為1句旱,如果正確則將標志位ACK置為1,ack=K+1晰奖,并將該數(shù)據(jù)包發(fā)送給Server谈撒,Server檢查確認序列號ack是否為K+1,ACK是否為1匾南,如果正確則連接建立成功啃匿,Client和Server進入ESTABLISHED狀態(tài),完成三次握手蛆楞,隨后Client與Server之間可以開始傳輸數(shù)據(jù)了溯乒。
2 三次握手時,會存在什么缺陷呢豹爹?
SYN攻擊:
在三次握手過程中裆悄,Server發(fā)送SYN-ACK之后,收到Client的ACK之前的TCP連接稱為半連接(half-open connect)臂聋,此時Server處于SYN_RCVD狀態(tài)光稼,當收到ACK后,Server轉入ESTABLISHED狀態(tài)孩等。SYN攻擊就是Client在短時間內(nèi)偽造大量不存在的IP地址艾君,并向Server不斷地發(fā)送SYN包,Server回復確認包肄方,并等待Client的確認冰垄,由于源地址是不存在的,因此权她,Server需要不斷重發(fā)直至超時虹茶,這些偽造的SYN包將長時間占用未連接隊列,導致正常的SYN請求因為隊列滿而被丟棄隅要,從而引起網(wǎng)絡堵塞甚至系統(tǒng)癱瘓蝴罪。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單拾徙,即當Server上有大量半連接狀態(tài)且源IP地址是隨機的,則可以斷定遭到SYN攻擊了感局,使用如下命令可以讓之現(xiàn)行:
#netstat -nap | grep SYN_RECV
3 什么時四次揮手呢尼啡?
四次揮手即終止TCP連接暂衡,就是指斷開一個TCP連接時,需要客戶端和服務端總共發(fā)送4個包以確認連接的斷開崖瞭。在socket編程中狂巢,這一過程由客戶端或服務端任一方執(zhí)行close來觸發(fā),整個流程如下圖所示:
由于TCP連接時全雙工的书聚,因此唧领,每個方向都必須要單獨進行關閉,這一原則是當一方完成數(shù)據(jù)發(fā)送任務后雌续,發(fā)送一個FIN來終止這一方向的連接斩个,收到一個FIN只是意味著這一方向上沒有數(shù)據(jù)流動了,即不會再收到數(shù)據(jù)了驯杜,但是在這個TCP連接上仍然能夠發(fā)送數(shù)據(jù)受啥,直到這一方向也發(fā)送了FIN。首先進行關閉的一方將執(zhí)行主動關閉鸽心,而另一方則執(zhí)行被動關閉滚局,上圖描述的即是如此。
(1)第一次揮手:Client發(fā)送一個FIN顽频,用來關閉Client到Server的數(shù)據(jù)傳送藤肢,Client進入FIN_WAIT_1狀態(tài)。
(2)第二次揮手:Server收到FIN后糯景,發(fā)送一個ACK給Client嘁圈,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號)莺奸,Server進入CLOSE_WAIT狀態(tài)丑孩。
(3)第三次揮手:Server發(fā)送一個FIN,用來關閉Server到Client的數(shù)據(jù)傳送灭贷,Server進入LAST_ACK狀態(tài)温学。
(4)第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態(tài)甚疟,接著發(fā)送一個ACK給Server仗岖,確認序號為收到序號+1,Server進入CLOSED狀態(tài)览妖,完成四次揮手轧拄。
4 Closing狀態(tài)是怎么產(chǎn)生的呢?
如果雙方幾乎在同時close一個SOCKET的話讽膏,那么就出現(xiàn)了雙方同時發(fā)送FIN報 文的情況檩电,也即會出現(xiàn)CLOSING狀態(tài),表示雙方都正在關閉SOCKET連接。
5 為什么需要“三次握手”俐末?三次握手的缺陷料按?
三次握手的目的是:為了防止已失效的連接請求報文段突然又傳送到了導致server端一直等待,浪費資源卓箫。
缺陷:SYN-Flood拒絕服務攻擊攻擊载矿,是一種典型的DDOS攻擊,偽造大量不存在的IP地址烹卒,并向Server不斷地發(fā)送SYN包闷盔,造成虛假連接(半連接讹语,可能造成目標服務器中的半開連接隊列被占滿)消约,導致正常的SYN請求因為隊列滿而被丟棄,從而引起網(wǎng)絡堵塞甚至系統(tǒng)癱瘓粉铐。
具體例如:client發(fā)出的第一個連接請求報文段并沒有丟失坠非,而是在某個網(wǎng)絡結點長時間的滯留了敏沉,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段炎码。但server收到此失效的連接請求報文段后盟迟,就誤認為是client再次發(fā)出的一個新的連接請求。于是就向client發(fā)出確認報文段潦闲,同意建立連接攒菠。假設不采用“三次握手”,那么只要server發(fā)出確認歉闰,新的連接就建立了辖众。由于現(xiàn)在client并沒有發(fā)出建立連接的請求,因此不會理睬server的確認和敬,也不會向server發(fā)送數(shù)據(jù)凹炸。但server卻以為新的運輸連接已經(jīng)建立,并一直等待client發(fā)來數(shù)據(jù)昼弟。這樣啤它,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生舱痘。例如剛才那種情況变骡,client不會向server的確認發(fā)出確認。server由于收不到確認芭逝,就知道client并沒有要求建立連接塌碌。
6 為什么建立連接是三次握手,而關閉連接卻是四次揮手呢旬盯?
由于TCP連接是全雙工的台妆,因此每個方向都必須單獨進行關閉翎猛;發(fā)送數(shù)據(jù)和接受數(shù)據(jù)的控制權是不一樣的,所以關閉的時候需要將ACK和FIN分開發(fā)送接剩。
因為當收到對方的FIN報文通知時办成,它僅僅表示對方?jīng)]有數(shù)據(jù)發(fā)送給你了;但未必你所有的數(shù)據(jù)都全部發(fā)送給對方了搂漠,所以你可能還需要發(fā)送一些數(shù)據(jù)給對方,再發(fā)送FIN報文給對方來表示你同意現(xiàn)在可以關閉連接了某弦,故這里的ACK報文和FIN報文多數(shù)情況下都是分開發(fā)送的桐汤,也就造成了4次揮手。
7 為什么TIME_WAIT狀態(tài)還需要等2MSL(最大報文段生存時間)后才能返回到CLOSED狀態(tài)靶壮?
作用:如果網(wǎng)絡不可靠怔毛,用來重發(fā)可能丟失的ACK報文
這是因為: 雖然雙方都同意關閉連接了,而且握手的4個報文也都協(xié)調(diào)和發(fā)送完畢腾降,按理可以直接回到CLOSED狀態(tài)拣度;但是因為我們必須要假想網(wǎng)絡是不可靠的,你無法保證你最后發(fā)送的ACK報文會一定被對方收到螃壤,因此對方處于 LAST_ACK狀態(tài)下的SOCKET可能會因為超時未收到ACK報文抗果,而重發(fā)FIN報文,所以這個TIME_WAIT狀態(tài)的作用就是用來重發(fā)可能丟失的 ACK報文奸晴。
8 介紹一下三次握手過程中的狀態(tài)冤馏?
CLOSED: 表示初始狀態(tài)。
LISTEN: 表示服務器端的某個SOCKET處于監(jiān)聽狀態(tài)寄啼,可以接受連接逮光。
SYN_SENT: 表示客戶端已發(fā)送SYN報文。當客戶端SOCKET執(zhí)行CONNECT連接時墩划,它首先發(fā)送SYN報文涕刚,因此也隨即它會進入到了SYN_SENT狀 態(tài),并等待服務端的發(fā)送三次握手中的第2個報文乙帮。
SYN_RCVD:表示接受到了SYN報文杜漠。在正常情況下,這個狀態(tài)是服務器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態(tài)蚣旱,很短暫碑幅,基本上用netstat你是很難看到這種狀態(tài)的,除非你特意寫了一個客戶端測試程序塞绿,故意將三次TCP握手過程中最后一個ACK報文不予發(fā)送沟涨。因此這種狀態(tài)時,當收到客戶端的ACK報文后异吻,它會進入到ESTABLISHED狀態(tài)裹赴。
ESTABLISHED: 表示已經(jīng)建立了連接喜庞。
9 介紹一下四次揮手過程中的狀態(tài)?
FIN_WAIT_1: 表示主動關閉連接時棋返,發(fā)送了FIN報文后的狀態(tài)延都。FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對方的FIN報文。而這兩種狀態(tài)的區(qū)別是:FIN_WAIT_1狀態(tài)實際上是當SOCKET在ESTABLISHED狀態(tài)時睛竣,它想主動關閉連接晰房,向?qū)Ψ桨l(fā)送了FIN報文,此時該SOCKET即 進入到FIN_WAIT_1狀態(tài)射沟。而當對方回應ACK報文后殊者,則進入到FIN_WAIT_2狀態(tài),當然在實際的正常情況下验夯,無論對方何種情況下猖吴,都應該馬 上回應ACK報文,所以FIN_WAIT_1狀態(tài)一般是比較難見到的挥转,而FIN_WAIT_2狀態(tài)還有時常澈1危可以用netstat看到。
FIN_WAIT_2: 當收到被動關閉方的ACK報文時绑谣,處于半連接的狀態(tài)党窜。實際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接借宵,此時還可以接受數(shù)據(jù)刑然,但不能發(fā)送數(shù)據(jù)了。
TIME_WAIT: 表示收到了對方的FIN報文暇务,并發(fā)送出了ACK報文泼掠,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FIN_WAIT_1狀態(tài)下垦细,收到了對方同時帶 FIN標志和ACK標志的報文時择镇,可以直接進入到TIME_WAIT狀態(tài),而無須經(jīng)過FIN_WAIT_2狀態(tài)括改。
CLOSING: 表示同時揮手發(fā)送FIN報文腻豌,這種狀態(tài)比較特殊,實際情況中應該是很少見嘱能,屬于一種比較罕見的例外狀態(tài)吝梅。正常情況下,當你發(fā)送FIN報文后惹骂,按理來說是應該先收到(或同時收到)對方的 ACK報文苏携,再收到對方的FIN報文。但是CLOSING狀態(tài)表示你發(fā)送FIN報文后对粪,并沒有收到對方的ACK報文右冻,反而卻也收到了對方的FIN報文装蓬。什 么情況下會出現(xiàn)此種情況呢?其實細想一下纱扭,也不難得出結論:那就是如果雙方幾乎在同時close一個SOCKET的話牍帚,那么就出現(xiàn)了雙方同時發(fā)送FIN報文的情況,也即會出現(xiàn)CLOSING狀態(tài)乳蛾,表示雙方都正在關閉SOCKET連接暗赶。
CLOSE_WAIT: 這種狀態(tài)的含義其實是表示在等待關閉。怎么理解呢肃叶?當對方close一個SOCKET后發(fā)送FIN報文給自己忆首,你系統(tǒng)毫無疑問地會回應一個ACK報文給對 方,此時則進入到CLOSE_WAIT狀態(tài)被环。接下來呢,實際上你真正需要考慮的事情是察看你是否還有數(shù)據(jù)發(fā)送給對方详幽,如果沒有的話筛欢,那么你也就可以 close這個SOCKET,發(fā)送FIN報文給對方唇聘,也即關閉連接版姑。所以你在CLOSE_WAIT狀態(tài)下,需要完成的事情是等待你去關閉連接迟郎。
LAST_ACK: 這個狀態(tài)還是比較容易好理解的剥险,它是被動關閉一方在發(fā)送FIN報文后,最后等待對方的ACK報文宪肖。當收到ACK報文后表制,也即可以進入到CLOSED可用狀態(tài)了。
10 TCP超時等待控乾、重傳以及流量控制?
TCP協(xié)議通過“滑動窗口(Sliding Window)”機制來進行流量控制么介,
TCP協(xié)議作為一個可靠的面向流的傳輸協(xié)議,其可靠性和流量控制由滑動窗口協(xié)議保證蜕衡,而擁塞控制則由控制窗口結合一系列的控制算法實現(xiàn)壤短。
1 流量控制:
端到端的控制方式,接收方傳遞信息給發(fā)送方慨仿,使其不要發(fā)送數(shù)據(jù)太快久脯。
主要的方式就是返回的ACK中會包含自己的接收窗口的大小,并且利用大小來控制發(fā)送方的數(shù)據(jù)發(fā)送;
2 擁塞控制:
就是防止過多的數(shù)據(jù)注入到網(wǎng)絡中镰吆,這樣可以使網(wǎng)絡中的路由器或鏈路不致過載帘撰。
常用的方法就是:a、慢開始万皿、擁塞控制(發(fā)送試探報文) b骡和、快重傳相赁、快恢復
TCP流量控制和擁塞控制
Boy-20180507