天天看點

Linux — 網絡基礎二應用層傳輸層

應用層

負責應用程式之間的資料溝通

網絡通信協定: 網絡資料傳輸中的資料格式規定

自定義協定

序列化: 将資料對象按照持久化存儲或者網絡資料傳輸的格式來排布。

反序列化: 對持久化存儲或者傳輸的資料以指定的協定進行解析的過程。

知名協定

HTTP ——超文本傳輸協定

URL —— 統一資源定位符(網址)

Linux — 網絡基礎二應用層傳輸層

URL編碼

因為URL中特殊字元都具有特殊含義,是以查詢字元串中有特殊字元時,會造成二義性,是以需要對使用者送出的資料進行編碼。

編碼規則:

将需要轉碼的字元轉為16進制,然後從右到左,取4位(不足4位直接處理),每2位做一位,前面加上%(進行辨別),編碼成%XY格式。

URL解碼

在查詢字元串中每遇到%,則表示之後的兩個字元需要進行URL解碼。

HTTP協定格式

HTTP請求
Linux — 網絡基礎二應用層傳輸層

首行: [方法] + [URL] + [版本]

Header: 請求的屬性,冒号分割的鍵值對;每組屬性之間使用\n分隔;遇到空行表示Header部分結束。

Body: 空行後面的内容都是Body, Body允許為空字元串。如果Body存在,則在Header中會有一個 Content-Length屬性來辨別Body的長度。

Linux — 網絡基礎二應用層傳輸層

GET所送出的資料在URL中(有長度的限制),POST所送出的資料在正文中。

HTTP響應
Linux — 網絡基礎二應用層傳輸層

首行: [版本号] + [狀态碼] + [狀态碼解釋]

Header: 請求的屬性,,冒号分割的鍵值對,每組屬性之間使用\n分隔,遇到空行表示Header部分結束。

一些重要頭部: Content-Length、Content-Type、Cookie、Set_Cookie、Transfer-Encoding、Location

Body: 空行後面的内容都是Body,Body允許為空字元串。如果Body存在,則在Header中會有一個 Content-Length屬性來辨別Body的長度。如果伺服器傳回了一個html頁面,那麼html頁面内容就是在body中。

Linux — 網絡基礎二應用層傳輸層

傳輸層

負責資料能夠從發送端傳輸接收端(程序與程序之間)

端口号

端口号(Port)辨別了一個主機上進行通信的不同的應用程式(程序),在TCP/IP協定中, 用 “源IP”, “源端口号”, “目的IP”,“目的端口号”,“協定号” 這樣一個五元組來辨別一個通信(可以通過 netstat -n檢視)。作業系統拿到網卡接受的資料之後,通過資料中的端口号知道資料被存放到哪一個socket的緩沖區中

檢視知名端口号 cat /etc/services

傳輸層的傳輸協定

UDP

UDP協定包含字段

源端口/目的端口: 傳輸,确定資料應該那個端口處理

校驗和: 二進制的反碼求和

資料包長度: uint_16類型

  • 意味着UDP資料報最大的長度是64k,若sendto給予的資料大于64k-8(前面的資訊長度為8)則會報錯,因為UDP在傳輸層不會進行資料分段。
  • 若傳輸的資料大于64k,則使用者需要在應用層将資料分割成一個一個小段進行傳輸。
  • UDP傳輸并不保證資料包的有序到達,是以也需要使用者在應用層進行包序管理,是以UDP要求資料整條接受,否則造成資料出錯。
  • UDP提供整條資料向應用層傳遞(也不會出現半個資料,因為頭部中有封包長度辨別),也正因為資料報長度在協定頭中有辨別,是以UDP不會産生粘報問題。

UDP協定端格式

Linux — 網絡基礎二應用層傳輸層
UDP的特點

無連接配接: 知道對端的IP和端口号就直接進行傳輸, 不需要建立連接配接。

不可靠: 沒有确認機制, 沒有重傳機制;如果因為網絡故障該段無法發到對方, UDP協定層也不會給應用層傳回任何錯誤資訊。

面向資料報: 資料整條收發,靈活性低,但是不會造成粘包問題;不能夠靈活的控制讀寫資料的次數和數量。

UDP傳輸速度快,實作了傳輸層廣播資料包。

UDP的緩沖區
  1. UDP沒有真正意義上的發送緩沖區(不會使用緩沖區,接受到資料後都會直接封裝,然後直接交給網絡層)。調用sendtod會直接交給核心,由核心将資料傳給網絡層協定進行後續的傳輸動作。
  2. UDP具有接收緩沖區.,但是這個接收緩沖區不能保證收到的UDP報的順序和發送UDP報的順序一緻;如果緩沖區滿了,再到達的UDP資料就會被丢棄。

TCP協定

TCP的特點

可靠傳輸

提高性能: 滑動視窗機制、延遲應答機制、捎帶應答機制

因為tcp為了實作可靠性傳輸犧牲了部分傳輸性能,并且有可能因為ACK确認應答丢失也要重傳資料,是以提出了以下幾種機制來避免大量丢包重傳以及ACK丢失重傳來保證性能不再降低。

滑動視窗機制

流量控制+快速重傳機制+擁塞控制

流量控制

  1. tcp通過雙方協商視窗大小進行流量控制,避免因為緩沖區資料塞滿而大量丢包重傳。
  2. 通過協定字段中的視窗大小,雙方進行協商,一次可以能最多傳輸多少條資料,之後等待确認應答,不需要進行一一停留。
  3. 雙方都維護一個視窗大小,發送方先框住一部分資料,接受到确認應答後,框開始向後移動發送資料,對方同樣在視窗中使用框滑動的方式接受。

快速重傳機制

  1. 每條資料的确認回複都必須按序回複,若前面的資料沒有收到,則不會對後邊的資料進行回複。意味着若收到一條回複,表示ACK确認序号之前的資料全部安全到達,不會因為前邊的資料的ACK丢失而重傳資料。
  2. 若前邊的資料丢失,則接受方收到後發的資料立即發送重傳請求,并且連發三次,若發送方連續收到三次重傳請求,則認為資料丢失,進行重傳。
  3. tcp對相同的資料包會丢棄,這樣就算前面的資料因為延遲到達或者丢包,都不會對重傳請求造成影響,因為無論是延遲到達還是重新發送的資料報到達,都可以減少等待确認前面資料丢包的時間。
  4. 如果資料次序發生錯誤,目前面的資料未收到,收到後面的資料,先将收到的後面的資料放入緩沖區,等待前面的資料到達後,再将緩沖區的資料取出。

擁塞控制

慢啟動,快增長

  1. 雙方雖然視窗可能很大,但是發送的資料并不大(因為剛開始時不知道網絡狀态),發送資料成功後,之後發送的資料按指數的增長形式,直到達到門檻值,則不再增長。
  2. 發送端控制一個擁塞視窗,再進行資料傳輸時進行網絡探測式的發送,若網絡狀态良好時發送的資料快速增長,達到門檻值,則不再繼續增長。若傳輸過程中出現丢包,則重新初始化擁塞視窗。
  3. 擁塞控制為了避免網絡狀态因為網絡狀态不好導緻通信初始,大量資料包丢失導緻重傳的情況,降低性能。

延遲應答機制

接收方收到資料後并不立即确認回複,而是等待一段時間,因為這段延遲的時間内,有可能使用者已經recv将緩沖區中的資料取走,視窗就可以盡可能的保證最大大小,保證傳輸吞吐量。

捎帶應答機制

接收方對每一條資料的确認回複,都需要發送一個tcp資料報,但空標頭的傳輸會降低性能,是以會在即将要發送的資料標頭中包含确認資訊(可以少發一個确認的空標頭)。

面向位元組流

傳輸靈活

  1. 發送方每次調用send都會将資料放到發送緩沖區中,然後核心選擇合适的時機發送資料。
  2. 接收方網卡接受到資料,都會将資料放到接受緩沖區中,使用者recv就是從接受緩沖區取資料。

粘報問題主要發生的位置

  1. 發送緩沖區中的資料堆積
  2. 接受緩沖區中的資料堆積

粘包本質原因: 資料之間沒有明顯的邊界,tcp隻管傳輸資料的位元組流導緻發送端/接受端因為資料的堆積在實際發送或recv時一次擷取到半條或多條資料。

解決辦法: tcp在傳輸層沒有資料邊界,但是使用者可以在應用層進行邊界處理

常見方法: 特殊字元間隔(HTTP),定長資料(UDP頭中包含長度)

TCP協定段格式

Linux — 網絡基礎二應用層傳輸層

TCP異常

發送端機器掉電/網線斷開,接收端認為連接配接還在,一旦接收端有寫入操作,接收端發現連接配接已經不在了, 就會進行reset。即使沒有寫入操作,TCP自己也内置了一個保活定時器,會定期詢問對方是否還在。如果對方不在,也會把連接配接釋放。

另外,應用層的某些協定,也有一些這樣的檢測機制。例如HTTP長連接配接中,也會定期檢測對方的狀态。斷線之後,也會定期嘗試重新連接配接。

tcp協定棧有自身的保活機制: 長時間無資料通信,則發送保活探測包,進行連結探測,若多個探測包都沒有響應,則認為斷開連結。

連結斷開的展現: recv傳回0,send出發SIGPIPE異常。

注: 具體的TCP/UDP使用可參見部落格《Linux — 網絡套接字程式設計》

https://blog.csdn.net/lw13572259173/article/details/93165915

繼續閱讀