TCP是一個十分複雜的協議,經過前面幾篇文章只涉及了TCP協議中一些基本的概念。html
雖說都是一些TCP最基本的概念,可是試驗過程當中一直在踩坑,例如:TCP flag設置錯誤,seq、ack號沒有計算正確,TCP狀態變遷錯誤等等。算法
經過Pcap.Net真正實驗一下才發現了不少TCP協議中要注意的細節,例如:Ack、Seq號的計算,EthernetLayer、IpV4Layer 、TcpLayer的層層包裝,不一樣TCP flags的含義等等。服務器
TCP中還有不少重要的內容,先作個記錄,後面再深刻了解。網絡
動手學習TCP:客戶端狀態變遷server
動手學習TCP:TCP特殊狀態blog
下面就對前面幾篇文章中涉及到的TCP知識的進行簡單的彙總。
TCP首部
TCP鏈接創建和終止
三次握手
四次揮手
網絡上的傳輸是沒有鏈接的,包括TCP也是同樣的。TCP所謂的"鏈接",實際上是在通信的雙方維護一個"鏈接狀態",讓它看上去好像有鏈接同樣。
TCP狀態機的所有11種狀態中:
客戶端狀態變遷
From State |
To State |
Recv Packet |
Send Packet |
CLOSED |
SYN_SENT |
- |
[SYN] |
SYN_SENT |
ESTABLISHED |
[SYN, ACK] |
[ACK] |
ESTABLISHED |
FIN_WAIT_1 |
- |
[FIN, ACK] |
FIN_WAIT_1 |
FIN_WAIT_2 |
[ACK] |
- |
FIN_WAIT_2 |
TIME_WAIT |
[FIN, ACK] |
[ACK] |
TIME_WAIT |
CLOSED |
- |
- |
服務器狀態變遷
From State |
To State |
Recv Packet |
Send Packet |
CLOSED |
LISTEN |
- |
- |
LISTEN |
SYN_RCVD |
[SYN] |
[SYN, ACK] |
SYN_RCVD |
ESTABLISHED |
[ACK] |
- |
ESTABLISHED |
CLOSE_WAIT |
[FIN, ACK] |
[ACK] |
CLOSE_WAIT |
LAST_ACK |
- |
[FIN, ACK] |
LAST_ACK |
CLOSED |
[ACK] |
- |
當服務端收到客戶端的TCP鏈接請求後,會發送[SYN, ACK]包,進入SYN_RCVD狀態。若是沒有收到客戶端的確認,服務器會嘗試重傳,並保持SYN_RCVD狀態一段時間(一般是30秒到2分鐘)。
因爲服務端的SYN_RCVD狀態,就有了SYN Flood攻擊。所謂的SYN Flood攻擊就是,惡意的客戶端給服務端發了一個SYN後,就下線了,經過這種方式來消耗服務器資源。
TIME_WAIT狀態也稱爲2MSL(Maximum Segment Lifetime)等待狀態,當TCP的一端進入TIME_WAIT狀態後,所產生的效果就是該端口在2MSL這段時間中不能被再次使用。
TCP首部的RST位是用於復位的。通常不管合適一個報文端發往相關的鏈接出現錯誤,TCP都會發出一個復位報文段。主要使用:
最大報文段長度表示TCP傳往另外一端的最大塊數據的長度。當一個鏈接創建時,鏈接的雙方都要通告各自的MSS。
通常,若是沒有分段發生,MSS仍是越大越好。報文段越大容許每一個報文段傳送的數據越多,相對IP和TCP首部有更高的網絡利用率。當TCP發送一個SYN時,它能將MSS值設置爲外出接口的MTU長度減去IP首部和TCP首部長度。對於以太網,MSS值可達1460。若是目的地址爲非本地的,MSS值一般默認爲536,是否本地主要經過網絡號區分。
以太網和802.3對數據幀的長度都有一個限制,最大值分別是1500和1492個字節。鏈路層的這個指標稱做MTU(注意MTU是鏈路層的概念),不一樣類型的網絡大多數都有一個上限。
若是網絡層(IP層)有一個數據報須要傳輸,且數據的長度比鏈路層的 MTU還大,那麼網絡層(IP層)就要進行分片(fragmentation),把數據報分紅若干片,保證每個分片都小於MTU;目的端的網絡層(IP層)會對收到的分片進行從新組裝。
TCP提供了鏈接的一端在結束它的發送後還能接收來自另外一端數據的能力,這就是TCP的半關閉。
客戶端發送FIN,另外一端發送對這個FIN的ACK報文段。當收到半關閉的一端在完成它的數據傳送後,才發送FIN關閉這個方向的鏈接,客戶端再對這個FIN確認,這個鏈接才完全關閉。
對於每一個TCP鏈接,TCP管理4個不一樣的定時器
TCP keepalive和HTTP HTTP Keep-Alive