TCP-UDP協議

TCP

TCP 的特性

CP 提供一種面向連接的、可靠的字節流服務
在一個 TCP 連接中,僅有兩方進行彼此通信。廣播和多播不能用於 TCP
TCP 使用校驗和,確認和重傳機制來保證可靠傳輸
TCP 給數據分節進行排序,並使用累積確認保證數據的順序不變和非重複
TCP 使用滑動窗口機制來實現流量控制,通過動態改變窗口的大小進行擁塞控制

注意:TCP 並不能保證數據一定會被對方接收到,因爲這是不可能的。TCP 能夠做到的是,如果有可能,就把數據遞送到接收方,否則就(通過放棄重傳並且中斷連接這一手段)通知用戶。因此準確說 TCP 也不是 100% 可靠的協議,它所能提供的是數據的可靠遞送或故障的可靠通知。

三次握手與四次揮手

在這裏插入圖片描述
所謂三次握手(Three-way Handshake),是指建立一個 TCP 連接時,需要客戶端和服務器總共發送3個包。

三次握手的目的是連接服務器指定端口,建立 TCP 連接,並同步連接雙方的序列號和確認號,交換 TCP 窗口大小信息。在 socket 編程中,客戶端執行 connect() 時。將觸發三次握手。

第一次握手(SYN=1, seq=x):

客戶端發送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算連接的服務器的端口,以及初始序號 X,保存在包頭的序列號(Sequence Number)字段裏。

發送完畢後,客戶端進入 SYN_SEND 狀態。

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):

服務器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均爲1。服務器端選擇自己 ISN 序列號,放到 Seq 域裏,同時將確認序號(Acknowledgement Number)設置爲客戶的 ISN 加1,即X+1。 發送完畢後,服務器端進入 SYN_RCVD 狀態。

第三次握手(ACK=1,ACKnum=y+1)

客戶端再次發送確認包(ACK),SYN 標誌位爲0,ACK 標誌位爲1,並且把服務器發來 ACK 的序號字段+1,放在確定字段中發送給對方,並且在數據段放寫ISN的+1

發送完畢後,客戶端進入 ESTABLISHED 狀態,當服務器端接收到這個包時,也進入 ESTABLISHED 狀態,TCP 握手結束。
在這裏插入圖片描述

TCP 的連接的拆除需要發送四個包,因此稱爲四次揮手(Four-way handshake),也叫做改進的三次握手。客戶端或服務器均可主動發起揮手動作,在 socket 編程中,任何一方執行 close() 操作即可產生揮手操作。

第一次揮手(FIN=1,seq=x)

假設客戶端想要關閉連接,客戶端發送一個 FIN 標誌位置爲1的包,表示自己已經沒有數據可以發送了,但是仍然可以接受數據。

發送完畢後,客戶端進入 FIN_WAIT_1 狀態。

第二次揮手(ACK=1,ACKnum=x+1)

服務器端確認客戶端的 FIN 包,發送一個確認包,表明自己接受到了客戶端關閉連接的請求,但還沒有準備好關閉連接。

發送完畢後,服務器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包之後,進入 FIN_WAIT_2 狀態,等待服務器端關閉連接。

第三次揮手(FIN=1,seq=y)

服務器端準備好關閉連接時,向客戶端發送結束連接請求,FIN 置爲1。

發送完畢後,服務器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個ACK。

第四次揮手(ACK=1,ACKnum=y+1)

客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入 TIME_WAIT狀態,等待可能出現的要求重傳的 ACK 包。

服務器端接收到這個確認包之後,關閉連接,進入 CLOSED 狀態。

客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到服務器端的 ACK ,認爲服務器端已經正常關閉連接,於是自己也關閉連接,進入 CLOSED 狀態。

SYN攻擊

什麼是 SYN 攻擊(SYN Flood)?

在三次握手過程中,服務器發送 SYN-ACK 之後,收到客戶端的 ACK 之前的 TCP 連接稱爲半連接(half-open connect)。此時服務器處於 SYN_RCVD 狀態。當收到 ACK 後,服務器才能轉入 ESTABLISHED 狀態.

SYN 攻擊指的是,攻擊客戶端在短時間內僞造大量不存在的IP地址,向服務器不斷地發送SYN包,服務器回覆確認包,並等待客戶的確認。由於源地址是不存在的,服務器需要不斷的重發直至超時,這些僞造的SYN包將長時間佔用未連接隊列,正常的SYN請求被丟棄,導致目標系統運行緩慢,嚴重者會引起網絡堵塞甚至系統癱瘓。

SYN 攻擊是一種典型的 DoS/DDoS 攻擊。

如何檢測 SYN 攻擊?

檢測 SYN 攻擊非常的方便,當你在服務器上看到大量的半連接狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊。在 Linux/Unix 上可以使用系統自帶的 netstats 命令來檢測 SYN 攻擊。

如何防禦 SYN 攻擊?

SYN攻擊不能完全被阻止,除非將TCP協議重新設計。我們所做的是儘可能的減輕SYN攻擊的危害,常見的防禦 SYN 攻擊的方法有如下幾種:

縮短超時(SYN Timeout)時間
增加最大半連接數
過濾網關防護
SYN cookies技術

TCP KeepAlive

TCP 的連接,實際上是一種純軟件層面的概念,在物理層面並沒有“連接”這種概念。TCP 通信雙方建立交互的連接,但是並不是一直存在數據交互,有些連接會在數據交互完畢後,主動釋放連接,而有些不會。在長時間無數據交互的時間段內,交互雙方都有可能出現掉電、死機、異常重啓等各種意外,當這些意外發生之後,這些 TCP 連接並未來得及正常釋放,在軟件層面上,連接的另一方並不知道對端的情況,它會一直維護這個連接,長時間的積累會導致非常多的半打開連接,造成端系統資源的消耗和浪費,爲了解決這個問題,在傳輸層可以利用 TCP 的 KeepAlive 機制實現來實現。主流的操作系統基本都在內核裏支持了這個特性。

TCP KeepAlive 的基本原理是,隔一段時間給連接對端發送一個探測包,如果收到對方迴應的 ACK,則認爲連接還是存活的,在超過一定重試次數之後還是沒有收到對方的迴應,則丟棄該 TCP 連接。

TCP-Keepalive-HOWTO 有對 TCP KeepAlive 特性的詳細介紹,有興趣的同學可以參考。這裏主要說一下,TCP KeepAlive 的侷限。首先 TCP KeepAlive 監測的方式是發送一個 probe 包,會給網絡帶來額外的流量,另外 TCP KeepAlive 只能在內核層級監測連接的存活與否,而連接的存活不一定代表服務的可用。例如當一個服務器 CPU 進程服務器佔用達到 100%,已經卡死不能響應請求了,此時 TCP KeepAlive 依然會認爲連接是存活的。因此 TCP KeepAlive 對於應用層程序的價值是相對較小的。需要做連接保活的應用層程序,例如 QQ,往往會在應用層實現自己的心跳功能。

UDP 簡介

UDP 是一個簡單的傳輸層協議。和 TCP 相比,UDP 有下面幾個顯著特性:

UDP 缺乏可靠性。UDP 本身不提供確認,序列號,超時重傳等機制。UDP 數據報可能在網絡中被複制,被重新排序。即 UDP 不保證數據報會到達其最終目的地,也不保證各個數據報的先後順序,也不保證每個數據報只到達一次
UDP 數據報是有長度的。每個 UDP 數據報都有長度,如果一個數據報正確地到達目的地,那麼該數據報的長度將隨數據一起傳遞給接收方。而 TCP 是一個字節流協議,沒有任何(協議上的)記錄邊界。
UDP 是無連接的。UDP 客戶和服務器之前不必存在長期的關係。UDP 發送數據報之前也不需要經過握手創建連接的過程。
UDP 支持多播和廣播。

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