天天看點

傳輸層TCPUDP 詳解

1、傳輸層存在的必要性

       由于網絡層的分組傳輸是不可靠的,無法了解資料到達終點的時間,無法了解資料未達終點的狀态。是以有必要增強網絡層提供服務的服務品質。

2、引入傳輸層的原因

       面向連接配接的傳輸服務與面向連接配接的網絡服務類似,都分為建立連接配接、資料傳輸、釋放連接配接三個階段;編址、尋址、流控制也是類似的。無連接配接的傳輸服務與無連接配接的網絡服務也非常類似。一個很顯然的問題:既然傳輸層的服務與網絡層的服務如此相似,那麼為什麼我們還要兩個獨立的層呢?

      原因在于:傳輸層的代碼完全運作在使用者的機器上,但是網絡層主要運作在由承運商控制的路由器上。試想以下幾種情況?

①       網絡層提供的服務不夠用;

②       頻繁的丢失分組;

③       路由器時常崩潰。

       使用者在網絡層上并沒有真正的控制權,是以他們不可能用最好的路由器或者在資料鍊路層上用更好的錯誤處理機制來解決服務太差的問題。唯一的可能是在網絡層之上的另一層中提高服務品質。這就是傳輸層存在的必要性。

      傳輸層的重要性:不僅僅是另外一層,它是整個協定層次的核心所在。如果沒有傳輸層,那麼分層協定的整個概念将變得沒有意義。

      傳輸層的任務:在源機器和目标機器之間提供可靠的、成本效益合理的資料傳輸服務,并且與目前使用的實體網絡完全獨立。

傳輸層TCPUDP 詳解

3、傳輸層的功能

        資料傳送,不關心資料含義,程序間通信。

        彌補高層(上3層)要求與網絡層(基于下3層)資料傳送服務品質間的差異(差錯率、差錯恢複能力、吞吐率、延時、費用等),對高層屏蔽網絡層的服務的差異,提供穩定和一緻的界面。

4、傳輸層協定與網絡層協定的主要差別

       網絡層(IP層)提供點到點的連接配接即提供主機之間的邏輯通信,傳輸層提供端到端的連接配接——提供程序之間的邏輯通信。

5、傳輸層的用途

      傳輸層将資料分段,并進行必要的控制,以便将這些片段重組成各種通信流。在此過程中,傳輸層主要負責:

①       跟蹤源主機和目的主機上應用程式間的每次通信;

②       将資料分段,并管理每個片段;

③       将分段資料重組為應用程式資料流;

④       辨別不同的應用程式。

6、端口号的概念

        運作在計算機中的程序是用程序辨別符來标志的。運作在應用層的各種應用程序卻不應當讓計算機作業系統指派它的程序辨別符。這是因為在網際網路上使用的計算機的作業系統種類很多,而不同的作業系統又使用不同格式的程序辨別符。為了使運作不同作業系統的計算機的應用程序能夠互相通信,就必須用統一的方法對TCP/IP體系的應用程序進行标志。

解決這個問題的方法就是在運輸層使用協定端口号(protocol port number),或通常簡稱為端口(port)。

雖然通信的終點是應用程序,但我們可以把端口想象是通信的終點,因為我們隻要把要傳送的封包交到目的主機的某一個合适的目的端口,剩下的工作(即最後傳遞目的程序)就由 TCP來完成。

傳輸層TCPUDP 詳解

7、傳輸層的主要協定

          TCP/ IP傳輸層的兩個主要協定都是網際網路的重要标準,傳輸控制協定TCP(Transmission Control Protocol)[RFC 768]、使用者資料報協定UDP(User Datagram Protocol)[RFC 793]。

          傳輸層的資料流要在網絡端點之間建立邏輯連接配接。如果使用UDP,傳輸層的首要任務是将資料從源裝置傳輸到目的裝置。如果使用TCP,傳輸層主要通過滑動視窗來提供端到端控制,以及利用确認序列号和确認資訊提供可靠性。傳輸層定義主機應用程式之間端到端的連接配接。

傳輸層TCPUDP 詳解

8、TCP&UDP的比較

       TCP(Transmission Control Protocol)可靠的、面向連接配接的協定(eg:打電話)、傳輸效率低全雙工通信(發送緩存&接收緩存)、面向位元組流。使用TCP的應用:Web浏覽器;電子郵件、檔案傳輸程式。

       UDP(User Datagram Protocol)不可靠的、無連接配接的服務,傳輸效率高(發送前時延小),一對一、一對多、多對一、多對多、面向封包,盡最大努力服務,無擁塞控制。使用UDP的應用:域名系統 (DNS);視訊流;IP語音(VoIP)。

傳輸層TCPUDP 詳解

 問題1:什麼是面向連接配接、面向無連接配接?

        面向連接配接舉例:兩個人之間通過電話進行通信。

面向無連接配接舉例:郵政服務,使用者把信函放在郵件中期待郵政處理流程來傳遞郵政包裹。顯然,不可達代表不可靠。

         從程式實作的角度解析面向連接配接、面向無連接配接如下:

         TCP面向連接配接,UDP面向無連接配接(在預設的阻塞模式下):

         在TCP協定中,當用戶端退出程式或斷開連接配接時,TCP協定的recv函數會立即傳回不再阻塞,因為服務端自己知道用戶端已經退出或斷開連接配接,證明它是面向連接配接的;

        而在UDP協定中,recvfrom這個接收函數将會始終保持阻塞,因為服務端自己不知道用戶端已經退出或斷開連接配接,證明它是面向無連接配接的)。

傳輸層TCPUDP 詳解

       從上圖也能清晰的看出,TCP通信需要伺服器端偵聽listen、接收用戶端連接配接請求accept,等待用戶端connect建立連接配接後才能進行資料包的收發(recv/send)工作。

         而UDP則伺服器和用戶端的概念不明顯,伺服器端即接收端需要綁定端口,等待用戶端的資料的到來。後續便可以進行資料的收發(recvfrom/sendto)工作。

問題2:什麼是面向位元組流、面向封包?

       面向位元組流:雖然應用程式和TCP的互動是一次一個資料塊(大小不等),但TCP把應用程式看成是一連串的無結構的位元組流。TCP有一個緩沖,當應用程式傳送的資料塊太長,TCP就可以把它劃分短一些再傳送。如果應用程式一次隻發送一個位元組,TCP也可以等待積累有足夠多的位元組後再構成封包段發送出去。

       面向封包:面向封包的傳輸方式是應用層交給UDP多長的封包,UDP就照樣發送,即一次發送一個封包。是以,應用程式必須選擇合适大小的封包。若封包太長,則IP層需要分片,降低效率。若太短,會是IP太小。(謝希仁,第五版。UDP對應用層交下來的封包,既不合并,也不拆分,而是保留這些封包的邊界。這也就是說,應用層交給UDP多長的封包,UDP就照樣發送),即一次發送一個封包)。

問題3:在預設的阻塞模式下,為什麼說TCP無邊界,UDP有邊界?

         對于TCP協定,用戶端連續發送資料,隻要服務端的這個函數的緩沖區足夠大,會一次性接收過來,即用戶端是分好幾次發過來,是有邊界的,而服務端卻一次性接收過來,是以證明是無邊界的;

        而對于UDP協定,用戶端連續發送資料,即使服務端的這個函數的緩沖區足夠大,也隻會一次一次的接收,發送多少次接收多少次,即用戶端分幾次發送過來,服務端就必須按幾次接收,進而證明,這種UDP的通訊模式是有邊界的。

問題4:UDP 如何發送大量的資料?如何處理分包?

        用 updclient 一次不能發送太大的資料量,不然就會報錯:一個在資料報套接字上發送的消息大于内部消息緩沖器或其他一些網絡限制,或該使用者用于接收資料報的緩沖器比資料報小。但不知道一次到底能發多少位元組?如果把一個大的位元組數組拆分成若幹個位元組數組發送,那麼接收時如何判斷和處理呢?

       答:方法很簡單:

1、在用戶端将你要發送的内容(檔案什麼的都可以)分塊,每塊内容進行編号,然後發送;

2、服務端在接收到你的分塊資料以後,根據你的用戶端資料内容的編号重新組裝;

3、一般我們在發送資料的時候,盡量采用比較小的資料塊的方式(我的都沒有超過1024的),資料塊太大的話容易出現發送和接收的資料時間長,比對出問題。

問題5.UDP發包的問題

       問:udp發送兩次資料,第一次 100位元組,第二次200位元組,接包方一次recvfrom( 1000 ),收到是 100,還是200,還是300?

       答:UDP是資料封包協定,是以資料包方式,是以每次可以接收100,200,在理想情況下,第一次是無論recvfrom多少都是接收到100。當然,可能由于網絡原因,第二個包先到的話,有可能是200了。對可能會由于網絡原因亂序,是以可能先收到200,是以自定義的udp協定標頭裡都要加上一個序列号,辨別發送與收包對應。

問題6.TCP的發包問題

       問:同樣如果換成tcp,第一次發送 100位元組,第二次發送200位元組,recv( 1000 )會接收到多少?

       答:tcp是流協定,是以recv( 1000 ),會收到300 tcp自己處理好了重傳,保證資料包的完整性

問題7.有分片的情況下如下處理

        問:如果MTU是1500,使用UDP發送 2000,那麼recvfrom(2000)是收到1500,還是2000?

        答:還是接收2000,資料分片由ip層處理了,放到udp還是一個完整的包。接收到的包是由路由路徑上最少的MTU來分片,注意轉到UDP已經在是組裝好的(組裝出錯的包會經crc校驗出錯而丢棄),是一個完整的資料包。

問題8.分片後的處理

       問:如果500那個片丢了怎麼辦?udp又沒有重傳

       答:udp裡有個crc檢驗,如果包不完整就會丢棄,也不會通知是否接收成功,是以UDP是不可靠的傳輸協定,而且TCP不存在這個問題,有自己的重傳機制。在内網來說,UDP基本不會有丢包,可靠性還是有保障。當然如果是要求有時序性和高可靠性,還是走TCP,不然就要自己提供重傳和亂序處理( UDP内網發包處理量可以達 7M~10M/s )

問題9.不同連接配接到同一個端口的包處理

       問:TCP

          A -> C發100

          B -> C發200

         AB同時同一端口

         C recv(1000) ,會收到多少?

      答:A與C是一個tcp連接配接,B與C又是另一個tcp連接配接,是以不同socket,是以分開處理。每個socket有自己的接收緩沖和發送緩沖

問題10.什麼是TCP粘包

        在應用開發過程中,基于TCP網絡傳輸的應用程式有時會出現粘包現象(即發送方發送的若幹包資料到接收方接收時粘成一包)。詳細解釋如下:由于TCP是流協定,對于一個socket的包,如發送 10AAAAABBBBB兩次,由于網絡原因第一次又分成兩次發送, 10AAAAAB和BBBB,如果接包的時候先讀取10(包長度)再讀入後續資料,當接收得快,發送的慢時,就會出現先接收了 10AAAAAB,會解釋錯誤 ,再接到BBBB10AAAAABBBBB,也解釋錯誤的情況。這就是TCP的粘包。

       在網絡傳輸應用中,通常需要在網絡協定之上再自定義一個協定封裝一下,簡單做法就是在要發送的資料前面再加一個自定義的標頭,標頭中可以包含資料長度和其它一些資訊,接收的時候先收標頭,再根據標頭中描述的資料長度來接收後面的資料。詳細做法是:先接收標頭,在標頭裡指定包體長度來接收。設定標頭包尾的檢查位(如群空間0x2開頭,0x3結束來檢查一個包是否完整)。對于TCP來說:1)不存在丢包,錯包,是以不會出現資料出錯 2)如果標頭檢測錯誤,即為非法或者請求,直接重置即可

       為了避免粘包現象,可采取以下幾種措施。

        一是對于發送方引起的粘包現象,使用者可通過程式設計設定來避免,TCP提供了強制資料立即傳送的操作指令push,TCP軟體收到該操作指令後,就立即将本段資料發送出去,而不必等待發送緩沖區滿;

        二是對于接收方引起的粘包,則可通過優化程式設計、精簡接收程序工作量、提高接收程序優先級等措施,使其及時接收資料,進而盡量避免出現粘包現象;

         三是由接收方控制,将一包資料按結構字段,人為控制分多次接收,然後合并,通過這種手段來避免粘包。

問題11.圖解TCP的3次握手建立連接配接,4次握手釋放連接配接?

         TCP是面向連接配接的協定。運輸連接配接是用來傳送TCP封包的。TCP傳輸連接配接的建立和釋放是每一次面向連接配接的通信中必不可少的過程。是以,傳輸連接配接就由三個階段,即:連接配接建立、資料傳送和連接配接釋放。

傳輸層TCPUDP 詳解

      這裡的SYN=SYNchronization,SYN=1,ACK=0,表示連接配接請求封包段;同意建立連接配接則SYN=1,ACK=1,連接配接後所有的ACK=1。

三次握手(three-way handshake)方案解決了由于網絡層會丢失、存儲和重複分組帶來的問題。試想不進行三次握手可能出現的問題?

傳輸層TCPUDP 詳解

        如上圖所示,如果僅僅是2次握手的話,可能出現的問題如下:

       Host A發送的資料包由于網絡的原因,出現了滞留,即延時到達了HostB。此時,B以為HostA發來了請求,于是就向HostA發送确認封包,以建立連接配接。而HostA收到封包後,由于其沒有向HostB發起建立連接配接的請求,是以不會理睬HostB的确認,也不會向HostB發送資料。而此時的B認為已經建立起連接配接了,就等待HostA發送的資料,導緻HostB的資源白白浪費!

連接配接釋放:

傳輸層TCPUDP 詳解

                                                      ——部分内容參考了《計算機網絡》、網上查找内容。