https://blog.csdn.net/guanghuichenshao/article/details/81916277
重點(diǎn):三次握手,四次分手怔蚌,TCP如何保證可靠性,TCP忧侧,UDP區(qū)別闷畸。
背景描述
通過上一篇中網(wǎng)絡(luò)模型中的IP層的介紹套才,我們知道網(wǎng)絡(luò)層,可以實(shí)現(xiàn)兩個主機(jī)之間的通信。但是這并不具體离唐,因?yàn)椴「剑嬲M(jìn)行通信的實(shí)體是在主機(jī)中的進(jìn)程,是一個主機(jī)中的一個進(jìn)程與另外一個主機(jī)中的一個進(jìn)程在交換數(shù)據(jù)亥鬓。IP協(xié)議雖然能把數(shù)據(jù)報(bào)文送到目的主機(jī)完沪,但是并沒有交付給主機(jī)的具體應(yīng)用進(jìn)程。而端到端的通信才應(yīng)該是應(yīng)用進(jìn)程之間的通信嵌戈。TCP在傳輸層覆积。
UDP,在傳送數(shù)據(jù)前不需要先建立連接熟呛,遠(yuǎn)地的主機(jī)在收到UDP報(bào)文后也不需要給出任何確認(rèn)宽档。雖然UDP不提供可靠交付,但是正是因?yàn)檫@樣庵朝,省去和很多的開銷吗冤,使得它的速度比較快,比如一些對實(shí)時性要求較高的服務(wù)九府,就常常使用的是UDP椎瘟。對應(yīng)的應(yīng)用層的協(xié)議主要有 DNS,TFTP,DHCP,SNMP,NFS 等。
TCP昔逗,提供面向連接的服務(wù)降传,在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送完成后要釋放連接勾怒。因此TCP是一種可靠的的運(yùn)輸服務(wù)婆排,但是正因?yàn)檫@樣,不可避免的增加了許多的開銷笔链,比如確認(rèn)段只,流量控制等。對應(yīng)的應(yīng)用層的協(xié)議主要有 SMTP,TELNET,HTTP,FTP 等鉴扫。
常用的熟知端口號
應(yīng)用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL
熟知端口 21,20 69 23 25 53 80 22 3306
傳輸層協(xié)議 TCP UDP TCP TCP UDP TCP
TCP的概述
TCP把連接作為最基本的對象赞枕,每一條TCP連接都有兩個端點(diǎn),這種斷點(diǎn)我們叫作套接字(socket)坪创,它的定義為端口號拼接到IP地址即構(gòu)成了套接字炕婶,例如,若IP地址為192.3.4.16 而端口號為80莱预,那么得到的套接字為192.3.4.16:80柠掂。
TCP報(bào)文首部
img
源端口和目的端口,各占2個字節(jié)依沮,分別寫入源端口和目的端口涯贞;
序號枪狂,占4個字節(jié),TCP連接中傳送的字節(jié)流中的每個字節(jié)都按順序編號宋渔。例如州疾,一段報(bào)文的序號字段值是 301 ,而攜帶的數(shù)據(jù)共有100字段皇拣,顯然下一個報(bào)文段(如果還有的話)的數(shù)據(jù)序號應(yīng)該從401開始严蓖;
確認(rèn)號,占4個字節(jié)审磁,是期望收到對方下一個報(bào)文的第一個數(shù)據(jù)字節(jié)的序號谈飒。例如,B收到了A發(fā)送過來的報(bào)文态蒂,其序列號字段是501杭措,而數(shù)據(jù)長度是200字節(jié),這表明B正確的收到了A發(fā)送的到序號700為止的數(shù)據(jù)钾恢。因此手素,B期望收到A的下一個數(shù)據(jù)序號是701,于是B在發(fā)送給A的確認(rèn)報(bào)文段中把確認(rèn)號置為701瘩蚪;
數(shù)據(jù)偏移泉懦,占4位,它指出TCP報(bào)文的數(shù)據(jù)距離TCP報(bào)文段的起始處有多遠(yuǎn)疹瘦;
保留崩哩,占6位,保留今后使用言沐,但目前應(yīng)都位0邓嘹;
緊急URG,當(dāng)URG=1险胰,表明緊急指針字段有效汹押。告訴系統(tǒng)此報(bào)文段中有緊急數(shù)據(jù);
確認(rèn)ACK起便,僅當(dāng)ACK=1時棚贾,確認(rèn)號字段才有效。TCP規(guī)定榆综,在連接建立后所有報(bào)文的傳輸都必須把ACK置1妙痹;
推送PSH,當(dāng)兩個應(yīng)用進(jìn)程進(jìn)行交互式通信時鼻疮,有時在一端的應(yīng)用進(jìn)程希望在鍵入一個命令后立即就能收到對方的響應(yīng)细诸,這時候就將PSH=1;
復(fù)位RST陋守,當(dāng)RST=1震贵,表明TCP連接中出現(xiàn)嚴(yán)重差錯,必須釋放連接水评,然后再重新建立連接猩系;
同步SYN,在連接建立時用來同步序號中燥。當(dāng)SYN=1寇甸,ACK=0,表明是連接請求報(bào)文疗涉,若同意連接拿霉,則響應(yīng)報(bào)文中應(yīng)該使SYN=1,ACK=1咱扣;
終止FIN绽淘,用來釋放連接。當(dāng)FIN=1闹伪,表明此報(bào)文的發(fā)送方的數(shù)據(jù)已經(jīng)發(fā)送完畢沪铭,并且要求釋放;
窗口偏瓤,占2字節(jié)杀怠,指的是通知接收方,發(fā)送本報(bào)文你需要有多大的空間來接受厅克;
檢驗(yàn)和赔退,占2字節(jié),校驗(yàn)首部和數(shù)據(jù)這兩部分证舟;
緊急指針硕旗,占2字節(jié),指出本報(bào)文段中的緊急數(shù)據(jù)的字節(jié)數(shù);
選項(xiàng)蛾茉,長度可變李命,定義一些其他的可選的參數(shù)。
TCP連接的建立(三次握手)
這里寫圖片描述
最開始的時候客戶端和服務(wù)器都是處于CLOSED狀態(tài)浪读。主動打開連接的為客戶端,被動打開連接的是服務(wù)器辛藻。
TCP服務(wù)器進(jìn)程先創(chuàng)建傳輸控制塊TCB碘橘,時刻準(zhǔn)備接受客戶進(jìn)程的連接請求,此時服務(wù)器就進(jìn)入了LISTEN(監(jiān)聽)狀態(tài)吱肌;
TCP客戶進(jìn)程也是先創(chuàng)建傳輸控制塊TCB痘拆,然后向服務(wù)器發(fā)出連接請求報(bào)文,這是報(bào)文首部中的同部位SYN=1氮墨,同時選擇一個初始序列號 seq=x 纺蛆,此時吐葵,TCP客戶端進(jìn)程進(jìn)入了 SYN-SENT(同步已發(fā)送狀態(tài))狀態(tài)。TCP規(guī)定桥氏,SYN報(bào)文段(SYN=1的報(bào)文段)不能攜帶數(shù)據(jù)温峭,但需要消耗掉一個序號。
TCP服務(wù)器收到請求報(bào)文后字支,如果同意連接凤藏,則發(fā)出確認(rèn)報(bào)文。確認(rèn)報(bào)文中應(yīng)該 ACK=1堕伪,SYN=1揖庄,確認(rèn)號是ack=x+1,同時也要為自己初始化一個序列號 seq=y欠雌,此時蹄梢,TCP服務(wù)器進(jìn)程進(jìn)入了SYN-RCVD(同步收到)狀態(tài)。這個報(bào)文也不能攜帶數(shù)據(jù)桨昙,但是同樣要消耗一個序號检号。
TCP客戶進(jìn)程收到確認(rèn)后,還要向服務(wù)器給出確認(rèn)蛙酪。確認(rèn)報(bào)文的ACK=1齐苛,ack=y+1,自己的序列號seq=x+1桂塞,此時凹蜂,TCP連接建立,客戶端進(jìn)入ESTABLISHED(已建立連接)狀態(tài)阁危。TCP規(guī)定玛痊,ACK報(bào)文段可以攜帶數(shù)據(jù),但是如果不攜帶數(shù)據(jù)則不消耗序號狂打。
當(dāng)服務(wù)器收到客戶端的確認(rèn)后也進(jìn)入ESTABLISHED狀態(tài)擂煞,此后雙方就可以開始通信了。
三次握手
為什么TCP客戶端最后還要發(fā)送一次確認(rèn)呢趴乡?
一句話对省,主要防止已經(jīng)失效的連接請求報(bào)文突然又傳送到了服務(wù)器,從而產(chǎn)生錯誤晾捏。
如果使用的是兩次握手建立連接蒿涎,假設(shè)有這樣一種場景,客戶端發(fā)送了第一個請求連接并且沒有丟失惦辛,只是因?yàn)樵诰W(wǎng)絡(luò)結(jié)點(diǎn)中滯留的時間太長了劳秋,由于TCP的客戶端遲遲沒有收到確認(rèn)報(bào)文,以為服務(wù)器沒有收到,此時重新向服務(wù)器發(fā)送這條報(bào)文玻淑,此后客戶端和服務(wù)器經(jīng)過兩次握手完成連接嗽冒,傳輸數(shù)據(jù),然后關(guān)閉連接岁忘。此時此前滯留的那一次請求連接辛慰,網(wǎng)絡(luò)通暢了到達(dá)了服務(wù)器,這個報(bào)文本該是失效的干像,但是,兩次握手的機(jī)制將會讓客戶端和服務(wù)器再次建立連接驰弄,這將導(dǎo)致不必要的錯誤和資源的浪費(fèi)麻汰。
如果采用的是三次握手,就算是那一次失效的報(bào)文傳送過來了戚篙,服務(wù)端接受到了那條失效報(bào)文并且回復(fù)了確認(rèn)報(bào)文五鲫,但是客戶端不會再次發(fā)出確認(rèn)。由于服務(wù)器收不到確認(rèn)岔擂,就知道客戶端并沒有請求連接位喂。
TCP連接的釋放(四次揮手)
這里寫圖片描述
數(shù)據(jù)傳輸完畢后,雙方都可釋放連接乱灵。最開始的時候塑崖,客戶端和服務(wù)器都是處于ESTABLISHED狀態(tài),然后客戶端主動關(guān)閉痛倚,服務(wù)器被動關(guān)閉规婆。
客戶端進(jìn)程發(fā)出連接釋放報(bào)文,并且停止發(fā)送數(shù)據(jù)蝉稳。釋放數(shù)據(jù)報(bào)文首部抒蚜,F(xiàn)IN=1,其序列號為seq=u(等于前面已經(jīng)傳送過來的數(shù)據(jù)的最后一個字節(jié)的序號加1)耘戚,此時嗡髓,客戶端進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài)。 TCP規(guī)定收津,F(xiàn)IN報(bào)文段即使不攜帶數(shù)據(jù)饿这,也要消耗一個序號。
服務(wù)器收到連接釋放報(bào)文朋截,發(fā)出確認(rèn)報(bào)文蛹稍,ACK=1,ack=u+1部服,并且?guī)献约旱男蛄刑杝eq=v唆姐,此時,服務(wù)端就進(jìn)入了CLOSE-WAIT(關(guān)閉等待)狀態(tài)廓八。TCP服務(wù)器通知高層的應(yīng)用進(jìn)程奉芦,客戶端向服務(wù)器的方向就釋放了赵抢,這時候處于半關(guān)閉狀態(tài),即客戶端已經(jīng)沒有數(shù)據(jù)要發(fā)送了声功,但是服務(wù)器若發(fā)送數(shù)據(jù)烦却,客戶端依然要接受。這個狀態(tài)還要持續(xù)一段時間先巴,也就是整個CLOSE-WAIT狀態(tài)持續(xù)的時間其爵。
客戶端收到服務(wù)器的確認(rèn)請求后,此時伸蚯,客戶端就進(jìn)入FIN-WAIT-2(終止等待2)狀態(tài)摩渺,等待服務(wù)器發(fā)送連接釋放報(bào)文(在這之前還需要接受服務(wù)器發(fā)送的最后的數(shù)據(jù))。
服務(wù)器將最后的數(shù)據(jù)發(fā)送完畢后剂邮,就向客戶端發(fā)送連接釋放報(bào)文摇幻,F(xiàn)IN=1,ack=u+1挥萌,由于在半關(guān)閉狀態(tài)绰姻,服務(wù)器很可能又發(fā)送了一些數(shù)據(jù),假定此時的序列號為seq=w引瀑,此時狂芋,服務(wù)器就進(jìn)入了LAST-ACK(最后確認(rèn))狀態(tài),等待客戶端的確認(rèn)伤疙。
客戶端收到服務(wù)器的連接釋放報(bào)文后银酗,必須發(fā)出確認(rèn),ACK=1徒像,ack=w+1黍特,而自己的序列號是seq=u+1,此時锯蛀,客戶端就進(jìn)入了TIME-WAIT(時間等待)狀態(tài)灭衷。注意此時TCP連接還沒有釋放,必須經(jīng)過2??MSL(最長報(bào)文段壽命)的時間后旁涤,當(dāng)客戶端撤銷相應(yīng)的TCB后翔曲,才進(jìn)入CLOSED狀態(tài)。
服務(wù)器只要收到了客戶端發(fā)出的確認(rèn)劈愚,立即進(jìn)入CLOSED狀態(tài)瞳遍。同樣,撤銷TCB后菌羽,就結(jié)束了這次的TCP連接掠械。可以看到,服務(wù)器結(jié)束TCP連接的時間要比客戶端早一些猾蒂。
四次揮手
為什么客戶端最后還要等待2MSL均唉?
MSL(Maximum Segment Lifetime),TCP允許不同的實(shí)現(xiàn)可以設(shè)置不同的MSL值舔箭。
第一,保證客戶端發(fā)送的最后一個ACK報(bào)文能夠到達(dá)服務(wù)器蚊逢,因?yàn)檫@個ACK報(bào)文可能丟失层扶,站在服務(wù)器的角度看來,我已經(jīng)發(fā)送了FIN+ACK報(bào)文請求斷開了时捌,客戶端還沒有給我回應(yīng)怒医,應(yīng)該是我發(fā)送的請求斷開報(bào)文它沒有收到,于是服務(wù)器又會重新發(fā)送一次奢讨,而客戶端就能在這個2MSL時間段內(nèi)收到這個重傳的報(bào)文,接著給出回應(yīng)報(bào)文焰薄,并且會重啟2MSL計(jì)時器拿诸。
第二,防止類似與“三次握手”中提到了的“已經(jīng)失效的連接請求報(bào)文段”出現(xiàn)在本連接中塞茅∧堵耄客戶端發(fā)送完最后一個確認(rèn)報(bào)文后,在這個2MSL時間中野瘦,就可以使本連接持續(xù)的時間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失描沟。這樣新的連接中不會出現(xiàn)舊連接的請求報(bào)文。
為什么建立連接是三次握手鞭光,關(guān)閉連接確是四次揮手呢吏廉?
建立連接的時候, 服務(wù)器在LISTEN狀態(tài)下惰许,收到建立連接請求的SYN報(bào)文后席覆,把ACK和SYN放在一個報(bào)文里發(fā)送給客戶端。
而關(guān)閉連接時汹买,服務(wù)器收到對方的FIN報(bào)文時佩伤,僅僅表示對方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù),而自己也未必全部數(shù)據(jù)都發(fā)送給對方了晦毙,所以己方可以立即關(guān)閉生巡,也可以發(fā)送一些數(shù)據(jù)給對方后,再發(fā)送FIN報(bào)文給對方來表示同意現(xiàn)在關(guān)閉連接见妒,因此孤荣,己方ACK和FIN一般都會分開發(fā)送,從而導(dǎo)致多了一次。
如果已經(jīng)建立了連接垃环,但是客戶端突然出現(xiàn)故障了怎么辦邀层?
TCP還設(shè)有一個保活計(jì)時器遂庄,顯然寥院,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去涛目,白白浪費(fèi)資源秸谢。服務(wù)器每收到一次客戶端的請求后都會重新復(fù)位這個計(jì)時器,時間通常是設(shè)置為2小時霹肝,若兩小時還沒有收到客戶端的任何數(shù)據(jù)估蹄,服務(wù)器就會發(fā)送一個探測報(bào)文段,以后每隔75分鐘發(fā)送一次沫换。若一連發(fā)送10個探測報(bào)文仍然沒反應(yīng)臭蚁,服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接讯赏。
TCP如何保證可靠性
? 數(shù)據(jù)包校驗(yàn)
? 超時重傳機(jī)制
? 應(yīng)答機(jī)制
? 對失序數(shù)據(jù)包重排序
? TCP還能提供流量控制
https://blog.csdn.net/guanghuichenshao/article/details/81916277
3