TCP協議入門

TCP是一種面向連接的、可靠的、基於IP的傳輸層協議。TCP是一個超級麻煩的協議,而它又是互聯網的基礎,也是每個程序員必備的基本功。

TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接(連接導向)的、可靠的、 基於IP的傳輸層協議。TCP在IP報文的協議號是6。TCP是一個超級麻煩的協議,而它又是互聯網的基礎,也是每個程序員必備的基本功。首先來看看OSI的七層模型:

這裏寫圖片描述

我們需要知道TCP工作在網絡OSI的七層模型中的第四層——Transport層,IP在第三層——Network層,ARP 在第二層——Data Link層;在第二層上的數據,我們把它叫Frame,在第三層上的數據叫Packet,第四層的數 據叫Segment。 同時,我們需要簡單的知道,數據從應用層發下來,會在每一層都會加上頭部信息,進行 封裝,然後再發送到數據接收端。這個基本的流程你需要知道,就是每個數據都會經過數據的封裝和解封 裝的過程。 在OSI七層模型中,每一層的作用和對應的協議如下:

這裏寫圖片描述

TCP是一個協議,那這個協議是如何定義的,它的數據格式是什麼樣子的呢?要進行更深層次的剖析,就 需要了解,甚至是熟記TCP協議中每個字段的含義。哦,來吧。

這裏寫圖片描述

上面就是TCP協議頭部的格式,由於它太重要了,是理解其它內容的基礎,下面就將每個字段的信息都詳 細的說明一下。
Source Port和Destination Port:分別佔用16位,表示源端口號和目的端口號;用於區別主機中的不同進程, 而IP地址是用來區分不同的主機的,源端口號和目的端口號配合上IP首部中的源IP地址和目的IP地址就能唯一 的確定一個TCP連接;
Sequence Number:用來標識從TCP發端向TCP收端發送的數據字節流,它表示在這個報文段中的的第一個數據 字節在數據流中的序號;主要用來解決網絡報亂序的問題;
Acknowledgment Number:32位確認序列號包含發送確認的一端所期望收到的下一個序號,因此,確認序號應 當是上次已成功收到數據字節序號加1。不過,只有當標誌位中的ACK標誌(下面介紹)爲1時該確認序列號的字 段纔有效。主要用來解決不丟包的問題;
Offset:給出首部中32 bit字的數目,需要這個值是因爲任選字段的長度是可變的。這個字段佔4bit(最多能 表示15個32bit的的字,即4*15=60個字節的首部長度),因此TCP最多有60字節的首部。然而,沒有任選字段, 正常的長度是20字節;
TCP Flags:TCP首部中有6個標誌比特,它們中的多個可同時被設置爲1,主要是用於操控TCP的狀態機的,依次 爲URG,ACK,PSH,RST,SYN,FIN。每個標誌位的意思如下:
URG:此標誌表示TCP包的緊急指針域(後面馬上就要說到)有效,用來保證TCP連接不被中斷,並且督促 中間層設備要儘快處理這些數據;
ACK:此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP數據包中;有兩個取值:0和1, 爲1的時候表示應答域有效,反之爲0;
PSH:這個標誌位表示Push操作。所謂Push操作就是指在數據包到達接收端以後,立即傳送給應用程序, 而不是在緩衝區中排隊;
RST:這個標誌表示連接復位請求。用來複位那些產生錯誤的連接,也被用來拒絕錯誤和非法的數據包;
SYN:表示同步序號,用來建立連接。SYN標誌位和ACK標誌位搭配使用,當連接請求的時候,SYN=1, ACK=0;連接被響應的時候,SYN=1,ACK=1;這個標誌的數據包經常被用來進行端口掃描。掃描者發送 一個只有SYN的數據包,如果對方主機響應了一個數據包回來 ,就表明這臺主機存在這個端口;但是由於這 種掃描方式只是進行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全 的主機將會強制要求一個連接嚴格的進行TCP的三次握手;
FIN: 表示發送端已經達到數據末尾,也就是說雙方的數據傳送完成,沒有數據可以傳送了,發送FIN標誌 位的TCP數據包後,連接將被斷開。這個標誌的數據包也經常被用於進行端口掃描。
Window:窗口大小,也就是有名的滑動窗口,用來進行流量控制;這是一個複雜的問題,這篇博文中並不會進行 總結的;
好了,基本知識都已經準備好了,開始下一段的征程吧。

三次握手又是什麼?

TCP是面向連接的,無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。在TCP/IP協議中,TCP 協議提供可靠的連接服務,連接是通過三次握手進行初始化的。三次握手的目的是同步連接雙方的序列號和確認號 並交換 TCP窗口大小信息。這就是面試中經常會被問到的TCP三次握手。只是瞭解TCP三次握手的 概念,對你獲得一份工作是沒有任何幫助的,你需要去了解TCP三次握手中的一些細節。先來看圖說話。

這裏寫圖片描述

多麼清晰的一張圖,當然了,也不是我畫的,我也只是引用過來說明問題了。
1.第一次握手:建立連接。客戶端發送連接請求報文段,將SYN位置爲1,Sequence Number爲x;然後,客戶端進入SYN_SEND狀態,等待服務器的確認;
2.第二次握手:服務器收到SYN報文段。服務器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設置Acknowledgment Number爲x+1(Sequence Number+1);同時,自己自己還要發送SYN請求信息,將SYN位置爲1,Sequence Number爲y;服務器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一併發送給客戶端,此時服務器進入SYN_RECV狀態;
3.第三次握手:客戶端收到服務器的SYN+ACK報文段。然後將Acknowledgment Number設置爲y+1,向服務器發送ACK報文段,這個報文段發送完畢以後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。
完成了三次握手,客戶端和服務器端就可以開始傳送數據。以上就是TCP三次握手的總體介紹。

那四次分手呢?

當客戶端和服務器通過三次握手建立了TCP連接以後,當數據傳送完畢,肯定是要斷開TCP連接的啊。那對於TCP的斷開連接,這裏就有了神祕的“四次分手”。
1.第一次分手:主機1(可以使客戶端,也可以是服務器端),設置Sequence Number和Acknowledgment Number,向主機2發送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有數據要發送給主機2了;
2.第二次分手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number爲Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我也沒有數據要發送了,可以進行關閉連接了;
3.第三次分手:主機2向主機1發送FIN報文段,請求關閉連接,同時主機2進入CLOSE_WAIT狀態;
4.第四次分手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連接;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連接了。
至此,TCP的四次分手就這麼愉快的完成了。當你看到這裏,你的腦子裏會有很多的疑問,很多的不懂,感覺很凌亂;沒事,我們繼續總結。

爲什麼要三次握手?

既然總結了TCP的三次握手,那爲什麼非要三次呢?怎麼覺得兩次就可以完成了。那TCP爲什麼非要進行三次連接呢?在謝希仁的《計算機網絡》中是這樣說的:
爲了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。
在書中同時舉了一個例子,如下:
“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,
而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達server。本來這是一
個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認爲是client再次發出的一個新
的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用“三次握手”,那麼只要server
發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,
也不會向server發送數據。但server卻以爲新的運輸連接已經建立,並一直等待client發來數據。這樣,
server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛纔那種情況,
client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。”
這就很明白了,防止了服務器端的一直等待而浪費資源。

爲什麼要四次分手?

那四次分手又是爲何呢?TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP是全雙工 模式,這就意味着,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2, 它的數據已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的數據;當主機2返回ACK報文 段時,表示它已經知道主機1沒有數據發送了,但是主機2還是可以發送數據到主機1的;當主機2也發送了FIN 報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,之後彼此 就會愉快的中斷這次TCP連接。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態變化。
FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等 待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時, 它想主動關閉連接,向對方發送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方迴應ACK報 文後,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK 報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。 (主動方)
FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連接,也即 有一方要求close連接,但另外還告訴對方,我暫時還有點數據需要傳送給你(ACK信息),稍後再關閉連接。 (主動方)
CLOSE_WAIT:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後發送FIN 報文給自己,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實 際上你真正需要考慮的事情是察看你是否還有數據發送給對方,如果沒有的話,那麼你也就可以 close這個 SOCKET,發送FIN報文給對方,也即關閉連接。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關 閉連接。(被動方)
LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在發送FIN報文後,最後等待對方的ACK報 文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)
TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。 如果FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無 須經過FIN_WAIT_2狀態。(主動方)
CLOSED: 表示連接中斷。

握手過程中傳送的包裏不包含數據,三次握手完畢後,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。斷開連接時服務器和客戶端均可以主動發起斷開TCP連接的請求,

轉載自:http://network.51cto.com/art/201411/456783.htm




Socket連接與HTTP連接

我們在傳輸數據時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別數據內容,如果想要使傳輸的數據有意義,則必須使用到應用層協議,應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。WEB使用HTTP協議作應用層協議,以封裝HTTP文本信息,然後使用TCP/IP做傳輸層協議將它發到網絡上。

1)

Socket是一個針對TCP和UDP編程的接口,你可以藉助它建立TCP連接等等。而TCP和UDP協議屬於傳輸層 。
而http是個應用層的協議,它實際上也建立在TCP協議之上。

(HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。)

2)

Socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用接口(API),通過Socket,我們才能使用TCP/IP協議。Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,從而形成了我們知道的一些最基本的函數接口。

利用Socket建立網絡連接的步驟

建立Socket連接至少需要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另一個運行於服務器端,稱爲ServerSocket 。

套接字之間的連接過程分爲三個步驟:服務器監聽,客戶端請求,連接確認。

1。服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。

2。客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端套接字提出連接請求。

3。連接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

TCP和UDP的區別

1。TCP是面向鏈接的,雖然說網絡的不安全不穩定特性決定了多少次握手都不能保證連接的可靠性,但TCP的三次握手在最低限度上(實際上也很大程度上保證了)保證了連接的可靠性;而UDP不是面向連接的,UDP傳送數據前並不與對方建立連接,對接收到的數據也不發送確認信號,發送端不知道數據是否會正確接收,當然也不用重發,所以說UDP是無連接的、不可靠的一種數據傳輸協議。

2。也正由於1所說的特點,使得UDP的開銷更小數據傳輸速率更高,因爲不必進行收發數據的確認,所以UDP的實時性更好。

知道了TCP和UDP的區別,就不難理解爲何採用TCP傳輸協議的MSN比採用UDP的QQ傳輸文件慢了,但並不能說QQ的通信是不安全的,因爲程序員可以手動對UDP的數據收發進行驗證,比如發送方對每個數據包進行編號然後由接收方進行驗證啊什麼的,即使是這樣,UDP因爲在底層協議的封裝上沒有采用類似TCP的“三次握手”而實現了TCP所無法達到的傳輸效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章