天天看點

TCP簡介

版權聲明:本文為部落客原創文章,轉載請注明部落格位址: https://blog.csdn.net/zy010101/article/details/86613500

TCP是Transmission Control Protocol的縮寫。他是一種面向有連接配接,可靠的傳輸層協定。

TCP是全雙工的通信方式。TCP将應用層傳遞給它的資料包會進行分組,形成一個個小的資料包。

與UDP不同,TCP是“名副其實”的,它确實是對通信進行有力的控制的協定。可以在丢包時進行重發,可以對次序混亂的包排序。當然,它的面向連接配接的特性,還可以讓它在确定對端确實存在的情況下才發送資料,是以它也能控制通信流量。

在TCP中,當發送端發送的資料成功到達接收端主機的時候,接收端主機會傳回一個已收到消息的通知給發送端。這個消息叫做确認應答(ACK)。TCP就是通過ACK來實作可靠傳輸的。如果發送端在一段時間内沒有等到ACK,那麼就認為資料已經丢失,會進行重發。是以,即使在TCP傳輸過程中産生了丢包,仍舊能夠保證資料的可靠傳輸。

當然,有時候接收端确實收到了資料,并且傳回了ACK,但是發送端并未得到這個ACK(這個ACK在應答途中丢失了),那麼發送端仍舊會重發資料包。當然還有情況,例如,ACK最終到達了發送端,但是是逾時到達。這種情況下,發送端仍舊會重發資料包。以上這種接收端确實收到了,但是發送端仍舊進行了多次發送的情況對于接收端而言是非常糟糕的。它不僅浪費了流量去接受資料包,而且還需要丢掉重複的包。為此,TCP又引入了一種機制,它能夠識别是否已經接受了資料,以及判斷是否需要接受。

序列号:按照順序給發送資料的每一個位元組都标上的号碼就是序列号。(初始序列号是随機生成的,之後的每一個序列号比前一個序列号大1)

接收端通過查詢資料包的TCP首部中的序列号和資料長度,将自己下一步應該接受的序号作為ACK返送回去。這樣TCP就能實作可靠傳輸。

那麼問題就是如何确定這個重發逾時的時間長短。理想情形下,應該是找到一個最小的時間,他能保證“确認應答一定能在這個時間内傳回”。是以,這個時間就是一個随着網絡環境不同而不同的值。在網絡環境良好的情形下,它肯定所需要的時間段,在網絡擁塞的情形下,需要的時間長。

但是,TCP要求盡量提供一個高性能的通信。為此,在每次發包時都會計算往返時間及其偏差。重發逾時的時間比這個時間大一點即可。偏差是因為網絡環境不是一個穩定的,它是會變化的。是以往返時間會有一個波動,導緻産生偏差。但是TCP要求盡量不去浪費網絡流量。在BSDUnix和Windows下,一般逾時以0.5秒作為一個機關。是以重發逾時是0.5的倍數。不過,由于最初的資料包不知道往返時間,是以一般設定為6s。資料包在多次重發以後,如果仍舊沒有收到接收端的确認應答(ACK),就判定網絡或者接收端出現異常,強制關閉連接配接,并且通知應用通信異常強行終止。

TCP是面向有連接配接的服務,它在通信正式開始之前,通過TCP首部發送一個SYN包,作為建立連接配接的請求,并等待确認應答。若果等到了确認應答,說明連接配接建立,否則認為連接配接未建立。在通信終止的時候,也會發送FIN包來确認終止連接配接。一般而言,TCP連接配接的建立與斷開需要來回收發7個包才行。

在建立TCP連接配接的過程中,也可以确定收發資料包的大小(MSS),理想情形下,資料正好是IP中不會被分開處理的最大長度。MSS是在三次握手的時候,被通信雙方計算出來的。

TCP以一個段為機關,每發一段進行一次确認應答。這種方式的缺點在于,若通信往返時間過長,那麼通信效率越低。為了解決這個問題,TCP引入了視窗,用它來控制效率的下降。視窗的大小就是無需等待确認應答能發送的資料最大值。這個機制使用了大量的緩沖區,實作對多個段的同時确認應答。(這個滑動視窗機制和CPU的流水線指令設計的想法是類似的)。滑動視窗的引入在一定程度上減少了部分資料包的重發,假設現在序号為1000的資料包的ACK在傳輸途中丢失了,但是2000的序号被發送端接受了,那麼發送端就不會再去重發序号為1000的資料包了。如果丢失某一段封包,接收端會提醒發送端重發,但是在視窗較大的時候,接收端會不斷提醒發送端,當3次提醒以後,發送端就會重發。

還需要考慮的一個問題是發送端和接收端的收發速率比對問題。如果出現發送端的發的太快,緩沖區存不下這種情況,接收端還是會請求發送端重發。這就導緻網絡流量的浪費。為此,TCP提供了流控制來讓發送端根據接收端的實際能力控制發送的資料量。那就是接收端會告訴發送端自己可以接受的資料的大小。這個大小就視窗的大小。在TCP首部中專門有一個字段來存儲視窗大小。這個視窗的大小不是不變的,他會随着接收端的情況而不斷變。例如接收端滿緩存的情形下,視窗的大小就會變成0。這個視窗大小的更新如果在傳輸途中遺失,那麼通信就無法進行,是以,為了避免發生這種情況。發送端會隔一段時間發送一個視窗探測的資料段(僅僅隻有一個位元組)來更新視窗大小。

擁塞控制,在TCP剛開始的時候會通過一個慢啟動的算法來進行發送資料的控制。是以TCP的網絡吞吐量看起來就是在逐漸占領網絡帶寬的感覺。