計(jì)算機(jī)網(wǎng)絡(luò)——TCP/UDP協(xié)議

計(jì)算機(jī)網(wǎng)絡(luò)七層模型中,傳輸層有兩個(gè)重要的協(xié)議:
(1)用戶數(shù)據(jù)報(bào)協(xié)議UDP (User Datagram Protocol)
(2)傳輸控制協(xié)議TCP (Transmission Control Protocol)

UDP 在傳送數(shù)據(jù)之前不需要先建立連接。遠(yuǎn)地主機(jī)的運(yùn)輸層在收到UDP 報(bào)文后,不需要給出任何確認(rèn)。雖然UDP 不提供可靠交付,但在某些情況下UDP 卻是一種最有效的工作方式。

TCP 則提供面向連接的服務(wù)。在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送結(jié)束后要釋放連接。TCP 不提供廣播或多播服務(wù)。由于TCP 要提供可靠的、面向連接的運(yùn)輸服務(wù),因此不可避免地增加了許多的開銷,如確認(rèn)、流量控制、計(jì)時(shí)器以及連接管理等。

使用UDP 和TCP 協(xié)議的各種應(yīng)用和應(yīng)用層協(xié)議

用戶數(shù)據(jù)報(bào)協(xié)議UDP

1 UDP 概述

UDP 的主要特點(diǎn)是:

  • UDP 是無連接的
    即發(fā)送數(shù)據(jù)之前不需要建立連接,因此減少了開銷和發(fā)送數(shù)據(jù)之前的時(shí)延。
  • UDP 使用盡最大努力交付
    即不保證可靠交付,因此主機(jī)不需要維持復(fù)雜的連接狀態(tài)表(這里面有許多參數(shù))。
  • UDP 是面向報(bào)文的
    UDP 對應(yīng)用層交下來的報(bào)文,既不合井,也不拆分,而是保留這些報(bào)文的邊界。這就是說,應(yīng)用層交給UDP 多長的報(bào)文, UDP 就照樣發(fā)送,即一次發(fā)送一個(gè)報(bào)文。因此應(yīng)用程序必須選擇合適大小的報(bào)文。若報(bào)文太長, UDP 把它交給IP 層后, IP 層在傳送時(shí)可能要進(jìn)行分片,這會(huì)降低IP 層的效率。反之,若報(bào)文太短, UDP 把它交給IP 層后,會(huì)使IP 數(shù)據(jù)報(bào)的首部的相對長度太太,這也降低了IP 層的效率。

2 UDP 的首都格式

首部手段很簡單,只有8 個(gè)字節(jié),由四個(gè)字段組成,每個(gè)字段的長度都是兩個(gè)字節(jié)。

  • 源端口
    在需要對方回信時(shí)選用。不需要時(shí)可用全0 。
  • 目的端口
    這在終點(diǎn)交付報(bào)文時(shí)必須要使用到。
  • 長度
    UDP 用戶數(shù)據(jù)報(bào)的長度,其最小值是8 (僅有首部)。
  • 檢驗(yàn)和
    檢測UDP 用戶數(shù)據(jù)報(bào)在傳輸中是否有錯(cuò)。有錯(cuò)就去棄。
UDP 的首都格式

傳輸控制協(xié)議TCP

1 TCP 最主要的特點(diǎn)

  • TCP 是面向連接的運(yùn)輸層協(xié)議
    這就是說,應(yīng)用程序在使用TCP 協(xié)議之前,必須先建立TCP 連接。在傳送數(shù)據(jù)完畢后,必須釋放已經(jīng)建立的TCP 連接。
  • 每一條TCP 連接只能是點(diǎn)對點(diǎn)的
  • TCP 提供可靠交付的服務(wù)
    也就是說,通過TCP 連接傳送的數(shù)據(jù),無差錯(cuò)、不丟失、不重復(fù)、并且按序到達(dá)。
  • TCP 提供全雙工通信
    TCP 允許通信雙方的應(yīng)用進(jìn)程在任何時(shí)候都能發(fā)送數(shù)據(jù)。TCP 連接的兩端都設(shè)有發(fā)送緩存和接收緩存,用來臨時(shí)存放雙向通信的數(shù)據(jù)。在發(fā)送時(shí),應(yīng)用程序在把數(shù)據(jù)傳送給TCP 的緩存后,就可以做自己的事,而TCP 在合適的時(shí)候把數(shù)據(jù)發(fā)送出去。在接收時(shí), TCP 把收到的數(shù)據(jù)放入緩存,上層的應(yīng)用進(jìn)程在合適的時(shí)候讀取緩存中的數(shù)據(jù)。
  • 面向字節(jié)流
    “面向字節(jié)流”的含義是:雖然應(yīng)用程序和TCP 的交互是一次一個(gè)數(shù)據(jù)塊(大小不等),但TCP 把應(yīng)用程序交下來的數(shù)據(jù)看成僅僅是一連串的無結(jié)構(gòu)的字節(jié)流。TCP 并不知道所傳送的字節(jié)流的含義。
TCP 面向流的概念

2 TCP 的連接

前面已經(jīng)講過,每條TCP 連接有兩個(gè)端點(diǎn),TCP 連接的端點(diǎn)叫做套接字(socket)或插口。套接字格式如下:

套接寧socket= (IP 地址:端口號(hào)’)

每一條TCP 連接唯一地被通信兩端的兩個(gè)端點(diǎn)(即兩個(gè)套接宇)所確定。即:
TCP 連接= {socket1, socket2} = {(IP1: port1), (IP2: port2)}

3次握手鏈接

  • 第一次握手
    當(dāng)客戶端向服務(wù)器發(fā)起連接請求時(shí),客戶端會(huì)發(fā)送同步序列標(biāo)號(hào)SYN到服務(wù)器,在這里我們設(shè)SYN為m,等待服務(wù)器確認(rèn),這時(shí)客戶端的狀態(tài)為SYN_SENT。
  • 第二次握手
    當(dāng)服務(wù)器收到客戶端發(fā)送的SYN后,發(fā)送確認(rèn)包ACK,這里的ACK為m+1,意思是說“我收到了你發(fā)送的SYN了”,同時(shí),服務(wù)器也會(huì)向客戶端發(fā)送一個(gè)SYN包,這里我們設(shè)SYN為n。這時(shí)服務(wù)器的狀態(tài)為SYN_RECV。
  • 第三次握手
    客戶端收到服務(wù)器發(fā)送的SYN和ACK包后,需向服務(wù)器發(fā)送確認(rèn)包ACK,這里的ACK為n+1,發(fā)送完畢后,客戶端和服務(wù)器的狀態(tài)為ESTABLISH,即TCP連接成功。
TCP三次握手

4次握手釋放鏈接

斷開連接請求可以由客戶端發(fā)出,也可以由服務(wù)器端發(fā)出,在這里我們稱A端向B端請求斷開連接。

  • 第一次揮手
    A端向B端請求斷開連接時(shí)會(huì)向B端發(fā)送一個(gè)帶有FIN標(biāo)記的報(bào)文段
  • 第二次揮手
    B端收到A發(fā)送的FIN后,B段現(xiàn)在可能現(xiàn)在還有數(shù)據(jù)沒有傳完,所以B端并不會(huì)馬上向A端發(fā)送FIN,而是先發(fā)送一個(gè)確認(rèn)序號(hào)ACK,意思是說“你發(fā)的斷開連接請求我收到了,但是我現(xiàn)在還有數(shù)據(jù)沒有發(fā)完,請稍等一下唄”。
  • 第三次揮手
    當(dāng)B端的事情忙完了,那么此時(shí)B端就可以斷開連接了,此時(shí)B端向A端發(fā)送FIN序號(hào),意思是這次可以斷開連接了。
  • 第四次揮手
    A端收到B端發(fā)送的FIN后,會(huì)向B端發(fā)送確認(rèn)ACK,然后經(jīng)過兩個(gè)MSL時(shí)長后斷開連接。
TCP四次揮手

各個(gè)狀態(tài)節(jié)點(diǎn)解釋如下:

  • FIN_WAIT_1:
    FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對方的FIN報(bào)文。而這兩種狀態(tài)的區(qū)別是:FIN_WAIT_1狀態(tài)實(shí)際上是當(dāng)SOCKET在ESTABLISHED狀態(tài)時(shí),它想主動(dòng)關(guān)閉連接,向?qū)Ψ桨l(fā)送了FIN報(bào)文,此時(shí)該SOCKET即進(jìn)入到FIN_WAIT_1狀態(tài)。而當(dāng)對方回應(yīng)ACK報(bào)文后,則進(jìn)入到FIN_WAIT_2狀態(tài),當(dāng)然在實(shí)際的正常情況下,無論對方何種情況下,都應(yīng)該馬上回應(yīng)ACK報(bào)文,所以FIN_WAIT_1狀態(tài)一般是比較難見到的,而FIN_WAIT_2狀態(tài)還有時(shí)常常可以用netstat看到。(主動(dòng)方)
  • CLOSE_WAIT
    這種狀態(tài)的含義其實(shí)是表示在等待關(guān)閉。怎么理解呢?當(dāng)對方close一個(gè)SOCKET后發(fā)送FIN報(bào)文給自己,你系統(tǒng)毫無疑問地會(huì)回應(yīng)一個(gè)ACK報(bào)文給對方,此時(shí)則進(jìn)入到CLOSE_WAIT狀態(tài)。接下來呢,實(shí)際上你真正需要考慮的事情是察看你是否還有數(shù)據(jù)發(fā)送給對方,如果沒有的話,那么你也就可以 close這個(gè)SOCKET,發(fā)送FIN報(bào)文給對方,也即關(guān)閉連接。所以你在CLOSE_WAIT狀態(tài)下,需要完成的事情是等待你去關(guān)閉連接。(被動(dòng)方)
  • FIN_WAIT_2
    上面已經(jīng)詳細(xì)解釋了這種狀態(tài),實(shí)際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時(shí)還有點(diǎn)數(shù)據(jù)需要傳送給你(ACK信息),稍后再關(guān)閉連接。(主動(dòng)方)
  • LAST_ACK
    這個(gè)狀態(tài)還是比較容易好理解的,它是被動(dòng)關(guān)閉一方在發(fā)送FIN報(bào)文后,最后等待對方的ACK報(bào)文。當(dāng)收到ACK報(bào)文后,也即可以進(jìn)入到CLOSED可用狀態(tài)了。(被動(dòng)方)
  • TIME_WAIT
    表示收到了對方的FIN報(bào)文,并發(fā)送出了ACK報(bào)文,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FIN_WAIT_1狀態(tài)下,收到了對方同時(shí)帶FIN標(biāo)志和ACK標(biāo)志的報(bào)文時(shí),可以直接進(jìn)入到TIME_WAIT狀態(tài),而無須經(jīng)過FIN_WAIT_2狀態(tài)。(主動(dòng)方)
  • CLOSED
    表示連接中斷。

TCP可靠傳輸?shù)墓ぷ髟?/h2>

1 停止等待協(xié)議

下面為了討論問題的萬便,我們僅考慮A發(fā)送數(shù)據(jù)而B 接收數(shù)據(jù)并發(fā)送確認(rèn)。因此A 叫做發(fā)送方,而B 叫做接收方。

“停止等待”就是每發(fā)送完一個(gè)分組就停止發(fā)送,等待對方的確認(rèn)。在收到確認(rèn)后再發(fā)送下一個(gè)分組。

  • 無差錯(cuò)情況
    A 發(fā)送分組M1,發(fā)完就暫停發(fā)送,等待B 的確認(rèn)。B 收到了M1 就向A 發(fā)送確認(rèn)。A 在收到了對M1的確認(rèn)后,就再發(fā)送下一個(gè)分組M2。同樣,在收到B 對M2的確認(rèn)后,再發(fā)送M3
無差錯(cuò)情況
  • 超時(shí)重傳
    B 接收M1時(shí)檢測出了差錯(cuò)就丟棄M1,其他什么也不做(不通知A 收到有差錯(cuò)的分組戶。也可能是M1 在傳輸過程中丟失了,這時(shí)B 當(dāng)然什么都不知道。在這兩種情況下, B都不會(huì)發(fā)送任何信息。可靠傳輸協(xié)議是只要超過了一段時(shí)間仍然沒有收到確認(rèn),就認(rèn)為剛才發(fā)送的分組丟失了,因而重傳前面發(fā)送過的分組。這就叫做超時(shí)重傳。要實(shí)現(xiàn)超時(shí)重傳,就要在每發(fā)送完一個(gè)分組設(shè)置一個(gè)超時(shí)計(jì)時(shí)器。如果在超時(shí)計(jì)時(shí)器到期之前收到了對方的確認(rèn),就撤銷己設(shè)置的超時(shí)計(jì)時(shí)器。
超時(shí)重傳
  • 確認(rèn)丟失
    B所發(fā)送的對M1的確認(rèn)丟失了。A在設(shè)定的超時(shí)重傳時(shí)間內(nèi)沒有收到確認(rèn),因此A 在超時(shí)計(jì)時(shí)器到期后就要重傳M1。現(xiàn)在應(yīng)注意B的動(dòng)作。假定B又收到了重傳的分組M1。這時(shí)應(yīng)采取兩個(gè)行動(dòng):
    (1)丟棄重復(fù)的M1
    (2)重新發(fā)送確認(rèn)
確認(rèn)丟失
  • 確認(rèn)超時(shí)
    傳輸過程中沒有出現(xiàn)差錯(cuò),但B 對分組M1 的確認(rèn)遲到了。A 會(huì)收到重復(fù)的確認(rèn)。對重復(fù)的確認(rèn)的處理很簡單:收下后就丟棄。B 仍然會(huì)收到重復(fù)的M1 ,并且同樣要丟棄重復(fù)的M1 ,并重傳確認(rèn)分組。
確認(rèn)超時(shí)

使用上述的確認(rèn)和重傳機(jī)制,我們就可以在不可靠的傳輸網(wǎng)絡(luò)上實(shí)現(xiàn)可靠的通信。像上述的這種可靠傳輸協(xié)議常稱為自動(dòng)重傳請求ARQ (Automatic Repeat reQuest)。意思是重傳的請求是自動(dòng)進(jìn)行的。接收方不需要請求發(fā)送方重傳某個(gè)出錯(cuò)的分組。

2 連續(xù)ARQ協(xié)議

滑動(dòng)窗口協(xié)議比較復(fù)雜,是TCP 協(xié)議的精髓所在。這里先給出連續(xù)ARQ 協(xié)議最基本的概念,但不涉提到許多細(xì)節(jié)問題。詳細(xì)的滑動(dòng)窗口協(xié)議將在后面討論。

下圖表示發(fā)送方維持的發(fā)送窗口,它的意義是:位于發(fā)送窗口內(nèi)的5 個(gè)分組都可連續(xù)發(fā)送出去,而不需要等待對方的確認(rèn)。這樣,信道利用率就提高了。

連續(xù)ARQ協(xié)議工作原理

連續(xù)ARQ 協(xié)議規(guī)定,發(fā)送方每收到一個(gè)確認(rèn),就把發(fā)送窗口向前滑動(dòng)一個(gè)分組的位置。

接收方一般都是采用累積確認(rèn)的方式。這就是說,接收方不必對收到的分組逐個(gè)發(fā)送確認(rèn),而是可以在收到幾個(gè)分組后,對按序到達(dá)的最后一個(gè)分組發(fā)送確認(rèn),這樣就表示:到這個(gè)分組為止的所有分組都己正確收到了。

累積確認(rèn)的優(yōu)點(diǎn)是容易實(shí)現(xiàn),即使確認(rèn)丟失也不必重傳。但缺點(diǎn)是不能向發(fā)送方反映出接收方己經(jīng)正確收到的所有分組的信息。

例如,如果發(fā)送方發(fā)送了前5 個(gè)分組,而中間的第3 個(gè)分組丟失了。這時(shí)接收方只能對前兩個(gè)分組發(fā)出確認(rèn)。發(fā)送方無法知道后面三個(gè)分組的下落,而只好把后面的三個(gè)分組都再重傳一次。這就叫做Go-back-N (回退N ),表示需要再退回來重傳己發(fā)送過的N 個(gè)分組。可見當(dāng)通信線路質(zhì)量不好時(shí),連續(xù)ARQ 協(xié)議會(huì)帶來負(fù)面的影響。

TCP報(bào)文格式

TCP報(bào)文格式
  • 源端口和目的端口各占2 個(gè)宇節(jié),分別寫入源端口號(hào)和目的端口號(hào)。
  • 序號(hào)
    占4 宇節(jié),TCP 是面向字節(jié)流的。在一個(gè)TCP 連接中傳送的宇節(jié)流中的每一個(gè)字節(jié)都按順序編號(hào)。首部中的序號(hào)字段值則指的是本報(bào)文段所發(fā)送的數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào)。例如,一報(bào)文段的序號(hào)字段值是301 ,而攜帶的數(shù)據(jù)共有100字節(jié)。這就表明:本報(bào)文段的數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào)是301 ,最后一個(gè)字節(jié)的序號(hào)是400。
  • 確認(rèn)號(hào)
    占4 字節(jié),是期望收到對方下一個(gè)報(bào)文段的第一個(gè)數(shù)據(jù)字節(jié)的序號(hào)。例如, B 正確收到了A 發(fā)送過來的一個(gè)報(bào)文段,其序號(hào)字段值是501 ,而數(shù)據(jù)長度是200 宇節(jié)(序號(hào)501 ~ 700 ),這表明B 正確收到了A 發(fā)送的到序號(hào)700 為止的數(shù)據(jù)。因此, B 期望收到A 的下一個(gè)數(shù)據(jù)序號(hào)是701 ,于是B 在發(fā)送給A 的確認(rèn)報(bào)文段中把確認(rèn)號(hào)置為701 。
  • 窗口
    占2 字節(jié),窗口指的是發(fā)送本報(bào)文段的一方的接收窗口(而不是自己的發(fā)送窗口)。窗口值告訴對方:從本報(bào)文段首部中的確認(rèn)號(hào)算起,接收方目前允許對方發(fā)送的數(shù)據(jù)量。例如,設(shè)確認(rèn)號(hào)是701 ,窗口字段是1000。這就表明,從701 號(hào)算起,發(fā)送此報(bào)文段的一方還有接收1000 個(gè)字節(jié)數(shù)據(jù)(字節(jié)序號(hào)是701 - 1700 )的接收緩存空間。
    總之,窗口字段明確指出了現(xiàn)在允許對方發(fā)送的數(shù)據(jù)量。窗口值是經(jīng)常在動(dòng)態(tài)變化著。

TCP 可靠傳輸?shù)膶?shí)現(xiàn)——以字節(jié)為單位的滑動(dòng)窗口

1 以字節(jié)為單位的滑動(dòng)窗口

TCP 的滑動(dòng)窗口是以字節(jié)為單位的。現(xiàn)假定A 收到了B 發(fā)來的確認(rèn)報(bào)文段,其中窗口是20 (字節(jié)),而確認(rèn)號(hào)是31 (這表明B 期望收到的下一個(gè)序號(hào)是31 ,而序號(hào)30 為止的數(shù)據(jù)己經(jīng)收到了)。根據(jù)這兩個(gè)數(shù)據(jù), A 就構(gòu)造出自己的發(fā)送窗口,其位置如圖所示。

根據(jù)B 給出的窗口值, A 構(gòu)造出自己的發(fā)送窗口

發(fā)送窗口表示:在沒有收到B 的確認(rèn)的情況下, A可以連續(xù)把窗口內(nèi)的數(shù)據(jù)都發(fā)送出去。凡是己經(jīng)發(fā)送過的數(shù)據(jù),在未收到確認(rèn)之前都必須暫時(shí)保留,以便在超時(shí)重傳時(shí)使用。

發(fā)送窗口后沿的后面部分表示己發(fā)送且己收到了確認(rèn)。這些數(shù)據(jù)顯然不需要再保留了。而發(fā)送窗口前沿的前面部分表示不允許發(fā)送的,因?yàn)榻邮辗蕉紱]有為這部分?jǐn)?shù)據(jù)保留臨時(shí)存放的緩存空間。

現(xiàn)在假定A 發(fā)送了序號(hào)為31 ~ 41 的數(shù)據(jù)。這時(shí)發(fā)送窗口位置并未改變,但發(fā)送窗口內(nèi)靠后面有11個(gè)字節(jié)(灰色小方框表示)表示己發(fā)送但未收到確認(rèn)。而發(fā)送窗口內(nèi)靠前面的9 個(gè)字節(jié)( 42 ~ 50 )是允許發(fā)送但尚未發(fā)送的。】

A 的發(fā)送窗門

再看一下B 的接收窗口。B 的接收窗口大小是20,在接收窗口外面,到30 號(hào)為止的數(shù)據(jù)是已經(jīng)發(fā)送過確認(rèn),并且己經(jīng)交付給主機(jī)了。因此在B 可以不再保留這些數(shù)據(jù)。接收窗口內(nèi)的序號(hào)(31~50)足允許接收的。B 收到了序號(hào)為32 和33 的數(shù)據(jù),這些數(shù)據(jù)沒有按序到達(dá),因?yàn)樾蛱?hào)為31 的數(shù)據(jù)沒有收到(也許丟失了,也許滯留在網(wǎng)絡(luò)中的某處)。請注意, B 只能對按序收到的數(shù)據(jù)中的最高序號(hào)給出確認(rèn),因此B 發(fā)送的確認(rèn)報(bào)文段中的確認(rèn)號(hào)仍然是31 (即期望收到的序號(hào))。

B的接收窗口

現(xiàn)在假定B 收到了序號(hào)為31 的數(shù)據(jù),并把序號(hào)為31~33的數(shù)據(jù)交付給主機(jī),然后B刪除這些數(shù)據(jù)。接著把接收窗口向前移動(dòng)3個(gè)序號(hào),同時(shí)給A 發(fā)送確認(rèn),其中窗口值仍為20,但確認(rèn)號(hào)是34,這表明B 已經(jīng)收到了到序號(hào)33 為止的數(shù)據(jù)。我們注意到,B還收到了序號(hào)為37, 38 和40 的數(shù)據(jù),但這些都沒有按序到達(dá),只能先存在接收窗口。A收到B的確認(rèn)后,就可以把發(fā)送窗口向前滑動(dòng)3個(gè)序號(hào),指針P2 不動(dòng)。可以看出,現(xiàn)在A 的可用窗口增大了,可發(fā)送的序號(hào)范圍是42~53。整個(gè)過程如下圖:

A 收到新的確認(rèn)號(hào),發(fā)送窗口向前滑動(dòng)

A 在繼續(xù)發(fā)送完序號(hào)42-53的數(shù)據(jù)后,指針P2向前移動(dòng)和P3重合。發(fā)送窗口內(nèi)的序號(hào)都已用完,但還沒有再收到確認(rèn)。由于A 的發(fā)送窗口己滿,可用窗口己減小到0,因此必須停止發(fā)送。

發(fā)送窗口內(nèi)的序號(hào)都屬于己發(fā)送但未被確認(rèn)

2 超時(shí)重傳時(shí)間的選擇

上面已經(jīng)講到, TCP 的發(fā)送方在規(guī)定的時(shí)間內(nèi)沒有收到確認(rèn)就要重傳已發(fā)送的報(bào)文段。這種重傳的概念是很簡單的,但重傳時(shí)間的選擇卻是TCP 最復(fù)雜的問題之一。

TCP采用了一種自適應(yīng)算法,它記錄一個(gè)報(bào)文段發(fā)出的時(shí)間,以及收到相應(yīng)的確認(rèn)的時(shí)間。這兩個(gè)時(shí)間之差就是報(bào)文段的往返時(shí)間RTT,TCP 保留了RTT的一個(gè)加權(quán)平均往返時(shí)間RTTs (這又稱為平滑的往返時(shí)間, S 表示Smoothed 。因?yàn)檫M(jìn)行的是加權(quán)平均,因此得出的結(jié)果更加平滑)。每當(dāng)?shù)谝淮螠y量到RTT樣本時(shí), RTTs值就取為所測量到的RTT樣本值。但以后每測量到一個(gè)新的RTT樣本,就按下式重新計(jì)算一次RTTs:

新的RTTs = (1 - α)×(舊的RTTs) + α ×(新的RTT樣本)

α 越大表示新的RTTs受新的RTT樣本的影響越大。推薦的α 值為0.125,用這種方法得出的加權(quán)平均往返時(shí)間RTTs 就比測量出的RTT值更加平滑。

顯然,超時(shí)計(jì)時(shí)器設(shè)置的超時(shí)重傳時(shí)間RTO (RetransmissionTime-Out)應(yīng)略大于上面得出的加權(quán)平均往返時(shí)間RTTs。RFC 2988 建議使用下式計(jì)算RTO:

RTO = RTTs + 4 × RTTd

RTTd是RTT 的偏差的加權(quán)平均值,它與RTTs和新的RTT樣本之差有關(guān)。計(jì)算公式如下:

新的RTTd= (1- β)×(舊的RTTd) + β × |RTTs-新的RTT樣本|

發(fā)現(xiàn)問題:如圖所示,發(fā)送出一個(gè)報(bào)文段。設(shè)定的重傳時(shí)間到了,還沒有收到確認(rèn)。于是重
傳報(bào)文段。經(jīng)過了一段時(shí)間后,收到了確認(rèn)報(bào)文段。現(xiàn)在的問題是:如何判定此確認(rèn)報(bào)文段是對先發(fā)送的報(bào)文段的確認(rèn),還是對后來重傳的報(bào)文段的確認(rèn)?

收到的確認(rèn)是對哪一個(gè)報(bào)文段的確認(rèn)?

若收到的確認(rèn)是對重傳報(bào)文段的確認(rèn),但卻被源主機(jī)當(dāng)成是對原來的報(bào)文段的確認(rèn),則這樣計(jì)算出的RTTs 和超時(shí)重傳時(shí)間RTO 就會(huì)偏大。若后面再發(fā)送的報(bào)文段又是經(jīng)過重傳后才收到確認(rèn)報(bào)文段,則按此方法得出的超時(shí)重傳時(shí)間RTO 就越來越長。

若收到的確認(rèn)是對原來的報(bào)文段的確認(rèn),但被當(dāng)成是對重傳報(bào)文段的確認(rèn),則由此計(jì)算出的RTTs 和RTO 都會(huì)偏小。這就必然導(dǎo)致報(bào)文段過多地重傳。這樣就有可能使RTO 越來越短。

Kam 提出了一個(gè)算法:在計(jì)算加權(quán)平均RTTs 時(shí),只要報(bào)文段重傳了就不采用其往返時(shí)間樣本。這樣得出的加權(quán)平均RTTs 和RTO 就較準(zhǔn)確。

新問題:設(shè)想出現(xiàn)這樣的情況:報(bào)文段的時(shí)延突然增大了很多。因此在原來得出的重傳時(shí)間內(nèi),不會(huì)收到確認(rèn)報(bào)文段。于是就重傳報(bào)文段。但根據(jù)Kam 算法,不考慮重傳的報(bào)文段的往返時(shí)間樣本。這樣,超時(shí)重傳時(shí)間就無法更新。

解決方案:對Kam 算法進(jìn)行修正,方法是z報(bào)文段每重傳一次,就把超時(shí)重傳時(shí)間RTO 增大一些。典型的做法是取新的重傳時(shí)間為2 倍的舊的重傳時(shí)間。當(dāng)不再發(fā)生報(bào)文段的重傳時(shí),才根據(jù)上面給出的公式計(jì)算超時(shí)重傳時(shí)間。

TCP 的流量控制

1 利用滑動(dòng)窗口實(shí)現(xiàn)流量控制

流量控制(flow control)就是讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收。

利用滑動(dòng)窗口機(jī)制可以很方便地在TCP 連接上實(shí)現(xiàn)對發(fā)送方的流量控制。

利用可變窗口進(jìn)行流量控制舉例

接收方的主機(jī)B 進(jìn)行了三次流量控制。第一次把窗口減小到rwnd =300,第二次又減到rwnd = 100 ,最后減到rwnd = 0 ,即不允許發(fā)送方再發(fā)送數(shù)據(jù)了。這種使發(fā)送方暫停發(fā)送的狀態(tài)將持續(xù)到主機(jī)B 重新發(fā)出一個(gè)新的窗口值為止。我們還應(yīng)注意到,B 向A 發(fā)送的三個(gè)報(bào)文段都設(shè)置了ACK=1,只有在ACK=1 時(shí)確認(rèn)號(hào)字段才有意義。

發(fā)生死鎖:現(xiàn)在我們考慮一種情況。上圖中, B 向A 發(fā)送了零窗口的報(bào)文段后不久, B 的接收緩存又有了一些存儲(chǔ)空間。于是B 向A 發(fā)送了rwnd = 400 的報(bào)文段。然而這個(gè)報(bào)文段在傳送過程中丟失了。A 一直等待收到B 發(fā)送的非零窗口的通知,而B 也一直等待A 發(fā)送的數(shù)據(jù)。如果沒有其他措施,這種互相等待的死鎖局面將一直延續(xù)下去。

解決方案:TCP 為每一個(gè)連接設(shè)有一個(gè)持續(xù)計(jì)時(shí)器(persistence timer)。只要TCP 連接的一方收到對方的零窗口通知,就啟動(dòng)持續(xù)計(jì)時(shí)器。若持續(xù)計(jì)時(shí)器設(shè)置的時(shí)間到期,就發(fā)送一個(gè)零窗口探測報(bào)文段(僅攜帶1 宇節(jié)的數(shù)據(jù)),而對方就在確認(rèn)這個(gè)探測報(bào)文段時(shí)給出了現(xiàn)在的窗口值。

常見問題解析

1 TCP連接時(shí)是三次握手,那么兩次握手可行嗎?

在《計(jì)算機(jī)網(wǎng)絡(luò)》中是這樣解釋的:已失效的連接請求報(bào)文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個(gè)連接請求報(bào)文段并沒有丟失,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長時(shí)間的滯留了,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server。本來這是一個(gè)早已失效的報(bào)文段。但server收到此失效的連接請求報(bào)文段后,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請求。于是就向client發(fā)出確認(rèn)報(bào)文段,同意建立連接。假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求,因此不會(huì)理睬server的確認(rèn),也不會(huì)向server發(fā)送ACK包。這樣就會(huì)白白浪費(fèi)資源。而經(jīng)過三次握手,客戶端和服務(wù)器都有應(yīng)有答,這樣可以確保TCP正確連接。

2 為什么TCP連接是三次,揮手確是四次?

在TCP連接中,服務(wù)器端的SYN和ACK向客戶端發(fā)送是一次性發(fā)送的,而在斷開連接的過程中,B端向A端發(fā)送的ACK和FIN是是分兩次發(fā)送的。因?yàn)樵贐端接收到A端的FIN后,B端可能還有數(shù)據(jù)要傳輸,所以先發(fā)送ACK,等B端處理完自己的事情后就可以發(fā)送FIN斷開連接了。

3 為什么在第四次揮手后會(huì)有2個(gè)MSL的延時(shí)?

MSL是Maximum Segment Lifetime,最大報(bào)文段生存時(shí)間,2個(gè)MSL是報(bào)文段發(fā)送和接收的最長時(shí)間。假定網(wǎng)絡(luò)不可靠,那么第四次發(fā)送的ACK可能丟失,即B端無法收到這個(gè)ACK,如果B端收不到這個(gè)確認(rèn)ACK,B端會(huì)定時(shí)向A端重復(fù)發(fā)送FIN,直到B端收到A的確認(rèn)ACK。所以這個(gè)2MSL就是用來處理這個(gè)可能丟失的ACK的。

TCP、UDP應(yīng)用層的使用

1 文件傳送協(xié)議

文件傳送協(xié)議FTP (File Transfer Protocol) [RFC 959]是因特網(wǎng)上使用得最廣泛的文件傳送協(xié)議,底層采用TCP協(xié)議。

盯P 使用客戶服務(wù)器方式。一個(gè)FTP 服務(wù)器進(jìn)程可同時(shí)為多個(gè)客戶進(jìn)程提供服務(wù)。FTP的服務(wù)器進(jìn)程由兩大部分組成:一個(gè)主進(jìn)程,負(fù)責(zé)接受新的請求:另外有若干個(gè)從屬進(jìn)程,負(fù)責(zé)處理單個(gè)請求。

FTP工作過程

在進(jìn)行文件傳輸時(shí),客戶和服務(wù)器之間要建立兩個(gè)并行的TCP 連接:“控制連接”(21端口)和“數(shù)據(jù)連接”(22端口)。控制連接在整個(gè)會(huì)話期間一直保持打開, FTP 客戶所發(fā)出的傳送請求,通過控制連接發(fā)送給服務(wù)器端的控制進(jìn)程,但控制連接并不用來傳送文件。實(shí)際用于傳輸文件的是“數(shù)據(jù)連接”。服務(wù)器端的控制進(jìn)程在接收到FTP 客戶發(fā)送來的文件傳輸請求后就創(chuàng)建“數(shù)據(jù)傳送進(jìn)程”和“數(shù)據(jù)連接”,用來連接客戶端和服務(wù)器端的數(shù)據(jù)傳送進(jìn)程。

2 簡單文件傳送協(xié)議TFTP

TCP/IP 協(xié)議族中還有一個(gè)簡單文件傳送協(xié)議TFfP (Trivial File Transfer Protocol),它是一個(gè)很小且易于實(shí)現(xiàn)的文件傳送協(xié)議,端口號(hào)69。

TFfP 也使用客戶服務(wù)器方式,但它使用UDP 數(shù)據(jù)報(bào),因此TFfP 需要有自己的差錯(cuò)改正措施。TFfP 只支持文件傳輸而不支持交耳。

3 TELNET

TELNET 是一個(gè)簡單的遠(yuǎn)程終端協(xié)議,底層采用TCP協(xié)議。TELNET 也使用客戶服務(wù)器方式。在本地系統(tǒng)運(yùn)行TELNET 客戶進(jìn)程,而在遠(yuǎn)地主機(jī)則運(yùn)行TELNET 服務(wù)器進(jìn)程,占用端口23。

4 郵件傳輸協(xié)議

一個(gè)電子郵件系統(tǒng)應(yīng)具如圖所示的三個(gè)主要組成構(gòu)件,這就是用戶代理、郵件服務(wù)器,以及郵件發(fā)送協(xié)議(如SMTP )和郵件讀取協(xié)議(如POP3), POP3 是郵局協(xié)議(Post Office Protocol)的版本3 。

電子郵件的最主要的組成構(gòu)件

SMTP 和POP3 (或IMAP )都是在TCP 連接的上面?zhèn)魉袜]件,使用TCP 的目的是為了使郵件的傳送成為可靠的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本書結(jié)構(gòu)是自頂向下的,所以請按下列順序閱讀: 1.計(jì)算機(jī)網(wǎng)絡(luò)自頂向下--應(yīng)用層2.計(jì)算機(jī)網(wǎng)絡(luò)自頂向下--運(yùn)輸層3....
    牛富貴兒閱讀 2,875評論 0 3
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】傳輸層 傳輸層協(xié)議概述 傳輸層協(xié)議為運(yùn)行在不同host上的進(jìn)程提供了一種邏輯通信機(jī)制。使得端到端不需...
    666真666閱讀 2,067評論 0 4
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,425評論 0 13
  • 傳輸層-TCP, TCP頭部結(jié)構(gòu) ,TCP序列號(hào)和確認(rèn)號(hào)詳解 TCP主要解決下面的三個(gè)問題 1.數(shù)據(jù)的可靠傳輸...
    抓兔子的貓閱讀 4,544評論 1 46
  • 1 運(yùn)輸層協(xié)議概述 1.1 進(jìn)程之間的通信 網(wǎng)絡(luò)層是為主機(jī)之間提供邏輯通信,而運(yùn)輸層為應(yīng)用進(jìn)程之間提供端到端的邏輯...
    Mr希靈閱讀 8,172評論 0 34