TCP/IP入门(3) --传输层
/**
本篇博客由汗青ZJF整理并發(fā)布,?轉(zhuǎn)載請注明出處:
http://blog.csdn.net/zjf280441589/article/category/1854365
*/
傳輸層的主要功能
? ? 1)傳輸層為應(yīng)用進(jìn)程之間提供端到端的邏輯通信(網(wǎng)絡(luò)層是為主機(jī)到主機(jī)提供邏輯通信)。
? ??2)復(fù)用和分用:?復(fù)用是指發(fā)送方不同的應(yīng)用進(jìn)程都可以使用同一個(gè)傳輸層協(xié)議傳送數(shù)據(jù);?分用是指接收方的傳輸層在剝?nèi)?bào)文的首部之后能夠把這些數(shù)據(jù)正確交付到目的應(yīng)用進(jìn)程.
? ??3)傳輸層還會(huì)對收到的報(bào)文進(jìn)行差錯(cuò)檢測(首部和數(shù)據(jù)部分),?而網(wǎng)絡(luò)層只檢查IP數(shù)據(jù)報(bào)的首部,?不檢驗(yàn)數(shù)據(jù)部分是否出錯(cuò)。
? ??4)傳輸層需要有兩種不同的運(yùn)輸協(xié)議:面向連接的傳輸控制協(xié)議?TCP?(Transmission?Control?Protocol)和無連接的用戶數(shù)據(jù)報(bào)協(xié)議?UDP?(User?Datagram?Protocol);
?
流量控制與擁塞控制的區(qū)別
? ??流量控制往往是指在發(fā)送端和接收端之間的點(diǎn)對點(diǎn)通信量的控制.?流量控制所要做的是抑制發(fā)送端發(fā)送數(shù)據(jù)的速率,?以便使接收端來得及接收;?而擁塞控制必須確保通信子網(wǎng)能夠傳送待傳送的數(shù)據(jù),?是一個(gè)全局性的問題,?涉及網(wǎng)絡(luò)中所有的主機(jī)、路由器以及導(dǎo)致網(wǎng)絡(luò)傳輸能力下降的所有因素.
?
端口
? ??端口就是傳輸層的服務(wù)訪問點(diǎn),?用一個(gè)?16位的數(shù)字進(jìn)行標(biāo)標(biāo)記。
? ??端口號(hào)只具有本地意義,即端口號(hào)只是為了標(biāo)志本計(jì)算機(jī)應(yīng)用層中的各進(jìn)程。在因特網(wǎng)中不同計(jì)算機(jī)的相同端口號(hào)是沒有聯(lián)系的。
? ??端口的作用是讓應(yīng)用層的各種應(yīng)用進(jìn)程都能將其數(shù)據(jù)通過端口向下交付給傳輸層,以及讓傳輸層知道應(yīng)當(dāng)將其報(bào)文段中的數(shù)據(jù)向上通過端口交付給應(yīng)用層的哪個(gè)進(jìn)程。
? ??從這個(gè)意義上講,端口是用來標(biāo)志應(yīng)用層的進(jìn)程;
?
常用端口號(hào)
應(yīng)用程序 | echo | ftp | ssh | telnet | smtp |
端口號(hào) | 7 | 20,21 | 22 | 23 | 25 |
應(yīng)用程序 | dns | dhcp | tftp | http | pop3 |
端口號(hào) | 53 | 67,?68 | 69 | 80 | 110 |
?
TCP?VS?UDP
1)TCP
? ??TCP是一種面向連接的(一對一),提供可靠交付的和全雙工通信的,基于字節(jié)流的端到端傳輸層通信協(xié)議。
? ??面向連接:?TCP在傳輸數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳輸結(jié)束后要釋放連接。
? ??一對一:?每一條TCP連接只能有2個(gè)端點(diǎn),故TCP不提供廣播或多播服務(wù)。
? ??可靠交付:?TCP提供可靠交付,通過TCP連接傳輸?shù)臄?shù)據(jù),無差錯(cuò)、不丟失、不重復(fù)、并且按序到達(dá)。
? ??基于字節(jié)流:?TCP是面向字節(jié)流的。雖然應(yīng)用進(jìn)程和TCP的交互是一次一個(gè)數(shù)據(jù)塊(大小不等),但TCP把應(yīng)用程序交下來的數(shù)據(jù)僅僅看成是一連串的無結(jié)構(gòu)的字節(jié)流,?而并不知道所傳輸?shù)淖止?jié)流的含義。
?
2)UDP
? ??UDP是一種無連接的,盡最大努力交付的和全雙工通信的,基于報(bào)文段的端到端傳輸層通信協(xié)議。
? ??無連接:?UDP在發(fā)送數(shù)據(jù)之前不需要建立連接
? ??盡最大努力交付:?UDP不保證可靠交付,主機(jī)不需要維持復(fù)雜的連接狀態(tài)
? ??面向報(bào)文:?UDP是面向報(bào)文的。UDP對應(yīng)用層交下來的報(bào)文,既不合并,也不拆分,而是保留這些報(bào)文的的邊界,即應(yīng)用層交給UDP多長的報(bào)文,UDP就照樣發(fā)送,即一次發(fā)送一個(gè)報(bào)文。在接收端,UDP一次交付一個(gè)完整的報(bào)文,?因此應(yīng)用程序需要選擇合適的報(bào)文大小。
其他:
? ??UDP沒有擁塞控制,網(wǎng)絡(luò)出現(xiàn)的擁塞不會(huì)使源主機(jī)的發(fā)送速率降低。
? ??UDP支持一對一、一對多、多對一和多對多的交互通信。
? ??UDP的首部開銷小,只有8個(gè)字節(jié),比TCP的20個(gè)字節(jié)的首部要短。
?
3)區(qū)別
TCP | UDP |
面向連接 | 無連接 |
傳輸速度慢 | 傳輸速度快 |
保證數(shù)據(jù)有序到達(dá) | 不保證數(shù)據(jù)有序到達(dá) |
保證數(shù)據(jù)正確性 | 可能丟包 |
TCP報(bào)文段 | UDP用戶數(shù)據(jù)報(bào) |
系統(tǒng)資源要求多(需要內(nèi)核維護(hù)發(fā)送/接受緩沖區(qū)) | 要求少(不需要內(nèi)核維護(hù)緩沖區(qū),?直接將數(shù)據(jù)報(bào)發(fā)送到網(wǎng)絡(luò)上,?或直接交付給進(jìn)程) |
適用于對效率要求相對低,但對準(zhǔn)確性要求相對高的場景下,或者是有一種連接概念的場景(如HTTP服務(wù)) | 適用于對效率要求相對高,對準(zhǔn)確性要求相對低的場景(如視頻點(diǎn)播) |
UDP數(shù)據(jù)報(bào)
?
UDP有兩個(gè)字段:?首部字段和數(shù)據(jù)字段。
首部字段很簡單,只有8個(gè)字節(jié),由4個(gè)字段組成,每個(gè)字段的長度都是兩個(gè)字節(jié)。
源端口號(hào) | 在需要對方回信時(shí)選用。不需要時(shí)可用全0 |
目的端口號(hào) | 這在終點(diǎn)交付報(bào)文時(shí)必須要使用到 |
UDP長度 | UDP用戶數(shù)據(jù)報(bào)的長度,其最小值是8(僅有首部) |
UDP校驗(yàn)和 | 檢測UDP用戶數(shù)據(jù)報(bào)在傳輸中是否有錯(cuò)。有錯(cuò)就丟棄 |
?
UDP校驗(yàn)
? ??UDP首部中校驗(yàn)和的計(jì)算方法有些特殊。在計(jì)算校驗(yàn)和時(shí),要在UDP用戶數(shù)據(jù)報(bào)之前增加12個(gè)字節(jié)的偽首部。偽首部既不向下傳送也不向上遞交,而僅僅是為了計(jì)算校驗(yàn)和。與IP數(shù)據(jù)報(bào)的校驗(yàn)和只校驗(yàn)IP數(shù)據(jù)報(bào)的首部不同,UDP的校驗(yàn)和是把首部和數(shù)據(jù)部分一起都校驗(yàn)。
? ??在計(jì)算檢驗(yàn)和時(shí),臨時(shí)把“偽首部”和?UDP?用戶數(shù)據(jù)報(bào)連接在一起。偽首部僅僅是為了計(jì)算檢驗(yàn)和,?示例如下:
?
? ??在發(fā)送方,首先是把全零放入校驗(yàn)和字段并且添加偽首部。然后,把UDP數(shù)據(jù)報(bào)看成是由許多16位的字串連接起來。若UDP數(shù)據(jù)報(bào)的數(shù)據(jù)部分不是偶數(shù)個(gè)字節(jié),則要在數(shù)據(jù)部分末尾增加一個(gè)全零字節(jié)(但此字節(jié)不發(fā)送)。接下來就按二進(jìn)制反碼計(jì)算出這些16位字的和。將此和的二進(jìn)制反碼寫入校驗(yàn)和字段。在接收方,把收到的UDP數(shù)據(jù)報(bào)加上偽首部(如果不為偶數(shù)個(gè)字節(jié),還需要補(bǔ)上全零字節(jié))后,按二進(jìn)制反碼計(jì)算出這些16位字的和。當(dāng)無差錯(cuò)時(shí)其結(jié)果應(yīng)全為1。否則就表明有差錯(cuò)出現(xiàn),接收方就應(yīng)該丟棄這個(gè)UDP數(shù)據(jù)報(bào)。
TCP報(bào)文段
協(xié)議描述 | |
源端口/目的端口 | 源/目的主機(jī)的IP地址加上端口號(hào)構(gòu)成一個(gè)TCP連接(Socket) |
序號(hào)和確認(rèn)號(hào) | 序號(hào)為該TCP數(shù)據(jù)包的第一個(gè)字節(jié)在所發(fā)送的數(shù)據(jù)流中的偏移量;確認(rèn)號(hào)為希望接收的下一個(gè)數(shù)據(jù)字節(jié)的序號(hào); |
數(shù)據(jù)偏移(首部長度) | 以4個(gè)字節(jié)為單位,通常為20個(gè)字節(jié) |
6個(gè)標(biāo)志位: | ? |
????URG | 如果使用了緊急指針,URG置1,緊急指針為當(dāng)前序號(hào)到緊急數(shù)據(jù)位置的偏移量(常用于發(fā)送/接受帶外數(shù)據(jù)) |
????ACK | 為1表示確認(rèn)號(hào)有效,為0表示該TCP數(shù)據(jù)包不包含確認(rèn)信息 |
????PSH | 表示是帶有PUSH標(biāo)志的數(shù)據(jù),接收到數(shù)據(jù)后不必等緩沖區(qū)滿再發(fā)送(較少使用) |
????RST | 置為1時(shí)表示TCP連接中出現(xiàn)了嚴(yán)重的差錯(cuò),?必須釋放連接,?然后重建連接,?也可用于拒絕非法的數(shù)據(jù)或拒絕連接請求 |
????SYN | 用于建立連接,連接請求時(shí)SYN=1,ACK=0;響應(yīng)連接請求時(shí)SYN=1,ACK=1 |
????FIN | 用于釋放連接,表示發(fā)送方已經(jīng)沒有供發(fā)送的數(shù)據(jù) |
窗口大小 | 用來讓對方設(shè)置發(fā)送窗口的大小(用于流量控制) |
校驗(yàn)和 | 校驗(yàn)和覆蓋了整個(gè)數(shù)據(jù)包,包括對數(shù)據(jù)包的首部和數(shù)據(jù) |
緊急指針 | 指出本報(bào)文段中緊急指針共占用多少個(gè)字節(jié)(緊急數(shù)據(jù)放在本報(bào)文段數(shù)據(jù)的最前面) |
選項(xiàng) | 常見的選項(xiàng)是MSS(Maximum?Segment?Size,?最大報(bào)文長度) |
填充字段 | 為了使整個(gè)首部為4字節(jié)整數(shù)倍 |
TCP三次握手
為什么需要采用三次握手?
? ??主要是為了防止兩次握手情況下已失效的連接請求報(bào)文段突然又傳送到服務(wù)端,而產(chǎn)生的錯(cuò)誤。舉例如下:
? ??客戶A向服務(wù)器B發(fā)出TCP連接請求,第一個(gè)連接請求報(bào)文在網(wǎng)絡(luò)的某個(gè)節(jié)點(diǎn)長時(shí)間滯留,A超時(shí)后認(rèn)為報(bào)文丟失,于是再重傳一次連接請求,B收到后建立連接。數(shù)據(jù)傳輸完畢后雙方斷開連接。而此時(shí),前一個(gè)滯留在網(wǎng)絡(luò)中的連接請求到達(dá)了服務(wù)端B,而B認(rèn)為A又發(fā)來連接請求,若采用的是“兩次握手”,則這種情況下B認(rèn)為傳輸連接已經(jīng)建立,并一直等待A傳輸數(shù)據(jù),而A此時(shí)并無連接請求,因此不予理睬,這樣就造成了B的資源白白浪費(fèi)了;但此時(shí)若是使用“三次握手”,則B向A返回確認(rèn)報(bào)文段,由于是一個(gè)失效的請求,因此A不予理睬,建立連接失敗。第三次握手的作用:防止已失效的連接請求報(bào)文段突然又傳送到了服務(wù)器。
?
三次握手過程
?
?
? ??1)第一次握手:客戶機(jī)的TCP首先向服務(wù)器的TCP發(fā)送一個(gè)連接請求報(bào)文段。這個(gè)特殊的報(bào)文段中不含應(yīng)用層數(shù)據(jù),其首部中的SYN標(biāo)志位被置為1。另外,客戶機(jī)會(huì)隨機(jī)選擇一個(gè)起始序號(hào)seq=x(連接請求報(bào)文不攜帶數(shù)據(jù),但要消耗掉一個(gè)序號(hào))。
? ??2)第二次握手:服務(wù)器的TCP收到連接請求報(bào)文段后,如同意建立連接,就向客戶機(jī)發(fā)回確認(rèn),并在OS內(nèi)核中為該TCP連接分配TCP緩存和變量。在確認(rèn)報(bào)文段中,SYN和ACK位都被置為1,確認(rèn)號(hào)字段的值為x+1(表示希望收到的下一個(gè)字節(jié)的序號(hào)為x+1),并且服務(wù)器隨機(jī)產(chǎn)生起始序號(hào)seq=y(確認(rèn)報(bào)文不攜帶數(shù)據(jù),但也要消耗掉一個(gè)序號(hào))。
? ??3)第三次握手:當(dāng)客戶機(jī)收到確認(rèn)報(bào)文段后,還要向服務(wù)器給出確認(rèn),并且也要在client端的OS內(nèi)核中給該連接分配緩存和變量。這個(gè)報(bào)文段的ACK標(biāo)志位被置1,序號(hào)字段為x+1,確認(rèn)號(hào)字段為y+1。
? ??需要注意的是:服務(wù)器端的資源是在完成第二次握手時(shí)分配的,而客戶端的資源是在完成第三次握手時(shí)分配的。這就使得服務(wù)器易于受到SYN洪泛攻擊。
?
TCP四次斷開
?
? ??1)第一次斷開:客戶機(jī)打算關(guān)閉連接,就向其TCP發(fā)送一個(gè)連接釋放報(bào)文段,并停止發(fā)送數(shù)據(jù),主動(dòng)關(guān)閉TCP連接,該報(bào)文段的FIN標(biāo)志位被置1,seq=u,它等于前面已傳送過的數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào)加1(FIN報(bào)文段即使不攜帶數(shù)據(jù),也要消耗掉一個(gè)序號(hào))。
? ??2)第二次斷開:服務(wù)器收到連接釋放報(bào)文段后即發(fā)出確認(rèn),確認(rèn)號(hào)是ack=u+1,而這個(gè)報(bào)文段自己的序號(hào)是v,等于它前面已傳送過的數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào)加1。此時(shí),從客戶機(jī)到服務(wù)器這個(gè)方向的連接就釋放了,TCP連接處于半關(guān)閉狀態(tài)。但服務(wù)器若發(fā)送數(shù)據(jù),客戶機(jī)仍要接收,即從服務(wù)器到客戶機(jī)這個(gè)方向的連接并未關(guān)閉。
? ??3)第三次斷開:若服務(wù)器已經(jīng)沒有要向客戶機(jī)發(fā)送的數(shù)據(jù),就通知TCP釋放連接,此時(shí)其發(fā)出FIN=1的連接釋放報(bào)文段(注意:?此時(shí)確認(rèn)號(hào)字段值仍為u+1,?因?yàn)檫@段時(shí)間里,?客戶端并未發(fā)送任何數(shù)據(jù)到服務(wù)器)。
? ??4)第四次斷開:客戶機(jī)收到連接釋放報(bào)文段后,必須發(fā)出確認(rèn)。在確認(rèn)報(bào)文段中,ACK字段被置為1,確認(rèn)號(hào)ack=w+1,序號(hào)seq=u+1。此時(shí)TCP連接還沒有釋放掉,必須經(jīng)過時(shí)間等待計(jì)時(shí)器設(shè)置的時(shí)間2MSL后,A才進(jìn)入到連接關(guān)閉狀態(tài)。
?
TIME_WAIT狀態(tài)
? ??1)為了保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文段能夠達(dá)到服務(wù)器。?這個(gè)ACK報(bào)文段可能丟失,因而使處在LAST_ACK狀態(tài)的服務(wù)器收不到確認(rèn)。這樣的話,?服務(wù)器會(huì)超時(shí)重傳FIN+ACK報(bào)文段,客戶端就能在2MSL時(shí)間內(nèi)收到這個(gè)重傳的FIN+ACK報(bào)文段,接著客戶端重傳一次確認(rèn),重啟計(jì)時(shí)器。最后,客戶端和服務(wù)器都正常進(jìn)入到CLOSED狀態(tài)。
? ??如果客戶端在TIME_WAIT狀態(tài)不等待一段時(shí)間,而是在發(fā)送完ACK報(bào)文后立即釋放連接,那么就無法收到服務(wù)器重傳的FIN+ACK報(bào)文段,因而也不會(huì)再發(fā)送一次確認(rèn)報(bào)文。這樣,服務(wù)器就無法按照正常步驟進(jìn)入CLOSED狀態(tài)。
? ??2)防止已失效的連接請求報(bào)文段出現(xiàn)在本連接中。客戶端在發(fā)送完最后一個(gè)ACK確認(rèn)報(bào)文段后,再經(jīng)過時(shí)間2MSL,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。這樣就可以使下一個(gè)新的連接中不會(huì)出現(xiàn)這種舊的連接請求報(bào)文段。
? ??注意:服務(wù)器結(jié)束TCP連接的時(shí)間要比客戶端早一些,因?yàn)榭蛻魴C(jī)(最先提出close請求的一端)最后要等待2MSL后才可以進(jìn)入CLOSED狀態(tài)。
TCP如何保證可靠性
? ??序號(hào):?TCP連接中傳送的數(shù)據(jù)流中的每一個(gè)字節(jié)都編上一個(gè)序號(hào)。序號(hào)字段的值則指的是本報(bào)文段所發(fā)送的數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào);
? ??確認(rèn):?TCP首部的確認(rèn)號(hào)是期望收到對方的下一個(gè)報(bào)文段數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào)。當(dāng)數(shù)據(jù)發(fā)送出去之后,?發(fā)送方緩存區(qū)會(huì)繼續(xù)存儲(chǔ)那些已經(jīng)發(fā)送但未收到確認(rèn)的報(bào)文段,以便在需要的時(shí)候重傳。TCP默認(rèn)使用累計(jì)確認(rèn),即TCP只確認(rèn)數(shù)據(jù)流中至第一個(gè)丟失字節(jié)為止的字節(jié)。
? ??重傳:?有兩種事件會(huì)導(dǎo)致TCP對報(bào)文段進(jìn)行重傳:超時(shí)和冗余ACK。
? ??? ??1)超時(shí):?TCP每發(fā)送一個(gè)報(bào)文段,就對這個(gè)報(bào)文段設(shè)置一次計(jì)時(shí)器。只要計(jì)時(shí)器設(shè)置的重傳時(shí)間到期但還沒有收到確認(rèn),就要重傳這一報(bào)文段。
? ??? ??2)冗余ACK(冗余確認(rèn)):?冗余ACK就是再次確認(rèn)某個(gè)報(bào)文段的ACK,而發(fā)送方先前已經(jīng)收到過該報(bào)文段的確認(rèn);?TCP規(guī)定當(dāng)發(fā)送方收到對同一個(gè)報(bào)文段的3個(gè)冗余ACK時(shí),就可以認(rèn)為跟在這個(gè)被確認(rèn)報(bào)文段之后的報(bào)文段已經(jīng)丟失;
? ??校驗(yàn):?TCP將保持它首部和數(shù)據(jù)的校驗(yàn)和。這是一個(gè)端到端的校驗(yàn)和,目的是檢測數(shù)據(jù)在傳輸過程中的任何變化。如果收到段的校驗(yàn)和有差錯(cuò),TCP將丟棄這個(gè)報(bào)文段并且不確認(rèn)(導(dǎo)致對方超時(shí)重傳);
? ??重排:?TCP承載于IP數(shù)據(jù)報(bào)來傳輸,而IP數(shù)據(jù)報(bào)的到達(dá)可能會(huì)失序,因此TCP報(bào)文段的到達(dá)也可能會(huì)失序。TCP將對收到的數(shù)據(jù)進(jìn)行重新排序。IP數(shù)據(jù)報(bào)會(huì)發(fā)生重復(fù),TCP的接收端會(huì)丟棄重復(fù)的數(shù)據(jù)。
? ??流量控制:?TCP還能提供流量控制。TCP連接的每一方都有一定大小的緩沖空間。
? ??分割:?應(yīng)用數(shù)據(jù)被分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊,稱為TCP報(bào)文段傳遞給IP層。
?
滑動(dòng)窗口協(xié)議與停止等待協(xié)議的區(qū)別
? ??滑動(dòng)窗口協(xié)議中,允許發(fā)送方發(fā)送多個(gè)分組(當(dāng)有多個(gè)分組可用時(shí)),?而不需等待確認(rèn),但它受限于在流水線中未確認(rèn)的分組數(shù)不能超過某個(gè)最大允許數(shù)N。
? ??滑動(dòng)窗口協(xié)議是TCP使用的一種控制流量的方法,此協(xié)議能夠加速數(shù)據(jù)的傳輸。?只有在接收窗口向前滑動(dòng)時(shí)(與此同時(shí)也發(fā)送了確認(rèn)),?發(fā)送窗口才有可能向前滑動(dòng)。收發(fā)兩端的窗口按照以上規(guī)律不斷地向前滑動(dòng),因此這種協(xié)議稱為滑動(dòng)窗口協(xié)議。
? ??當(dāng)發(fā)送窗口和接收窗口的大小都等于1時(shí),就是停止等待協(xié)議。
TCP流量控制
? ??TCP提供了流量控制服務(wù)以消除發(fā)送方使接收方緩存區(qū)溢出的可能性,因此可以說流量控制是一個(gè)速度匹配服務(wù)(匹配發(fā)送方的發(fā)送速率與接收方的讀取速率)。
? ??在通信過程中,接收方根據(jù)自己接收緩存的大小,動(dòng)態(tài)地調(diào)整發(fā)送方的發(fā)送窗口大小,這就是接收窗口rwnd,即調(diào)整TCP報(bào)文段首部中的“窗口”字段值,來限制發(fā)送方向網(wǎng)絡(luò)注入報(bào)文的速率。同時(shí),發(fā)送方根據(jù)其對當(dāng)前網(wǎng)絡(luò)擁塞程序的估計(jì)而確定的窗口值,稱為擁塞窗口cwnd,其大小與網(wǎng)絡(luò)的帶寬和時(shí)延密切相關(guān)。
?
滑動(dòng)窗口
? ??TCP?采用大小可變的滑動(dòng)窗口進(jìn)行流量控制(窗口大小的單位是字節(jié)),?在?TCP?報(bào)文段首部的窗口字段寫入的數(shù)值就是當(dāng)前給對方設(shè)置的發(fā)送窗口數(shù)值的上限。
? ??發(fā)送窗口在連接建立時(shí)由雙方商定。但在通信的過程中,接收端可根據(jù)自己的資源情況,隨時(shí)動(dòng)態(tài)地調(diào)整對方的發(fā)送窗口上限值(可增大或減小)。
?
發(fā)送過程及詳細(xì)分析
? ??1)發(fā)送端要發(fā)送?900?字節(jié)長的數(shù)據(jù),劃分為?9?個(gè)?100?字節(jié)長的報(bào)文段,而發(fā)送窗口確定為?500?字節(jié)。 發(fā)送端只要收到了對方的確認(rèn),發(fā)送窗口就可前移。發(fā)送?TCP?要維護(hù)一個(gè)指針。每發(fā)送一個(gè)報(bào)文段,指針就向前移動(dòng)一個(gè)報(bào)文段的距離。
?
? ??2)發(fā)送端已發(fā)送了?400?字節(jié)的數(shù)據(jù),但只收到對前?200?字節(jié)數(shù)據(jù)的確認(rèn),同時(shí)窗口大小不變。現(xiàn)在發(fā)送端還可發(fā)送?300?字節(jié)(401~700)。
?
? ??3)發(fā)送端收到了對方對前?400?字節(jié)數(shù)據(jù)的確認(rèn),但對方通知發(fā)送端必須把窗口減小到?400?字節(jié)。現(xiàn)在發(fā)送端最多還可發(fā)送?400?字節(jié)(401~800)的數(shù)據(jù)。
?
利用可變窗口大小進(jìn)行流量控制(雙方確定的窗口值是?400)
(101~200的數(shù)據(jù)發(fā)生丟失)
慢開始和擁塞避免
1.?發(fā)送端的主機(jī)在確定發(fā)送報(bào)文段的速率時(shí),既要根據(jù)接收端的接收能力,又要從全局考慮不要使網(wǎng)絡(luò)發(fā)生擁塞。因此,每一個(gè)?TCP?連接需要有以下兩個(gè)狀態(tài)變量:
? ??接收窗口?rwnd?(receiver?window):?這是接收端根據(jù)其目前的接收緩存大小所許諾的最新的窗口值,是來自接收端的流量控制。接收端將此窗口值放在?TCP?報(bào)文的首部中的窗口字段,傳送給發(fā)送端。
? ??擁塞窗口?cwnd?(congestion?window):?是發(fā)送端根據(jù)自己估計(jì)的網(wǎng)絡(luò)擁塞程度而設(shè)置的窗口值,是來自發(fā)送端的流量控制。
? ??發(fā)送端的發(fā)送窗口的上限值應(yīng)當(dāng)取為接收端窗口?rwnd?和擁塞窗口?cwnd?這兩個(gè)變量中較小的一個(gè),即應(yīng)按以下公式確定:
? ??? ??發(fā)送窗口的上限值?=?Min(rwnd,?cwnd)
?
2.?慢開始算法
? ??在TCP剛剛連接好,開始發(fā)送TCP報(bào)文段時(shí),先令擁塞窗口cwnd=1,即一個(gè)最大報(bào)文段長度MSS。而在每收到一個(gè)對新的報(bào)文段的確認(rèn)后,將cwnd加1,即增大一個(gè)MSS。用這樣的方法逐步增大發(fā)送方的擁塞窗口cwnd,可以使分組注入到網(wǎng)絡(luò)的速率更加合理。
? ??使用慢開始算法后,每經(jīng)過一個(gè)傳輸輪次(即往返時(shí)延RTT),擁塞窗口cwnd就會(huì)加倍,即cwnd的大小呈指數(shù)形式增長(可以看出”慢開始”并不”慢”)。這樣慢開始一直把擁塞窗口cwnd增大到一個(gè)規(guī)定的慢開始門限ssthresh(閾值),然后改用擁塞避免算法。
?
3.?擁塞避免算法
? ??發(fā)送端的擁塞窗口cwnd每經(jīng)過一個(gè)往返時(shí)延RTT就增加一個(gè)MSS的大小,而不是加倍(不同于慢開始算法),使cwnd按線性規(guī)律緩慢增長(即加法增大),而當(dāng)出現(xiàn)一次超時(shí)(網(wǎng)絡(luò)擁塞)時(shí),則令慢開始門限ssthresh等于當(dāng)前cwnd的一半(即乘法減小)。
根據(jù)cwnd的大小執(zhí)行不同的算法,可歸納如下:
? ??? ??當(dāng)cwnd<ssthresh時(shí),使用慢開始算法。
? ??? ??當(dāng)cwnd>ssthresh時(shí),停止使用慢開始算法而改用擁塞避免算法。
? ??? ??當(dāng)cwnd=ssthresh時(shí),既可使用慢開始算法,也可使用擁塞避免算法(通常做法)。
?
4.網(wǎng)絡(luò)擁塞的處理
? ??當(dāng)網(wǎng)絡(luò)出現(xiàn)擁塞時(shí),無論在慢開始階段還是在擁塞避免階段,只要發(fā)送方檢測到超時(shí)事件的發(fā)生(沒有按時(shí)收到確認(rèn),重傳計(jì)時(shí)器超時(shí)),就要把慢開始門限ssthresh設(shè)置為出現(xiàn)擁塞時(shí)的發(fā)送方cwnd值的一半(但不能小于2)。然后把擁塞窗口cwnd重新設(shè)置為1,執(zhí)行慢開始算法。這樣做的目的就是要迅速減少主機(jī)發(fā)送到網(wǎng)絡(luò)中的分組數(shù),使得發(fā)生擁塞的路由器有足夠時(shí)間把隊(duì)列中積壓的分組處理完畢。
? ??擁塞避免并非完全能避免擁塞。利用以上措施要完全避免網(wǎng)絡(luò)擁塞是不可能的。擁塞避免是指在擁塞避免階段把擁塞窗口控制為按線性規(guī)律增長,使網(wǎng)絡(luò)比較不容易出現(xiàn)擁塞。
? ??慢開始和擁塞避免算法的實(shí)現(xiàn)過程如下圖所示:
? ??注意,在慢開始(指數(shù)級(jí)增長)階段,若2*cwnd>ssthresh,則下一個(gè)RTT的cwnd應(yīng)等于ssthresh,而不是2*cwnd,即cwnd不能躍過ssthresh值。
?
小結(jié):
? ??在慢開始和擁塞避免算法中使用了“乘法減小”和“加法增大”方法。“乘法減小”是指不論在慢開始階段還是擁塞避免階段,只要出現(xiàn)一次超時(shí)(即很可能出現(xiàn)了網(wǎng)絡(luò)擁塞),就把慢開始門限值ssthresh設(shè)置為當(dāng)前的擁塞窗口值的一半。當(dāng)網(wǎng)絡(luò)頻繁出現(xiàn)擁塞時(shí),ssthresh值就下降得很快,以大大減少注入到網(wǎng)絡(luò)中的分組數(shù)。而“加法增大”是指執(zhí)行擁塞避免算法后,在收到對所有報(bào)文段的確認(rèn)后(即經(jīng)過一個(gè)RTT),就把擁塞窗口cwnd增加一個(gè)MSS大小,使擁塞窗口緩慢增大,以防止網(wǎng)絡(luò)過早出現(xiàn)擁塞。
快重傳與快恢復(fù)
? ??快重傳和快恢復(fù)算法是對慢開始和擁塞避免算法的改進(jìn)。
1.快重傳
? ??當(dāng)發(fā)送方連續(xù)收到三個(gè)重復(fù)的ACK報(bào)文時(shí),直接重傳對方尚未收到的報(bào)文段,而不必等待那個(gè)報(bào)文段設(shè)置的重傳計(jì)時(shí)器超時(shí)。
?
2.快恢復(fù)
? ??快恢復(fù)算法原理:當(dāng)發(fā)送端收到連續(xù)三個(gè)冗余ACK(即重復(fù)確認(rèn))時(shí),就執(zhí)行“乘法減小”算法,把慢開始門限ssthresh減半。與慢開始(慢開始算法將擁塞窗口cwnd設(shè)置為1)不同之處是它把cwnd的值設(shè)置為慢開始門限ssthresh減半后的數(shù)值,然后開始執(zhí)行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。
? ??由于跳過了cwnd從1起始的慢開始過程(因?yàn)榧热滑F(xiàn)在能夠收到三個(gè)重復(fù)ACK確認(rèn),?就說明擁塞程序并不是很大),所以被稱為快恢復(fù)。快恢復(fù)算法的實(shí)現(xiàn)過程如下圖所示,作為對比,虛線為慢開始的處理過程。
?
?
?
? ??注-發(fā)送方發(fā)送窗口的實(shí)際大小由流量控制和擁塞控制共同決定。因此,當(dāng)同時(shí)出現(xiàn)了接收端窗口(rwnd)和擁塞窗口(cwnd)時(shí),發(fā)送方實(shí)際的發(fā)送窗口大小是由rwnd和cwnd中較小的那一個(gè)確定的。
總結(jié)
以上是生活随笔為你收集整理的TCP/IP入门(3) --传输层的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。