關(guān)于 TCP/IP,運(yùn)維必知必會的十個問題
一、TCP/IP模型
上圖以HTTP協(xié)議為例,具體說明。
二、數(shù)據(jù)鏈路層
-
封裝成幀: 把網(wǎng)絡(luò)層數(shù)據(jù)報(bào)加頭和尾,封裝成幀,幀頭中包括源MAC地址和目的MAC地址。
-
透明傳輸:零比特填充、轉(zhuǎn)義字符。
-
可靠傳輸: 在出錯率很低的鏈路上很少用,但是無線鏈路WLAN會保證可靠傳輸。
-
差錯檢測(CRC):接收者檢測錯誤,如果發(fā)現(xiàn)差錯,丟棄該幀。
三、網(wǎng)絡(luò)層
1.IP協(xié)議
IP協(xié)議是TCP/IP協(xié)議的核心,所有的TCP,UDP,IMCP,IGMP的數(shù)據(jù)都以IP數(shù)據(jù)格式傳輸。要注意的是,IP不是可靠的協(xié)議,這是說,IP協(xié)議沒有提供一種數(shù)據(jù)未傳達(dá)以后的處理機(jī)制,這被認(rèn)為是上層協(xié)議:TCP或UDP要做的事情。
1.1 IP地址
B類IP地址:128.0.0.1~191.255.0.0
C類IP地址:192.168.0.0~239.255.255.0
1.2 IP協(xié)議頭
2.ARP及RARP協(xié)議
3. ICMP協(xié)議
IP協(xié)議并不是一個可靠的協(xié)議,它不保證數(shù)據(jù)被送達(dá),那么,自然的,保證數(shù)據(jù)送達(dá)的工作應(yīng)該由其他的模塊來完成。其中一個重要的模塊就是ICMP(網(wǎng)絡(luò)控制報(bào)文)協(xié)議。ICMP不是高層協(xié)議,而是IP層的協(xié)議。
當(dāng)傳送IP數(shù)據(jù)包發(fā)生錯誤。比如主機(jī)不可達(dá),路由不可達(dá)等等,ICMP協(xié)議將會把錯誤信息封包,然后傳送回給主機(jī)。給主機(jī)一個處理錯誤的機(jī)會,這 也就是為什么說建立在IP層以上的協(xié)議是可能做到安全的原因。
四、ping
ping可以說是ICMP的最著名的應(yīng)用,是TCP/IP協(xié)議的一部分。利用“ping”命令可以檢查網(wǎng)絡(luò)是否連通,可以很好地幫助我們分析和判定網(wǎng)絡(luò)故障。
例如:當(dāng)我們某一個網(wǎng)站上不去的時(shí)候。通常會ping一下這個網(wǎng)站。ping會回顯出一些有用的信息。一般的信息如下:
五、Traceroute
Traceroute是用來偵測主機(jī)到目的主機(jī)之間所經(jīng)路由情況的重要工具,也是最便利的工具。
Traceroute的原理是非常非常的有意思,它收到到目的主機(jī)的IP后,首先給目的主機(jī)發(fā)送一個TTL=1的UDP數(shù)據(jù)包,而經(jīng)過的第一個路由器收到這個數(shù)據(jù)包以后,就自動把TTL減1,而TTL變?yōu)?以后,路由器就把這個包給拋棄了,并同時(shí)產(chǎn)生 一個主機(jī)不可達(dá)的ICMP數(shù)據(jù)報(bào)給主機(jī)。主機(jī)收到這個數(shù)據(jù)報(bào)以后再發(fā)一個TTL=2的UDP數(shù)據(jù)報(bào)給目的主機(jī),然后刺激第二個路由器給主機(jī)發(fā)ICMP數(shù)據(jù) 報(bào)。如此往復(fù)直到到達(dá)目的主機(jī)。這樣,traceroute就拿到了所有的路由器IP。
六、TCP/UDP
面向報(bào)文
面向報(bào)文的傳輸方式是應(yīng)用層交給UDP多長的報(bào)文,UDP就照樣發(fā)送,即一次發(fā)送一個報(bào)文。因此,應(yīng)用程序必須選擇合適大小的報(bào)文。若報(bào)文太長,則IP層需要分片,降低效率。若太短,會是IP太小。
面向字節(jié)流
什么時(shí)候應(yīng)該使用TCP?
什么時(shí)候應(yīng)該使用UDP?
七、DNS
八、TCP連接的建立與終止
1.三次握手
為什么要三次握手?
2.四次揮手
當(dāng)客戶端和服務(wù)器通過三次握手建立了TCP連接以后,當(dāng)數(shù)據(jù)傳送完畢,肯定是要斷開TCP連接的啊。那對于TCP的斷開連接,這里就有了神秘的“四次分手”。
第一次分手:主機(jī)1(可以使客戶端,也可以是服務(wù)器端),設(shè)置Sequence Number,向主機(jī)2發(fā)送一個FIN報(bào)文段;此時(shí),主機(jī)1進(jìn)入FIN_WAIT_1狀態(tài);這表示主機(jī)1沒有數(shù)據(jù)要發(fā)送給主機(jī)2了;
第二次分手:主機(jī)2收到了主機(jī)1發(fā)送的FIN報(bào)文段,向主機(jī)1回一個ACK報(bào)文段,Acknowledgment Number為Sequence Number加1;主機(jī)1進(jìn)入FIN_WAIT_2狀態(tài);主機(jī)2告訴主機(jī)1,我“同意”你的關(guān)閉請求;
第三次分手:主機(jī)2向主機(jī)1發(fā)送FIN報(bào)文段,請求關(guān)閉連接,同時(shí)主機(jī)2進(jìn)入LAST_ACK狀態(tài);
第四次分手:主機(jī)1收到主機(jī)2發(fā)送的FIN報(bào)文段,向主機(jī)2發(fā)送ACK報(bào)文段,然后主機(jī)1進(jìn)入TIME_WAIT狀態(tài);主機(jī)2收到主機(jī)1的ACK報(bào)文段以后,就關(guān)閉連接;此時(shí),主機(jī)1等待2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,主機(jī)1也可以關(guān)閉連接了。
為什么要四次分手?
為什么要等待2MSL?
MSL:報(bào)文段最大生存時(shí)間,它是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長時(shí)間。原因有二:
-
保證TCP協(xié)議的全雙工連接能夠可靠關(guān)閉
-
保證這次連接的重復(fù)數(shù)據(jù)段從網(wǎng)絡(luò)中消失
第一點(diǎn):如果主機(jī)1直接CLOSED了,那么由于IP協(xié)議的不可靠性或者是其它網(wǎng)絡(luò)原因,導(dǎo)致主機(jī)2沒有收到主機(jī)1最后回復(fù)的ACK。那么主機(jī)2就會在超時(shí)之后繼續(xù)發(fā)送FIN,此時(shí)由于主機(jī)1已經(jīng)CLOSED了,就找不到與重發(fā)的FIN對應(yīng)的連接。所以,主機(jī)1不是直接進(jìn)入CLOSED,而是要保持TIME_WAIT,當(dāng)再次收到FIN的時(shí)候,能夠保證對方收到ACK,最后正確的關(guān)閉連接。
第二點(diǎn):如果主機(jī)1直接CLOSED,然后又再向主機(jī)2發(fā)起一個新連接,我們不能保證這個新連接與剛關(guān)閉的連接的端口號是不同的。也就是說有可能新連接和老連接的端口號是相同的。一般來說不會發(fā)生什么問題,但是還是有特殊情況出現(xiàn):假設(shè)新連接和已經(jīng)關(guān)閉的老連接端口號是一樣的,如果前一次連接的某些數(shù)據(jù)仍然滯留在網(wǎng)絡(luò)中,這些延遲數(shù)據(jù)在建立新連接之后才到達(dá)主機(jī)2,由于新連接和老連接的端口號是一樣的,TCP協(xié)議就認(rèn)為那個延遲的數(shù)據(jù)是屬于新連接的,這樣就和真正的新連接的數(shù)據(jù)包發(fā)生混淆了。所以TCP連接還要在TIME_WAIT狀態(tài)等待2倍MSL,這樣可以保證本次連接的所有數(shù)據(jù)都從網(wǎng)絡(luò)中消失。
九、TCP流量控制
如果發(fā)送方把數(shù)據(jù)發(fā)送得過快,接收方可能會來不及接收,這就會造成數(shù)據(jù)的丟失。所謂流量控制就是讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收。
利用滑動窗口機(jī)制可以很方便地在TCP連接上實(shí)現(xiàn)對發(fā)送方的流量控制。
設(shè)A向B發(fā)送數(shù)據(jù)。在連接建立時(shí),B告訴了A:“我的接收窗口是 rwnd = 400 ”(這里的 rwnd 表示 receiver window) 。因此,發(fā)送方的發(fā)送窗口不能超過接收方給出的接收窗口的數(shù)值。請注意,TCP的窗口單位是字節(jié),不是報(bào)文段。假設(shè)每一個報(bào)文段為100字節(jié)長,而數(shù)據(jù)報(bào)文段序號的初始值設(shè)為1。大寫ACK表示首部中的確認(rèn)位ACK,小寫ack表示確認(rèn)字段的值ack。
從圖中可以看出,B進(jìn)行了三次流量控制。第一次把窗口減少到 rwnd = 300 ,第二次又減到了 rwnd = 100 ,最后減到 rwnd = 0 ,即不允許發(fā)送方再發(fā)送數(shù)據(jù)了。這種使發(fā)送方暫停發(fā)送的狀態(tài)將持續(xù)到主機(jī)B重新發(fā)出一個新的窗口值為止。B向A發(fā)送的三個報(bào)文段都設(shè)置了 ACK = 1 ,只有在ACK=1時(shí)確認(rèn)號字段才有意義。
TCP為每一個連接設(shè)有一個持續(xù)計(jì)時(shí)器(persistence timer)。只要TCP連接的一方收到對方的零窗口通知,就啟動持續(xù)計(jì)時(shí)器。若持續(xù)計(jì)時(shí)器設(shè)置的時(shí)間到期,就發(fā)送一個零窗口控測報(bào)文段(攜1字節(jié)的數(shù)據(jù)),那么收到這個報(bào)文段的一方就重新設(shè)置持續(xù)計(jì)時(shí)器。
十、TCP擁塞控制
發(fā)送方維持一個擁塞窗口 cwnd ( congestion window )的狀態(tài)變量。擁塞窗口的大小取決于網(wǎng)絡(luò)的擁塞程度,并且動態(tài)地在變化。發(fā)送方讓自己的發(fā)送窗口等于擁塞窗口。
發(fā)送方控制擁塞窗口的原則是:只要網(wǎng)絡(luò)沒有出現(xiàn)擁塞,擁塞窗口就再增大一些,以便把更多的分組發(fā)送出去。但只要網(wǎng)絡(luò)出現(xiàn)擁塞,擁塞窗口就減小一些,以減少注入到網(wǎng)絡(luò)中的分組數(shù)。
慢開始算法:
當(dāng)主機(jī)開始發(fā)送數(shù)據(jù)時(shí),如果立即所大量數(shù)據(jù)字節(jié)注入到網(wǎng)絡(luò),那么就有可能引起網(wǎng)絡(luò)擁塞,因?yàn)楝F(xiàn)在并不清楚網(wǎng)絡(luò)的負(fù)荷情況。因此,較好的方法是 先探測一下,即由小到大逐漸增大發(fā)送窗口,也就是說,由小到大逐漸增大擁塞窗口數(shù)值。
通常在剛剛開始發(fā)送報(bào)文段時(shí),先把擁塞窗口 cwnd 設(shè)置為一個最大報(bào)文段MSS的數(shù)值。而在每收到一個對新的報(bào)文段的確認(rèn)后,把擁塞窗口增加至多一個MSS的數(shù)值。用這樣的方法逐步增大發(fā)送方的擁塞窗口 cwnd ,可以使分組注入到網(wǎng)絡(luò)的速率更加合理。
每經(jīng)過一個傳輸輪次,擁塞窗口 cwnd 就加倍。一個傳輸輪次所經(jīng)歷的時(shí)間其實(shí)就是往返時(shí)間RTT。不過“傳輸輪次”更加強(qiáng)調(diào):把擁塞窗口cwnd所允許發(fā)送的報(bào)文段都連續(xù)發(fā)送出去,并收到了對已發(fā)送的最后一個字節(jié)的確認(rèn)。
另,慢開始的“慢”并不是指cwnd的增長速率慢,而是指在TCP開始發(fā)送報(bào)文段時(shí)先設(shè)置cwnd=1,使得發(fā)送方在開始時(shí)只發(fā)送一個報(bào)文段(目的是試探一下網(wǎng)絡(luò)的擁塞情況),然后再逐漸增大cwnd。
為了防止擁塞窗口cwnd增長過大引起網(wǎng)絡(luò)擁塞,還需要設(shè)置一個慢開始門限ssthresh狀態(tài)變量。慢開始門限ssthresh的用法如下:
-
當(dāng) cwnd < ssthresh 時(shí),使用上述的慢開始算法。
-
當(dāng) cwnd > ssthresh 時(shí),停止使用慢開始算法而改用擁塞避免算法。
-
當(dāng) cwnd = ssthresh 時(shí),既可使用慢開始算法,也可使用擁塞控制避免算法。擁塞避免
擁塞避免
讓擁塞窗口cwnd緩慢地增大,即每經(jīng)過一個往返時(shí)間RTT就把發(fā)送方的擁塞窗口cwnd加1,而不是加倍。這樣擁塞窗口cwnd按線性規(guī)律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多。
無論在慢開始階段還是在擁塞避免階段,只要發(fā)送方判斷網(wǎng)絡(luò)出現(xiàn)擁塞(其根據(jù)就是沒有收到確認(rèn)),就要把慢開始門限ssthresh設(shè)置為出現(xiàn)擁塞時(shí)的發(fā)送 方窗口值的一半(但不能小于2)。然后把擁塞窗口cwnd重新設(shè)置為1,執(zhí)行慢開始算法。
這樣做的目的就是要迅速減少主機(jī)發(fā)送到網(wǎng)絡(luò)中的分組數(shù),使得發(fā)生 擁塞的路由器有足夠時(shí)間把隊(duì)列中積壓的分組處理完畢。
如下圖,用具體數(shù)值說明了上述擁塞控制的過程。現(xiàn)在發(fā)送窗口的大小和擁塞窗口一樣大。
2.快重傳和快恢復(fù)
快重傳
快重傳算法首先要求接收方每收到一個失序的報(bào)文段后就立即發(fā)出重復(fù)確認(rèn)(為的是使發(fā)送方及早知道有報(bào)文段沒有到達(dá)對方)而不要等到自己發(fā)送數(shù)據(jù)時(shí)才進(jìn)行捎帶確認(rèn)。
接收方收到了M1和M2后都分別發(fā)出了確認(rèn)。現(xiàn)在假定接收方?jīng)]有收到M3但接著收到了M4。
顯然,接收方不能確認(rèn)M4,因?yàn)镸4是收到的失序報(bào)文段。根據(jù) 可靠傳輸原理,接收方可以什么都不做,也可以在適當(dāng)時(shí)機(jī)發(fā)送一次對M2的確認(rèn)。
但按照快重傳算法的規(guī)定,接收方應(yīng)及時(shí)發(fā)送對M2的重復(fù)確認(rèn),這樣做可以讓 發(fā)送方及早知道報(bào)文段M3沒有到達(dá)接收方。發(fā)送方接著發(fā)送了M5和M6。接收方收到這兩個報(bào)文后,也還要再次發(fā)出對M2的重復(fù)確認(rèn)。這樣,發(fā)送方共收到了 接收方的四個對M2的確認(rèn),其中后三個都是重復(fù)確認(rèn)。
快重傳算法還規(guī)定,發(fā)送方只要一連收到三個重復(fù)確認(rèn)就應(yīng)當(dāng)立即重傳對方尚未收到的報(bào)文段M3,而不必 繼續(xù)等待M3設(shè)置的重傳計(jì)時(shí)器到期。
由于發(fā)送方盡早重傳未被確認(rèn)的報(bào)文段,因此采用快重傳后可以使整個網(wǎng)絡(luò)吞吐量提高約20%。
快恢復(fù)
當(dāng)發(fā)送方連續(xù)收到三個重復(fù)確認(rèn),就執(zhí)行“乘法減小”算法,把慢開始門限ssthresh減半。 與慢開始不同之處是現(xiàn)在不執(zhí)行慢開始算法(即擁塞窗口cwnd現(xiàn)在不設(shè)置為1),而是把cwnd值設(shè)置為 慢開始門限ssthresh減半后的數(shù)值,然后開始執(zhí)行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。