TCP/UDP經典問題總結

1、TCP/UDP基本概念:

我們知道網絡層(IP),可以實現兩個主機之間的通信。但是這並不具體,因爲,真正進行通信的實體是在主機中的進程,是一個主機中的一個進程與另外一個主機中的一個進程在交換數據。IP協議雖然能把數據報文送到目的主機,但是並沒有交付給主機的具體應用進程。而端到端的通信才應該是應用進程之間的通信。

UDP,在傳送數據前不需要先建立連接,遠地的主機在收到UDP報文後也不需要給出任何確認。雖然UDP不提供可靠交付,但是正是因爲這樣,省去和很多的開銷,使得它的速度比較快,比如一些對實時性要求較高的服務,就常常使用的是UDP。對應的應用層的協議主要有 DNS,TFTP,DHCP,SNMP,NFS 等。

TCP,提供面向連接的服務,在傳送數據之前必須先建立連接,數據傳送完成後要釋放連接。因此TCP是一種可靠的的運輸服務,但是正因爲這樣,不可避免的增加了許多的開銷,比如確認,流量控制,擁塞控制等。對應的應用層的協議主要有SMTP,TELNET,HTTP,FTP等。

2、什麼是TCP:

TCP是面向連接的、可靠的、基於字節流的傳輸層通信協議,把連接作爲最基本的對象,每一條TCP連接都有兩個端點,這種斷點我們叫作套接字(socket),它的定義爲端口號拼接到IP地址即構成了套接字,例如,若IP地址爲192.3.4.16 而端口號爲80,那麼得到的套接字爲192.3.4.16:80。

3、TCP報文首部:

                                            

(1)源端口和目的端口,各佔2個字節,分別寫入源端口和目的端口;

(2)序列號seq,佔4個字節,TCP連接中傳送的字節流中的每個字節都按順序編號。例如,一段報文的序號字段值是 301 ,而攜帶的數據共有100字段,顯然下一個報文段(如果還有的話)的數據序號應該從401開始;

(3)確認應答號ack,佔4個字節,是期望收到對方下一個報文的第一個數據字節的序號。例如,B收到了A發送過來的報文,其序列號seq字段是501,而數據長度是200字節,這表明B正確的收到了A發送的到序號700爲止的數據。因此,B期望收到A的下一個數據序列號seq是701,於是B在發送給A的確認報文段中把確認號ack置爲701;

(4)數據偏移/首部長度,佔4位,它指出TCP報文的數據距離TCP報文段的起始處有多遠;

(5)保留,佔6位,保留今後使用,但目前應都位0;

(6)緊急URG,當URG=1,表明緊急指針字段有效。告訴系統此報文段中有緊急數據;

(7)確認ACK,僅當ACK=1時,確認號字段纔有效。TCP規定,在連接建立後所有報文的傳輸都必須把ACK置1;

(8)推送PSH,當兩個應用進程進行交互式通信時,有時在一端的應用進程希望在鍵入一個命令後立即就能收到對方的響應,這時候就將PSH=1;

(9)復位RST,當RST=1,表明TCP連接中出現嚴重差錯,必須釋放連接,然後再重新建立連接;

(10)同步SYN,在連接建立時用來同步序號。當SYN=1,ACK=0,表明是連接請求報文,若同意連接,則響應報文中應該使SYN=1,ACK=1;SYN=1的報文不能攜帶數據,佔1個序號。

(11)終止FIN,用來釋放連接。當FIN=1,表明此報文的發送方的數據已經發送完畢,並且要求釋放;

(12)窗口,佔2字節,指的是通知接收方,發送本報文你需要有多大的空間來接受;

(13)檢驗和,佔2字節,校驗首部和數據這兩部分;

(14)緊急指針,佔2字節,指出本報文段中的緊急數據的字節數;

(15)選項,長度可變,定義一些其他的可選的參數。

4、TCP保證可靠性傳輸的措施:

(1)連接管理:TCP是面向連接的,三次握手和四次揮手都保證了本次數據傳送的可靠性。

(2)序列號:保證數據段的按序到達,TCP是面向字節流的,它對每一個字節都進行了編號,接收端也是根據序號來對收到的數據進行排序,如果中間有某個數據報丟了,則之後的數據報還是會接受,但是不會對發送端返回之後的確認,而是會重複發送對丟失處之前數據的確認,保證發送端會對丟失數據段進行重發。
(3)超時重傳機制:當TCP發出一個段後,它啓動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。   

(4)流量控制:根據接收端處理數據的能力來控制發送端發送數據的速度。接收端將自己接收緩衝區的空閒空間的大小填充到TCP的報文頭部中的窗口大小的字段中,通過ACK確認應答發送給發送端。如果接收端的接收緩衝區快滿了,接收端就會將窗口大小設置爲一個更小的值發送給發送端,這時發送端的發送速度就會減緩;如果接收端接收緩衝區徹底滿了,接收端就會將窗口大小設置爲0,這時發送端便停止發送數據段,但是會定時的發送一個窗口探測報文,以此來獲取接收端的接收緩衝區狀態。

(5)擁塞控制:TCP的擁塞控制由4個核心算法組成“慢啓動”(Slow Start)、“擁塞避免”(Congestion voidance)、“快速重傳 ”(Fast Retransmit)、“快速恢復”(Fast Recovery)。

首先需要了解一個概念,爲了在發送端調節所要發送的數據量,定義了一個“擁塞窗口”(Congestion Window),在發送數據時,將擁塞窗口的大小與接收端ack的窗口大小做比較,取較小者作爲發送數據量的上限。擁塞控制主要是四個算法:

1、慢啓動:當建立新的TCP連接時,擁塞窗口(congestion window,cwnd)初始化爲一個數據包大小。源端按cwnd大小發送數據,每收到一個ACK確認,cwnd就增加一個數據包發送量。  

2、擁塞避免:一旦進入到擁塞避免,則說明cwnd目前的值裏擁塞可能並不遙遠了,你就不應該使用慢啓動那種指數增長的方式擴展cwnd,此時用的是較爲保守的方式,每個RTT只是將cwnd的值增加1個MSS。

5、TCP三次握手:

                           

(1)TCP建立連接前,客戶端和服務端都是關閉的狀態,主動發出連接請求的是客戶端,服務端被動的接收請求。

(2)TCP服務器進程先創建傳輸控制塊TCB,時刻準備接受客戶進程的連接請求,此時服務器就進入了LISTEN(監聽)狀態;

(3)第一次握手(連接請求報文,SYN:TCP客戶進程也是先創建傳輸控制塊TCB,然後向服務器發出連接請求報文,這是報文首部中的同部位SYN=1,同時選擇一個初始序列號seq=x,此時,TCP客戶端進程進入了SYN-SENT(同步已發送狀態)狀態。TCP規定,SYN報文段(SYN=1的報文段)不能攜帶數據,但需要消耗掉一個序號

(4)第二次握手(同意建立連接確認報文,SYN+ACK):TCP服務器收到請求報文後,如果同意連接,則發出確認報文。確認報文中應該ACK=1,SYN=1,確認號是ack=x+1,同時也要爲自己初始化一個序列號seq=y,此時,TCP服務器進程進入了SYN-RCVD(同步收到)狀態。這個報文也不能攜帶數據,但是同樣要消耗一個序號

(5)第三次握手(確認報文,ACK):TCP客戶進程收到服務端回覆的確認後,還要向服務器給出確認。確認報文的ACK=1,ack=y+1,自己的序列號seq=x+1,此時,TCP連接建立,客戶端進入ESTABLISHED(已建立連接)狀態。TCP規定,ACK報文段可以攜帶數據,但是如果不攜帶數據則不消耗序號。當服務器收到客戶端的確認後也進入ESTABLISHED狀態,此後雙方可以開始通信了。

注:前兩次握手不可以攜帶數據,第三次握手可以攜帶數據。

6、TCP爲什麼是三次握手:

(1)避免歷史連接,造成資源浪費

       如果只建立兩次握手連接的機制,假定某一個連接請求因爲網絡擁塞的原因無法即使發送至服務端,導致客戶端無法及時收到確認報文,因此會重新向服務端發送服務器超時重傳,若此時客戶端與服務端完成握手連接,傳輸數據並關閉連接,而此前失效的連接請求又到達了服務端,兩次握手機制會將客戶端與服務端再次建立連接,造成了不必要的資源浪費。但採用三次握手協議,即使失效報文傳送過來,服務端接收到報文後回覆了確認請求,客戶端也不會再次發出確認,無法建立連接。

(2)同步雙方初始的序列號

       在TCP通信中,通信雙方都需要維護一個序列號(字節流中每個字節的序號),序列號是保證可靠傳輸的關鍵,它可以是接收方去除重複接收的數據、接收方根據序列號按需接收數據、表示發出的數據包中已經發出的部分。

       當客戶端發送攜帶序列號seq的SYN報文,需要服務端回覆一個帶有應答序列號ack的ACK報文。同樣,服務端發送一個帶有序列號seq的SYN報文,客戶端也會回覆一個帶有應答序列號ack的ACK報文。從而保證了通信雙發序列號的同步性。

(3)4次握手可以簡化爲3

       4次握手連接同樣可以實現一個可靠的連接服務,但是第2步和第3步是可以直接合併成1步的,因此簡化爲3步即可。

7、爲什麼客戶端與服務端的初始序列號seq不同:

因爲網絡中的報文會延遲、會複製重發、也有可能丟失,這樣會造成的不同連接之間產生互相影響,所以爲了避免互相影響,客戶端和服務端的初始序列號是隨機且不同的。

基於時鐘生成隨機數

8、保活機制:如果已經建立了連接,但是客戶端突然出現故障了怎麼辦:

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75分鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

9、什麼是SYN攻擊:

我們都知道TCP連接建立是需要三次握手,假設攻擊者短時間僞造不同IP地址的SYN 報文,服務端每接收到一個SVN報文,就進入SYN_RCVD狀態,但服務端發送出去的ACK + SYN報文,無法得到未知IP主機的ACK應答,久而久之就會佔滿服務端的SYN接收隊列(未連接隊列),使得服務器不能爲正常用戶服務。

10、TCP四次揮手釋放:

                                   

(1)數據傳輸完畢後,雙方都可釋放連接。最開始的時候,客戶端和服務器都是處於ESTABLISHED狀態,然後客戶端主動關閉,服務器被動關閉

(2)第一次揮手客戶端進程發出連接釋放FIN報文,並且停止發送數據。釋放數據報文首部FIN=1,其序列號seq=u(等於前面已傳送過來的數據最後一個字節序號+1),客戶端進入FIN-WAIT-1(終止等待1)狀態。TCP規定,FIN報文段即使不攜帶數據也要消耗一個序號。

(3)第二次揮手:服務器收到連接釋放報文回覆確認ACK報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時服務端進入CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。

(4)客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)。

(5)第三次揮手:服務器處理完數據後,就向客戶端發送連接釋放FIN報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號爲seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。

(6)第四次揮手:客戶端收到服務器的連接釋放報文後,必鬚髮出確認ACK報文,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,客戶端必須經過2MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。

(7)服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。

11、爲什麼斷開連接是四次揮手呢:

而關閉連接時,服務器收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,而自己也未必全部數據都發送給對方了,所以己方可以立即關閉,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。

12、爲什麼客戶端最後要多等待2MSL:

MSL爲報文最大生存時間,TCP允許不同的實現可以設置不同的MSL值。

(1)保證連接正確關閉:

第一,保證客戶端發送的最後一個ACK報文能夠到達服務器,因爲這個ACK報文可能丟失,站在服務器的角度看來,2MSL 的時間是從客戶端接收到 FIN 後發送 ACK 開始計時的。如果在 TIME-WAIT 時間內,因爲客戶端的 ACK 沒有傳輸到服務端,客戶端又接收到了服務端重發的 FIN 報文,那麼 2MSL 時間將重新計時。

(2)防止舊連接的數據包

防止類似與“三次握手”中提到了的“已經失效的連接請求報文段”出現在本連接中。如果不設置2MSL時間,假定連接中有一個數據包被延遲了,而後當前連接斷開後這個端口的TCP又被複用了,將導致這個被延遲的數據包被新的連接正確接收,導致數據混亂。如果設置了2MSL機制,客戶端發送完最後一個確認報文後,在2MSL時間中可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣新的連接中不會出現舊連接的請求報文。

13、socket編程流程:

                                           

(1)TCP:

服務端:    

創建socket:socket();

       綁定IP地址及port信息到socket:bind();

       設計允許最大連接數:listen();

       接收客戶端的連接:accept();

       首發數據:send();recv();或read();write();

客戶端:

創建socket:socket();

       綁定IP地址及port信息到socket:bind();

       連接服務器:connect();

       首發數據:send();recv();或read();write();

14、UDP基本概念:

UDP不提供複雜的傳輸控制機制,利用IP提供面向無連接的通信服務,UDP的頭部非常簡單:

                                               

(1)源端口、目的端口:告訴udp協議,報文應該發送到哪。

(2)包長度:保留了UDP首部和數據的長度和。

(3)校驗和:爲了提供可靠的UDP首部和數據設計的。

15、UDP與TCP的區別:

(1)連接性:TCP是面向連接的傳輸層協議,進行通信前需要建立連接;UDP不需要先建立連接,直接進行數據傳輸。

(2)服務對象:TCP是一對一的兩點傳輸服務,UDP支持一對一、一對多、多對多的交互通信。

(3)可靠性:TCP提供可靠的交付通信,數據可以無差錯、不丟失、不重複的按需到達;UDP盡最大努力交付,不保證可靠交付。

(4)擁塞控制、流量控制:TCP提供擁塞控制與流量控制,保證數據傳輸的安全性。UDP沒有,即使網絡十分堵塞,也不影響發送速率。

(5)首部開銷:TCP的首部開銷較大,沒有使用選型字段時是20個字節;UDP首部開銷小,是8個字節。

(6)TCP是基於字節流模式,UDP是面向數據報模式

16、UDP的單播、廣播、組播:

(1)單播Unicast:是客戶端與服務器之間的點到點連接。

(2)廣播BroadCast:主機之間“一對所有”的通訊模式,廣播者可以向網絡中所有主機發送信息。廣播禁止在Internet寬帶網上傳輸(廣播風暴)。

(3)組播MultiCast:主機之間“一對一組”的通訊模式,也就是加入了同一個組的主機可以接受到此組內的所有數據。

組播報文的目的地址使用D類IP地址,D類地址不能出現在IP報文的源IP地址字段。單播數據傳輸過程中,一個數據包傳輸的路徑是從源地址路由到目的地址,利用“逐跳”的原理[路由選擇]在IP網絡中傳輸。

然而在ip組播環中,數據包的目的地址不是一個,而是一組,形成組地址。所有的信息接收者都加入到一個組內,並且一旦加入之後,流向組地址的數據立即開始向接收者傳輸,組中的所有成員都能接收到數據包。組播組中的成員是動態的,主機可以在任何時刻加入和離開組播組。

用同一個IP多播地址接收多播數據包的所有主機構成了一個主機組,也稱爲多播組。一個多播組的成員是隨時變動的,一臺主機可以隨時加入或離開多播組,多播組成員的數目和所在的地理位置也不受限制,一臺主機也可以屬於幾個多播組。此外,不屬於某一個多播組的主機也可以向該多播組發送數據包。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章