基礎網絡概念(五)TCP/IP傳輸層相關封包與數據、TCP三次握手

聲明:本文爲筆者複習計算機網絡相關知識時的摘錄,文章中的圖片及語句均出自《鳥哥的Linux私房菜》,這裏僅作爲整理自用。

喜歡鳥哥文章的朋友可以到鳥哥的主頁查看:http://linux.vbird.org/


TCP/IP 的傳輸層相關封包與數據
網絡層的 IP 封包只負責將數據送到正確的目標主機去,但這個封包到底會不會被接受,或者是有沒有被正確的接收,  那就不是 IP 的任務啦!那是傳送層的任務之一。

2.4.1 可靠聯機的 TCP 協議
在網絡層的 IP 之上則是傳送層,而傳送層的數據打包成什麼? 最常見的就是 TCP 封包了。這個 TCP 封包數據必須要能夠放到 IP 的數據袋當中纔行!將 MAC, IP 與 TCP 的封包數據這樣看:


想當然爾,TCP 也有表頭數據來記錄該封包的相關信息囉?沒錯啦~ TCP 封包的表頭是長這個樣子的:



上圖就是一個 TCP 封包的表頭數據,各個項目以 Source Port, Destination Port 及 Code 算是比較重要的項目。

Source Port & Destination Port (來源端口 & 目標端口)什麼是埠口(port)?我們知道 IP 封包的傳送主要是藉由 IP 地址連接兩端,但是到底這個聯機的通道是連接到哪裏去呢?沒錯!就是連接到 port 上頭啦!舉例來說,鳥哥的網站有開放 WWW 服務器,這表示鳥站的主機必須要啓動一個可以讓 client 端連接的端口,這個端口就是 port (中文翻譯成爲埠口)。同樣的,客戶端想要連接到鳥哥的鳥站時,就必須要在 client 主機上面啓動一個port ,這樣這兩個主機才能夠利用這條『通道』來傳遞封包數據喔!這個目標與來源 port 的紀錄,可以說是 TCP 封包上最重要的參數了!

Code (Control Flag, 控制標誌碼)
當我們在進行網絡聯機的時候,必須要說明這個聯機的狀態,好讓接收端了解這個封包的主要動作。  這可是一個非常重要的句柄喔!這個字段共有 6 個 bits ,分別代表 6 個句柄,若爲 1 則爲啓動。分別說明如下: 
URG(Urgent):若爲 1 則代表該封包爲緊急封包, 接收端應該要緊急處理,且圖 2.4-1 當中的 Urgent Pointer 字段也會被啓用。
o    ACK(Acknowledge):若爲 1 代表這個封包爲響應封包,  則與上面提到的 Acknowledge Number 有關。
o    PSH(Push function):若爲 1 時,代表要求對方立即傳送緩衝區內的其他對應封包,而無須等待緩衝區滿了才送。 
o    RST(Reset):如果 RST 爲 1 的時候,表示聯機會被馬上結束,而無需等待終止確認手續。這也就是說, 這是個強制結束的聯機,且發送端已斷線。
o    SYN(Synchronous):若爲 1,表示發送端希望雙方建立同步處理,  也就是要求建立聯機。通常帶有 SYN 標誌的封包表示『主動』要連接到對方的意思。
o    FIN(Finish):若爲 1 ,表示傳送結束,所以通知對方數據傳畢,  是否同意斷線,只是發送者還在等待對方的響應而已。

其實每個項目都很重要,不過我們這裏僅對 ACK/SYN 有興趣而已,這樣未來在談到防火牆的時候,你纔會比較清楚爲啥每個 TCP 封包都有所謂的『狀態』條件!那就是因爲聯機方向的不同所致啊


通訊端口口
在上圖的 TCP 表頭數據中,最重要的就屬那 16 位的兩個咚咚,亦即來源與目標的端口口。由於是 16 位,因此目標與來源端口口最大可達 65535 號 (2 的 16 次方)!那這個埠口有什麼用途呢?上面稍微提到過,網絡是雙向的,服務器與客戶端要達成聯機的話, 兩邊應該要有一個對應的埠口來達成聯機信道,好讓數據可以透過這個信道來進行溝通。
那麼這個埠口怎麼打開呢?就是透過程序的執行!舉例來說,鳥哥的網站上,必須要啓動一個 WWW 服務器軟件, 這個服務器軟件會主動的喚起 port 80 來等待客戶端的聯機。你想要看我網站上的數據,就得要利用瀏覽器, 填入網址,然後瀏覽器也會啓動一個埠口,並將 TCP 的表頭填寫目標端口口爲 80 ,而來源端口口是你主機隨機啓動的一個埠口,  然後將 TCP 封包封裝到 IP 後,送出到網絡上。等鳥站主機接收到
你這個封包後,再依據你的埠口給予迴應。
這麼說你或許不好理解,我們換個說法好了。假如 IP 是網絡世界的門牌,那麼這個埠口就是那個門牌號碼上建築物的樓層!  每個建築物都有 1~65535 層樓,你需要什麼網絡服務,就得要去該對應的樓層取得正確的資料。但那個樓層裏面有沒有人在服務你呢? 這就得要看有沒有程序真的在執行啦。所以,IP 是門牌, TCP 是樓層,真正提
供服務的, 是在該樓層的那個人 (程序)!
Tips:
曾經有一個朋友問過我說:『一部主機上面這麼多服務,那我們跟這部主機進行聯機時,該主機怎麼知道我們要的數據是 WWW 還是FTP 啊?』就是透過埠口啊!因爲每種 Client 軟件他們所需要的數據都不相同,例如上面提到的瀏覽器所需要的數據是 WWW ,所以該軟件默認就會向服務器的 port 80 索求數據;而如果你是使用filezilla 來進行與服務器的 FTP 數據索求時, filezilla 當然預設就是向服務器的 FTP 相關埠口 (預設就是 port 21) 進行連接的動作啦!所以當然就可以正確無誤的取得 Client 端所需要的數據了。再舉個例子來說,一部主機就好像是一間多功能銀行,該銀行內的每個負責不同業務的窗口就好像是通訊端口口,  而我們民衆就好像是 Client 端來的封包。當你進入銀行想要繳納信用卡賬單時,  一到門口服務人員就會指示你直接到該窗口去繳納,當然,如果你是要領錢,服務人員就會請你到領錢的窗口去填寫數據,  你是不會跑錯的對吧! ^_^。萬一跑錯了怎麼辦?呵呵!當然該窗口就會告訴你『我不負責這個業務,你請回去!』, 呵呵!所以該次的聯機就會『無法成功』咯!

特權埠口 (Privileged Ports)
你現在瞭解了埠口的意義後,再來想想,網絡既然是雙向的,一定有一個發起端。問題是,到底要聯機到服務器取得啥玩意兒? 也就是說,哪支程序應該在哪個端口口執行,以讓大家都知道該埠口就是提供哪個服務,如此一來,纔不會造成廣大用戶的困擾嘛!  所以囉, Internet 上面已經有很多規範好的固定 port (well-known port),  這些 port number 通常小於 1024 ,且是提供給許多知名的網絡服務軟件用的。 在我們的 Linux 環境下,各網絡服務與port number 的對應默認給他寫在 /etc/services 檔案內喔! 底下鳥哥列出幾個常見的 port number 與網絡服務的對應:


另外一點比較值得注意的是,小於 1024 以下的埠口要啓動時, 啓動者的身份必須要是 root 纔行,所以才叫做特權埠口嘛!這個限制挺重要的,大家不要忘記了喔!不過如果是 client 端的話,由於 client 端都是主動向 server 端要數據, 所以client 端的 port number 就使用隨機取一個大於 1024 以上且沒有在用的 port number

Socket Pair
由於網絡是雙向的,要達成聯機的話得要服務器與客戶端均提供了 IP 與埠口才行。因此,我們常常將這個成對的數據稱之爲 Socket Pair 了! 
    來源 IP + 來源埠口 (Source Address + Source Port)
    目的 IP + 目的埠口 (Destination Address + Destination Port)
由於 IP 與埠口常常連在一起說明,因此網絡尋址常常使用『 IP:port 』來說明,例如想要連上鳥哥的網站時,  正確的鳥哥網站寫法應該是:『 linux.vbird.org:80 』纔對!

2.4.2 TCP 的三向交握
TCP 被稱爲可靠的聯機封包,主要是透過許多機制來達成的,其中最重要的就是三向交握的功能。 那麼如何藉由 TCP 的表頭來確認這個封包有實際被對方接收,並進一步與對方主機達成聯機? 我們以底下的圖示來作爲說明。


在上面的封包連接模式當中,在建立聯機之前都必須要通過三個確認的動作, 所以這種聯機方式也就被稱爲三向交握(Three-way handshake)。  那麼我們將整個流程依據上面的 A, B, C, D 四個階段來說明一下:
    A:封包發起
當客戶端想要對服務器端聯機時,就必須要送出一個要求聯機的封包,此時客戶端必須隨機取用一個大於 1024 的端口來做爲程序溝通的接口。然後在TCP 的表頭當中,必須要帶有 SYN 的主動聯機(SYN=1),並且記下發送出聯機封
包給服務器端的序號 (Sequence number = 10001) 。 
    B:封包接收與確認封包傳送
當服務器接到這個封包,並且確定要接收這個封包後,就會開始製作一個同時帶有 SYN=1, ACK=1 的封包,  其中那個 acknowledge 的號碼是要給 client 端確認用的,所以該數字會比(A 步驟)裏面的 Sequence 號碼多一號 (ack = 10001+1 = 10002), 那我們服務器也必須要確認客戶端確實可以接收我們的封包纔行,所以也會發送出一個 Sequence (seq=20001) 給客戶端,並且開始等待客戶端給我們服務器端的迴應喔!
    C:回送確認封包
當客戶端收到來自服務器端的 ACK 數字後 (10002) 就能夠確認之前那個要求封包被正確的收受了, 接下來如果客戶端也同意與服務器端建立聯機時,就會再次的發送一個確認封包 (ACK=1) 給服務器,亦即是 acknowledge = 20001+1 = 20002 囉。
    D:取得最後確認
若一切都順利,在服務器端收到帶有 ACK=1 且 ack=20002 序號的封包後,就能夠建立起這次的聯機了。
也就是說,你必須要瞭解『網絡是雙向的』這個事實! 所以不論是服務器端還是客戶端,都必須要透過一次 SYN 與 ACK 來建立聯機,所以總共會進行三次的交談!  在設定防火牆或者是追蹤網絡聯機的問題時,這個『雙向』的概念最容易被忽略, 而常常導致無法聯機成功的問題啊!切記切記!
Tips:
鳥哥上課談到 TCP 最常做的事就是,叫一個同學起來,實際表演三
向交握給大家看!
1. 鳥哥說:A 同學你在不在?
2. A 同學說:我在!那鳥哥你在不在?
3. 鳥哥說:我也在
此時兩個人就確認彼此都可以聽到對方在講啥,這就是可靠聯機啦!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章