程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> TCP/IP學習筆記(6)

TCP/IP學習筆記(6)

編輯:關於VC++

一、TCP協議

1、TCP 通過以下方式提供可靠性:

◆ 應用程序分割為TCP認為最合適發送的數據塊。由TCP傳遞給IP的信息單位叫做報文段。

◆ 當TCP發出一個報文段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能記時收到一個確認,它 就重發這個報文段。

◆ 當TCP收到發自TCP連接另一端的數據,它將發送一個確認。這個確認不是立即發送,通常延遲幾分之一秒。

◆ TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化如果收到報文段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到這個報文段。

◆ 既然TCP報文段作為IP數據報來傳輸,而IP數據報的到達可能失序,因此TCP報文段的到達也可能失序。如果必要,TCP將對收到的數據進行排序,將收到的數據以正確的順序交給應用層。

◆ 既然IP數據報會發生重復,TCP連接端必須丟棄重復的數據。

◆ TCP還能提供流量控制,TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發送接收端緩沖區所能接納的數據。這將防止較快主機致使較慢主機的緩沖區溢出。

另外,TCP對字節流的內容不作任何解釋。

2、TCP首部:

TCP數據被封裝在一個IP數據報中,格式如下:

IP首部20 TCP首部20 TCP首部

TCP首部格式如下:

16位源端口號 16位目的端口號 32位序號 32位確認序號 4位首部長度 保留6位 U

 

R

G

A

 

C

K

P

 

S

H

R

 

S

T

S

 

Y

N

F

 

I

N

16位窗口大小 16位檢驗和 16位緊急指針 選項 數據

說明:

(1)每個TCP段都包括源端和目的端的端口號,用於尋找發送端和接收端的應用進程。這兩個值加上IP首部的源端IP地址和目的端IP地址唯一確定一個TCP連接。

(2)序號用來標識從TCP發送端向接收端發送的數據字節流,它表示在這個報文段中的第一個數據字節。如果將字節流看作在兩個應用程序間的單向流動,則TCP用序號對每個字節進行計數。

(3)當建立一個新連接時,SYN標志變1。序號字段包含由這個主機選擇的該連接的初始序號ISN,該主機要發送數據的第一個字節的序號為這個ISN加1,因為SYN標志使用了一個序號。

(4)既然每個被傳輸的字節都被計數,確認序號包含發送確認的一端所期望收到的下一個序號。因此,確認序號應當時上次已成功收到數據字節序號加1。只有ACK標志為1時確認序號字段才有效。

(5)發送ACK無需任何代價,因為32位的確認序號字段和ACK標志一樣,總是TCP首部的一部分。因此一旦一個連接建立起來,這個字段總是被設置,ACK標志也總是被設置為1。

(6)TCP為應用層提供全雙工的服務。因此,連接的每一端必須保持每個方向上的傳輸數據序號。

(7)TCP可以表述為一個沒有選擇確認或否認的華東窗口協議。因此TCP首部中的確認序號表示發送方已成功收到字節,但還不包含確認序號所指的字節。當前還無法對數據流中選定的部分進行確認。

(8)首部長度需要設置,因為任選字段的長度是可變的。TCP首部最多60個字節。

(9)6個標志位中的多個可同時設置為1

◆ URG-緊急指針有效

◆ ACK-確認序號有效

◆ PSH-接收方應盡快將這個報文段交給應用層

◆ RST-重建連接

◆ SYN-同步序號用來發起一個連接

◆ FIN-發送端完成發送任務

(10)TCP的流量控制由連接的每一端通過聲明的窗口大小來提供。窗口大小為字節數,起始於確認序號字段指明的值,這個值是接收端期望接收的字節數。窗口大小是一個16為的字段,因而窗口大小最大為65535字節。

(11)檢驗和覆蓋整個TCP報文端:TCP首部和TCP數據。這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證。TCP檢驗和的計算和UDP首部檢驗和的計算一樣,也使用偽首部。

(12)緊急指針是一個正的偏移量,黃蓉序號字段中的值相加表示緊急數據最後一個字節的序號。TCP的緊急方式是發送端向另一端發送緊急數據的一種方式。

(13)最常見的可選字段是最長報文大小MMS,每個連接方通常都在通信的第一個報文段中指明這個選項。它指明本端所能接收的最大長度的報文段。

二、TCP連接的建立和終止

1、建立連接協議

(1) 請求端發送一個SYN段指明客戶打算連接的服務器的端口,隱疾初始序號(ISN),這個SYN報文段為報文段1。

(2) 服務器端發回包含服務器的初始序號的SYN報文段(報文段2)作為應答。同時將確認序號設置為客戶的ISN加1以對客戶的SYN報文段進行確認。一個SYN將占用一個序號。

(3) 客戶必須將確認序號設置為服務器的ISN加1以對服務器的SYN報文段進行確認(報文段3)。

這3個報文段完成連接的建立,稱為三次握手。發送第一個SYN的一端將執行主動打開,接收這個SYN並發回下一個SYN的另一端執行被動打開。

2、連接終止協議

由於TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接。收到一個FIN只意味著這一方向上沒有數據流動,一個TCP連接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

(1) TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送(報文段4)。

(2) 服務器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。和SYN一樣,一個FIN將占用一個序號。

(3) 服務器關閉客戶端的連接,發送一個FIN給客戶端(報文段6)。

(4) 客戶段發回確認,並將確認序號設置為收到序號加1(報文段7)。

3、連接建立的超時

如果與服務器無法建立連接,客戶端就會三次向服務器發送連接請求。在規定的時間內服務器未應答,則連接失敗。

4、最大報文段長度MSS

最大報文段長度表示TCP傳往另一端的最大塊數據的長度。當一個連接建立時,連接的雙方都要通告各自的MSS。

一般,如果沒有分段發生,MSS還是越大越好。報文段越大允許每個報文段傳送的數據越多,相對IP和TCP首部有更高的網絡利用率。當TCP發送一個SYN時,它能將MSS值設置為外出接口的MTU長度減去IP首部和TCP首部長度。對於以太網,MSS值可達1460。

如果目的地址為非本地的,MSS值通常默認為536,是否本地主要通過網絡號區分。MSS讓主機限制另一端發送數據報的長度,加上主機也能控制它發送數據報的長度,這將使以較小MTU連接到一個網絡上的主機避免分段。

5、 TCP的半關閉

TCP提供了連接的一端在結束它的發送後還能接收來自另一端數據的能力,這就是TCP的半關閉。

客戶端發送FIN,另一端發送對這個FIN的ACK報文段。當收到半關閉的一端在完成它的數據傳送後,才發送FIN關閉這個方向的連接,客戶端再對這個FIN確認,這個連接才徹底關閉。

6、2MSL連接

TIME_WAIT狀態也稱為2MSL等待狀態。每個TCP必須選擇一個報文段最大生存時間(MSL)。它是任何報文段被丟棄前在網絡的最長時間。

處理原則:當TCP執行一個主動關閉,並發回最後一個ACK,該連接必須在TIME_WAIT狀態停留的時間為2MSL。這樣可以讓TCP再次發送最後的ACK以避免這個ACK丟失(另一端超時並重發最後的FIN)。這種2MSL等待的另一個結果是這個TCP連接在2MSL等待期間,定義這個連接的插口不能被使用。

7、平靜時間

TCP在重啟的MSL秒內不能建立任何連接,這就是平靜時間。

8、FIN_WAIT_2狀態

在FIN_WAIT_2狀態我們已經發出了FIN,並且另一端也對它進行了確認。只有另一端的進程完成了這個關閉,我們這端才會從FIN_WAIT_2狀態進入TIME_WAIT狀態。這意味著我們這端可能永遠保持這個狀態,另一端也將處於CLOSE_WAIT狀態,並一直保持這個狀態直到應用層決定進行關閉。

9、復位報文段

TCP首部的RST位是用於復位的。一般,無論合適一個報文端發往相關的連接出現錯誤,TCP都會發出一個復位報文段。主要情況:

(1)到不存在的端口的連接請求;

(2)異常終止一個連接。

10、同時打開

為了處理同時打開,對於同時打開它僅建立一條連接而不是兩條連接。兩端幾乎在同時發送SYN,並進入SYN_SENT狀態。當每一端收到SYN時,狀態變為SYN_RCVD,同時他們都再發SYN並對收到的SYN進行確認。當雙方都收到SYN及相應的ACK時,狀態都變為ESTABLISHED。一個同時打開的連接需要交換4個報文段,比正常的三次握手多了一次。

11、 同時關閉

當應用層發出關閉命令,兩端均從ESTABLISHED變為FIN_WAIT_1。這將導致雙方各發送一個FIN,兩個FIN經過網絡傳送後分別到達另一端。收到FIN後,狀態由FIN_WAIT_1變為CLOSING,並發送最後的ACK。當收到最後的ACK,狀態變為TIME_WAIT。同時關閉和正常關閉的段減緩數目相同。

12、TCP選項

每個選項的開始是1字節的kind字段,說明選項的類型。

Kind=1:選項表結束(1字節)
   Kind=1:無操作(1字節)
   Kind=2:最大報文段長度(4字節)
   Kind=3:窗口擴大因子(4字節)
   Kind=8:時間戳(10字節)

三、TCP的超時和重傳

對於每個TCP連接,TCP管理4個不同的定時器。

(1) 重傳定時器用於當希望收到另一端的確認。

(2) 堅持定時器使窗口大小信息保持不斷流動,即使另一端關閉了其接收窗口。

(3) 保活定時器可檢測到一個空閒連接的另一端何時崩潰或重啟。

(4) 2MSL定時器測量一個連接處於TIME_WAIT狀態的時間。

1、往返時間測量

TCP超時和重傳重最重要的就是對一個給定連接的往返時間(RTT)的測量。由於路由器和網絡流量均會變化,因此TCP應該跟蹤這些變化並相應地改變超時時間。首先TCP必須測量在發送一個帶有特別序號地字節和接收到包含該字節地確認之間的RTT。

2、擁塞避免算法

該算法假定由於分組收到損壞引起的丟失是非常少的,因此分組丟失就意味著在源主機和目的主機之間的某處網絡上發生了阻塞。有兩種分組丟失的指示:發生超時和收到重復的確認。擁塞避免算法需要對每個連接維持兩個變量:一個擁塞窗口cwnd和一個慢啟動門限ssthresh。

(1) 對一個給定的連接,初始化cwnd為1個報文段,ssthresh為65535個字節。

(2) TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小。擁塞避免是發送方使用的流量控制。前者是發送方感受到的網絡擁塞的估計,而後者則與接收方在該連接上的可用緩存大小有關。

(3) 當擁塞發生時,ssthresh被設置為當前窗口大小的一般(cwnd和接收方通告窗口大小的最小值,但最小為2個報文段)。此外,如果是超時引起了擁塞,則cwnd被設置為1個報文段。

(4) 當新的數據被對方確認時,就增加cwnd,但增加的方法依賴與是否正在進行慢啟動或擁塞避免。如果cwnd小於或等於ssthresh,則正在進行慢啟動,否則正在進行擁塞避免。

3、快速重傳和快速恢復算法

如果我們一連串收到3個或以上的重復ACK,就非常可能是一個報文段丟失了。於是我們就重傳丟失的數據報文段,而無需等待超時定時器溢出。

(1) 當收到第3個重復的ACK時,將ssthresh設置為當前擁塞窗口cwnd的一半,重傳丟失的報文段,設置cwnd為ssthresh加上3倍的報文段大小。

(2) 每次收到另一個重復的ACK時,cwnd增加1個報文段大小並發送一個1個分組,如果允許的話。

(3) 當下一個確認新數據的ACK到達時,設置cwnd為ssthresh,這個ACK應該時在進行重傳後的一個往返時間內對步驟1重重傳的確認。另外,這個ACK也應該是對丟失的分組和收到的第一個重復的ACK之間的所有中間報文段的確認。

4、 ICMP差錯

TCP如何處理一個給定的連接返回的ICMP差錯。TCP能夠遇到的最常見的ICMP差錯就是源站抑制、主機不可達和網絡不可達。

(1) 一個接收到的源站抑制引起擁塞窗口cwnd被置為1個報文段大小來發起慢啟動,但是慢啟動門限ssthresh沒有變化,所以窗口將打開直到它開放了所有的通路或者發生了擁塞。

(2) 一個接收到的主機不可達或網絡不可達實際都被忽略,因為這兩個差錯都被認為是短暫現象。TCP試圖發送引起該差錯的數據,盡管最終有可能會超時。

5、重新分組:

當TCP超時並重傳時,它並不一定要重傳同樣的報文段,相反,TCP允許進行重新分組而發送一個較大的報文段。這是允許的,因為TCP是使用字節序號而不是報文段序號來進行識別它所要發送的數據和進行確認。

四、TCP的堅持定時器

ACK的傳輸並不可靠,也就是說,TCP不對ACK報文段進行確認,TCP只確認那些包含數據的ACK報文段。為了防止因為ACK報文段丟失而雙方進行等待的問題,發送方用一個堅持定時器來周期性地向接收方查詢。這些從發送方發出地報文段稱為窗口探查。

五、TCP的保活定時器

如果一個給定的連接在2小時內沒有任何動作,那麼服務器就向客戶發送一個探查報文段。客戶主機必須處於以下4個狀態之一。

(1) 客戶主機依然正常運行,並從服務器可達。客戶的TCP響應正常,而服務器也知道對方的正常工作的。服務器在2小時內將保活定時器復位。

(2) 客戶主機已經崩潰,並且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務器將不能收到對探查的響應,並在75秒後超時。總共發送10個探查,間隔75秒。

(3) 客戶主機崩潰並已經重新啟動。這是服務器將收到一個對其保活探查的響應,但這個響應是一個復位,使得服務器終止這個連接。

(4) 客戶主機正常運行,但是從服務器不可達。

六、TCP的一些性能

1、 路徑MTU發現:

TCP的路徑MTU發現按如下方式進行:在連接建立時,TCP使用輸出接口或對段聲明的MSS中的最下MTU作為其實的報文段大小。路徑MTU發現不允許TCP超過對端聲明的MSS。如果對端沒有指定一個MSS,則默認為536。

一旦選定了起始的報文段大小,在該連接上的所有被TCP發送的IP數據報都將被設置DF位。如果中間路由器需要對一個設置了DF標志的數據報進行分片,它就丟棄這個數據報,並產生一個ICMP的“不能分片”差錯。

如果收到這個ICMP差錯,TCP就減少段大小並進行重傳。如果路由器產生的是一個較新的該類ICMP差錯,則報文段大小被設置位下一跳的MTU減去IP和TCP的首部長度。如果是一個較舊的該類ICMP差錯,則必須嘗試下一個可能的最小MTU。

2、 長肥管道

一個連接的容量=帶寬X時延(RTT)。具有大的帶寬時延乘積的網絡稱為長肥網絡(LFN)。一個運行在LFN的TCP連接稱為長肥管道。管道可以被水平拉長(一個長的RTT),或被垂直拉高(較高的帶寬),或兩個方向拉伸。

3、窗口擴大選項:

窗口擴大選項使TCP的窗口定義從16位增加到32位,這並不是通過修改TCP首部來實現的,TCP首部仍然使用16位,而是通過定義一個選項實現對16位的擴大操作來完成的。

4、時間戳選項:

時間戳選項使發送方在每個報文段中放置一個時間戳值。接收方在確認中返回這個數值,從而允許發送方為每一個收到的ACK計算RTT。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved