計算機網絡 - 運輸層(上)

計算機網絡 - 運輸層(上)

概述

運輸層在某種程度上起到了用戶功能與通訊部份之間橋樑的做用。
運輸層向它上面的應用層提供通訊服務,它屬於面向通訊部分的最高層,同時也是用戶功能中的最低層。算法

在一開始學習TCP/IP五層協議時咱們已經瞭解到,只有位於網絡邊緣部分的主機的協議棧纔有運輸層,而網絡核心部分中的路由器在轉發分組時都只用到下三層的功能。
信息流瀏覽器

「進程間的通訊」

從IP層來講,通訊的兩端是兩臺主機。但「兩臺主機之間的通訊」這種說法還不夠清楚。緩存

從運輸層的角度看,通訊的真正端點並非主機而是主機中的進程。也就是說,端到端的通訊是應用進程之間的通訊。服務器

在一臺主機中常常有多個應用進程同時分別和另外一臺主機中的多個應用進程通訊
這代表運輸層有一個很重要的功能——複用 (multiplexing)和分用 (demultiplexing)。
根據應用程序的不一樣需求,運輸層須要有兩種不一樣的運輸協議,即面向鏈接的 TCP無鏈接的 UDP網絡

在詳細介紹兩種運輸協議以前,咱們先對兩者各自的特色有一個直觀認識:socket

TCP UDP
傳輸對象 面向字節流 面向報文
只能提供點對點的通訊 可實現一對1、一對多、多對多
是否鏈接 面向鏈接 面向非鏈接
可靠性 可靠 不可靠
優勢 可靠、穩定
創建鏈接時須要三次握手 沒有TCP的那一系列機制
傳輸時有重傳、擁塞控制等機制 一種無狀態的傳輸協議
傳輸結束後斷開鏈接節約資源
缺點 慢、效率低 不可靠、不穩定
容易被攻擊 網絡狀態很差時,容易丟包
適用場合 對網絡通信質量有要求時 對網絡通信質量要求不高
如傳輸HTTP/FTP/SMTP等協議 要求通信速度儘可能的快
傳輸大量數據時 實時應用程序
傳輸少許數據時
常見應用 瀏覽器(HTTP) QQ語音、QQ視頻
Outlook(POP/SMTP)
首部開銷 20字節 8字節

能夠看出,兩者主要的差異就在於UDP的「面向報文無鏈接」與TCP的「面向流有鏈接」。
TCP與UDP的區別tcp

看到這裏,你可能對於TCP所謂的「可靠性」有所疑問:明明不管是網絡層的IP協議仍是數據鏈路層的協議提供的都是「不可靠」(盡最大可能交付)的,爲何到了運輸層就能夠實現「可靠傳輸」了呢?
這實際上是由於TCP協議在運輸層創建起的「邏輯通訊信道」中採用了一系列方法來保證運輸的可靠性,具體哪些方法呢?立刻就會揭曉了。

端口(port)

爲了使運行不一樣操做系統的計算機的應用進程可以互相通訊,就必須用統一的方法對 TCP/IP 體系的應用進程進行標誌。解決這個問題的方法就是在運輸層使用協議端口號 (protocol port number),或一般簡稱爲端口 (port)。學習

端口用一個16位端口號進行標誌。
端口號只具備本地意義,即端口號只是爲了標誌本計算機應用層中的各進程。spa

端口分爲兩大類

一、服務器端使用的端口號操作系統

  • 熟知端口(well-known ports),數值通常爲 0~1023。
  • 登記端口號,數值爲 1024~49151,爲沒有熟知端口號的應用程序使用的。

熟知端口號

二、客戶端使用的端口號

  • 又稱爲短暫端口號,數值爲 49152~65535,留給客戶進程選擇暫時使用。

用戶數據報協議UDP

UDP 只在 IP 的數據報服務之上增長了不多一點的功能:

  • 複用和分用的功能
  • 差錯檢測的功能

面向報文的UDP

UDP一箇中最大的特色就是「面向報文」(無鏈接)。

  • 發送方UDP 對應用程序交下來的報文,在添加首部後就向下交付 IP 層。UDP 對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界。
    若報文太長,UDP 把它交給 IP 層後,IP 層在傳送時可能要進行分片。
  • 接收方UDP 對 IP 層交上來的 UDP 用戶數據報,在去除首部後就原封不動地交付上層的應用進程,一次交付一個完整的報文。

UDP的首部格式

UDP報文結構

僞首部
在計算檢驗和時,臨時把「僞首部」和 UDP 用戶數據報鏈接在一塊兒。僞首部僅僅是爲了計算檢驗和。

傳輸控制協議TCP

咱們先回顧熟悉一下TCP的特色:

  • TCP 是面向鏈接的運輸層協議
  • 每一條 TCP 鏈接只能有兩個端點 (endpoint),每一條 TCP 鏈接只能是點對點的(一對一)
  • TCP 提供可靠交付的服務。
  • TCP 提供全雙工通訊。
  • 面向字節流

由此咱們對於TCP有了一個大概的概念:面向流,有鏈接,很可靠
下面就從這些特色開始細說。

TCP面向流的概念

與UDP不一樣,TCP 不關心應用進程一次把多長的報文發送到 TCP 緩存。這和UDP的「給多少裝多少」正相反
TCP 對連續的字節流進行分段,造成 TCP 報文段。
TCP的分段

TCP的鏈接

首先注意,TCP鏈接是一條虛鏈接而不是一條真正的物理鏈接。
在這個鏈接的基礎上,TCP能夠根據對方給出的窗口值和當前網絡擁塞的程度來決定一個報文段應包含多少個字節(UDP 發送的報文長度是應用進程給出的)。

每一條 TCP 鏈接有兩個端點,而且惟一地被通訊兩端的兩個端點所肯定。
這裏的端點不是應用進程也不是端口,它有一個特殊的名字叫「套接字」(socket)。

套接字(socket) = (IP地址 : 端口號)
TCP 鏈接 ::= {socket1, socket2}

在解釋TCP的可靠性以前,咱們先了解一下到底什麼是可靠傳輸

可靠傳輸的工做原理

所謂「可靠性」主要靠兩大法寶協議實現:

  • 中止等待協議
  • 連續ARQ協議
一個直觀的理解就是:「只有確認我發的東西你收到了,我才能繼續往下發。(中止等待協議)可是每發一個報文都要等待確認效率過低,因此規定那麼一個區域範圍,範圍以內的分組能夠一次發送出去而不須要確認。(連續ARQ協議)」

中止等待協議

「中止等待」就是每發送完一個分組就中止發送,等待對方的確認。在收到確認後再發送下一個分組。

超時重傳

發送方爲每個已發送的分組都設置了一個超時計時器。
只要在超時計時器到期以前收到了相應的確認,發送方就撤銷該超時計時器,繼續發送下一個分組。
不然,發送方將重傳分組。

自動重傳請求 ARQ

重傳的請求是自動進行的,接收方不須要請求發送方重傳某個出錯的分組。
使用這種確認和重傳機制,咱們就能夠在不可靠的傳輸網絡上實現可靠的通訊。

經過滑動窗口實現的連續ARQ協議

發送方維持一個發送窗口,位於發送窗口內的分組均可連續發送出去,而不須要等待對方的確認。
連續ARQ協議規定,發送方每收到一個確認,就把發送窗口向前滑動一個分組的位置。

累計確認

接收方通常採用累積確認的方式。即沒必要對收到的分組逐個發送確認,而是對按序到達的最後一個分組發送確認,表示到這個分組爲止的全部分組都已正確收到了

在瞭解TCP具體如何實現「可靠傳輸」以前,咱們先來了解一下TCP報文的組成結構。

TCP報文段的首部格式

TCP報文結構

  • 源端口和目的端口:各佔兩個字節(16位),端口(Port)是運輸層與應用層的服務接口,以實現複用和分用。
  • 序號(sequence number):佔4個字節,指本報文段所發送的數據的第一個字節的序號。
  • 確認號(acknowledgement number):一樣佔4個字節,是指望收到對方下一個報文段的第一個字節的序號。(即收到對方的報文段最後一個字節的序號加一)
  • 數據偏移:佔4位,指首部的長度,以4字節爲單位。
  • 標誌位(Flags)

    • 緊急(URG):URG=1時表示報文段中有緊急數據,應儘快傳送;
    • 確認(ACK):ACK=1時確認號字段(acknowledgement number)纔有效;
    • 推送(PSH):接收TCP收到 PSH = 1 的報文段,就儘快地交付接收應用進程,而再也不等到整個緩存都填滿了後再向上交付;
    • 復位(RST):RST=1時代表鏈接中出現嚴重差錯,須要重連;
    • 同步(SYN):SYN=1表示這是一個「鏈接請求(SYN)」或「鏈接接受(SYN-ACK)」報文;
    • 終止(FIN):用於釋放鏈接,FIN=1代表報文段發送完畢,要求釋放鏈接。
  • 窗口:佔2字節,是用來讓對方設置發送窗口的依據。
  • 檢驗和:佔2字節。檢驗和字段檢驗的範圍包括首部和數據這兩部分在計算檢驗和時,要在 TCP 報文段的前面加上 12 字節的僞首部
  • 可變部分中的最大報文長度MSS:MSS (Maximum Segment Size)是 TCP 報文段中的數據字段(不包括首部)的最大長度。經過這個告訴對方「個人緩存所能接收的報文段的數據字段的最大長度是 MSS 個字節」。
  • 填充字段:爲了使整個首部長度是 4 字節的整數倍。

TCP可靠傳輸的實現

以字節爲單位的滑動窗口

以前已經介紹過了連續ARQ協議,這個協議在TCP中的應用就是「滑動窗口」,這個窗口以字節爲單位。
如今假設,A收到了B發來的確認號爲32(代表B指望收到的下一個報文段的開頭序號爲32),窗口爲20字節的確認報文段,那麼A即可以根據這兩個數據構建出以下發送窗口:
發送窗口1

A發送11個字節的數據後,發送窗口位置不變,可用窗口變小:
發送窗口2

此時,B收到了前三個字節,向A發送確認號爲35的確認報文字段(同時接收窗口向前移動三個字節);
A的發送窗口在收到B的確認報文後也向前移動三個字節。
發送窗口3

接着,A繼續向B發送報文,可是B一直沒有發回確認報文。
A在發送至可用窗口爲零時便中止發送。
發送窗口4

發送緩存與接收緩存

發送緩存與接收緩存

發送方在發送報文前,應用進程是先把字節流寫入 TCP 的發送緩存中。
同時,發送端發送出去的報文在沒有收到確認報文時,也會暫存在發送緩存中。發送窗口一般只是發送緩存的一部分。

在接收端,接收緩存負責暫存按序到達的、但還沒有被接收應用程序讀取的數據;以及不按序到達的數據。

這裏有幾點須要咱們注意

  • A的發送窗口並不老是和B的接收窗口同樣大(由於有必定的時間滯後)。
  • TCP標準沒有規定對不按序到達的數據應如何處理。一般是先臨時存放在接收窗口中,等到字節流中所缺乏的字節收到後,再按序交付上層的應用進程。(或者使用*選擇確認SACK)
  • TCP 要求接收方必須有累積確認的功能,這樣能夠減少傳輸開銷。
  • 接收方能夠在合適的時候發送確認,也能夠在本身有數據要發送時把確認信息順便捎帶上。

在找資料時看到一篇很好的解釋TCP傳輸控制的文章,你們能夠check it out~

*關於選擇確認SACK:
接收方收到了和前面的字節流不連續的兩個字節塊。
若是這些字節的序號都在接收窗口以內,那麼接收方就先收下這些數據,並把這些信息準確地告訴發送方,使發送方不要再重複發送這些已收到的數據。
首先,需在TCP首部選項中加上「容許 SACK」的選項。
原來首部中的「確認號字段」的用法仍然不變,只是之後在 TCP 報文段的首部中增長了SACK選項,以便報告收到的不連續的字節塊的邊界。

超時重傳時間的選擇

重傳機制是TCP中最重要和最複雜的問題之一。
TCP 每發送一個報文段,就對這個報文段設置一次計時器。只要計時器設置的重傳時間到但尚未收到確認,就要重傳這一報文段。

那麼如何肯定重傳時間呢?這是TCP最複雜的問題之一。
若是把超時重傳時間設置得過短,就會引發不少報文段的沒必要要的重傳,使網絡負荷增大。
但若把超時重傳時間設置得過長,則又使網絡的空閒時間增大,下降了傳輸效率。

爲了獲得較爲合理的重傳時間,TCP 採用了一種自適應算法。
RTO算法

算法中最關鍵的就是往返時間(RTT)的測量。
測量往返時間時,因爲有的報文通過重傳後,沒法判斷收到的確認報文是重傳報文的確認報文仍是原報文的確認報文,故採用了Karn算法
在計算平均往返時間 RTT 時,只要報文段重傳了,就不採用其往返時間樣本。
而且,報文段每重傳一次,就把 RTO 增大一些,以彌補重傳時間的沒法更新。

TCP的流量控制

流量控制(flow control)就是讓發送方的發送速率不要太快,既要讓接收方來得及接收,也不要使網絡發生擁塞。

利用滑動窗口機制能夠很方便地在 TCP 鏈接上實現流量控制。
發送方根據收到的接收方報文段中的窗口(rwnd)字段調整發送窗口的大小。

死鎖問題
接收方在發送給發送方零報文段後,假設接收方又有了緩存空間,便會給發送方發送帶有新窗口大小的報文段。
可是這個報文段在傳送過程當中丟失了。發送方仍在等待窗口非零的報文;而接收方在等待發送方的數據, 場面一度十分尷尬。這就造成了「死鎖」。
爲了解決這個問題,TCP 爲每個鏈接設有一個持續計時器 (persistence timer)。
只要TCP鏈接的一方收到對方的零窗口通知,就啓動該持續計時器。
若持續計時器設置的時間到期,就發送一個零窗口探測報文段(僅攜帶 1 字節的數據),而對方就在確認這個探測報文段時給出瞭如今的窗口值。
若是仍是零窗口值,那麼從新設置計時器,繼續等。如此一來就解決了「互相干等」的死鎖問題。

下一節會介紹TCP協議中很重要的「擁塞避免」內容,later~

相關文章
相關標籤/搜索