TCP報文段的首部格式
TCP雖然是面向字節(jié)流的,但TCP傳送的數(shù)據(jù)單元卻是報文段
TCP報文段首部前20個字節(jié)是固定的,后面有4n(n為整數(shù))個字節(jié)可以根據(jù)需要而增加,整個報頭最多為60字節(jié)
首部字段:

端口號
端口號字段包括源端口號與目的端口號;
每個端口號字段長度為16 位(2字節(jié)),分別表示發(fā)送該報文段的應(yīng)用進程的源端口號與接收進程的目的端口號。
序號
序號字段長度為32位(4個字節(jié)),序號范圍在0~(232-1),即0~4284967295;序號增加到232-1后,下一個序號又回到0;
為發(fā)送字節(jié)流中的每個字節(jié)都按順序編號,起始序號必須在連接建立時設(shè)置;序號字段值是本報文段所發(fā)送的數(shù)據(jù)的第一個字節(jié)的序號
例如,一個報文段的序號字段為301,攜帶數(shù)據(jù)為100字節(jié),第二個報文段的序號就要是401
確認號
確認號字段長度為32 位(4字節(jié));確認號表示一個進程已經(jīng)正確接收序號為N-1之前的字節(jié)(包含N-1),要求發(fā)送方下一個應(yīng)該發(fā)送序號為N的字節(jié)的報文段。
例如,A發(fā)送一個序號為301,長度為100個字節(jié)的數(shù)據(jù)給B,B此時需要回復(fù)一個為401的確認號,以此來確認已經(jīng)收到前400個字節(jié)的數(shù)據(jù)
報頭長度
報頭長度也稱數(shù)據(jù)偏移,都是說頭部長度,只是角度不同。報頭長度字段的長度為4位;TCP報頭長度是以4字節(jié)為一個單元來計算的,實際報頭長度是在20~60字節(jié),因此這個字段的值是在5至15之間。
保留
占6位,保留今后使用,目前全部置為0
控制字段
控制字段定義了6種不同的控制位或標志位;
控制字段將在TCP的連接建立和終止、流量控制,以及數(shù)據(jù)傳送中發(fā)揮作用。
| 標志 | 說明 |
|---|---|
| SYN | 在連接時對序號進行同步 |
| ACK | 確認字段的值有效。當ACK=1時,確認號才有效 |
| FIN | 終止連接 |
| RST | 連接必須復(fù)位。TCP連接出現(xiàn)嚴重差錯要重新建立連接。還可用來拒絕一個非法報文段或拒絕打開一個鏈接。 |
| URG | 緊急指針字段的值有效。有緊急數(shù)據(jù)盡快傳送,插入到報文段最前面,與緊急指針配合使用。 |
| PSH | 將數(shù)據(jù)推向前,希望立即收到對方響應(yīng)。接收方收到后盡快交付給接收應(yīng)用進程 |
窗口大小
窗口字段長度為16位;窗口的長度值是在0~65535之間;
窗口字段值指示對方最多可以發(fā)送的字節(jié)數(shù),作為發(fā)送方確定發(fā)送窗口的依據(jù)。明確指出了從被確認的字節(jié)算起可以發(fā)送的數(shù)據(jù)量。窗口字段值是動態(tài)變化的。窗口值為0也是合法的。表示接收方暫時不能接收數(shù)據(jù),發(fā)送方要停止發(fā)送。
校驗和
計算校驗和與UDP校驗和的方法相同;
TCP校驗和同樣需要偽報頭,唯一不同的是協(xié)議字段的值是6。
緊急指針
緊急指針字段的長度為16位,只有當緊急標志URG=1時,這個字段才有效,這時的報文段中包括緊急數(shù)據(jù);指出了緊急數(shù)據(jù)的末尾在報文段中的位置。
TCP軟件要在優(yōu)先處理完緊急數(shù)據(jù)之后才能夠恢復(fù)正常操作。
注意,即使窗口為零時也可以發(fā)送緊急數(shù)據(jù)。
TCP最早只規(guī)定了一種選項,即最大報文段長度MSS(Maximum Segment Size)
TCP報文段的最大長度與窗口長度的概念不同:
- 設(shè)置窗口大小是通知發(fā)送方下一次可以連續(xù)傳輸?shù)淖止?jié)數(shù);
- 最大段長度MSS是在構(gòu)成一個TCP 報文段時最多可以在報文的數(shù)據(jù)- - 字段中放置的數(shù)據(jù)字節(jié)數(shù)量;
- MSS值的確定與每次傳輸?shù)拇翱诖笮o關(guān);
- MSS是TCP報文中數(shù)據(jù)部分的最大長度,不包括報頭長度。
TCP的運輸連接
建立連接-->三次握手

B的TCP服務(wù)器先創(chuàng)建傳輸控制塊TCB,準備接受客戶進程的連接請求,然后服務(wù)進程就處于listen狀態(tài)。
第一次握手:首先創(chuàng)建傳輸控制模塊TCB,向B發(fā)出連接請求報文段,這是首部中的同步位SYN=1,同時選擇1個隨機初始序號x,此時不能攜帶數(shù)據(jù),但需要消耗一個序號。
第二次握手:B收到請求后,如果同意連接的情況下,向A發(fā)送確認。此時SYN=1,ACK=1,確認號ack=x+1,同時自己選擇一個初始序列號seq=y。此時這個報文也不能攜帶數(shù)據(jù),但需要消耗一個序號。
第三次握手:A收到B的確認后,需要向B確認,確認報文段ACK=1,ack=y+1,seq=x+1,這時連接已建立。此時,若這個報文不攜帶數(shù)據(jù)則不消耗序列號,下一個報文的序列號還是seq=x+1。
問題:為什么A最后要在發(fā)送一次確認?
答:主要是防止已失效的連接請求報文突然又傳送到了B,從而產(chǎn)生錯誤。
由于有了A再發(fā)一次確認,當一個失效的請求到B后,B發(fā)來一個確認,而A此時并沒有請求,所以不會理睬此B的確認,也不會再發(fā)一次確認。從而沒有建立連接。
斷開連接-->四次揮手
- 第一次揮手:主機A發(fā)送位碼為FIN=1,用來關(guān)閉客戶A到服務(wù)器B的數(shù)據(jù)傳送。此時A的狀態(tài)為FIN_WAIT_1
- 服務(wù)器B收到這個FIN,它發(fā)回一個ACK,確認序號為收到的序號加1。此時A為FIN_WAIT_2,B為CLOSE_WAIT
- 服務(wù)器B關(guān)閉與客戶端A的連接,發(fā)送一個FIN給客戶端A。此時A為TIME_WAIT,B為LAST_ACK
- 客戶端A發(fā)回ACK報文確認,并將確認序號設(shè)置為收到序號加1。此時A、B都關(guān)閉了,狀態(tài)變?yōu)镃LOSED。
當(2)、(3)步中的ACK和FIN在一個包中發(fā)送時,A的狀態(tài)會直接從FIN_WAIT_1變?yōu)門IME_WAIT
問題:為什么建立連接需要三次握手,而斷開連接需要四次握手?
因為每個方向都需要一個FIN和ACK,當一端發(fā)送了FIN包之后,處于半關(guān)閉狀態(tài),此時仍然可以接收數(shù)據(jù)包。
在建立連接時,服務(wù)器可以把SYN和ACK放在一個包中發(fā)送。
但是在斷開連接時,如果一端收到FIN包,但此時仍有數(shù)據(jù)未發(fā)送完,此時就需要先向?qū)Χ嘶貜?fù)FIN包的ACK。等到將剩下的數(shù)據(jù)都發(fā)送完之后,再向?qū)Χ税l(fā)送FIN,斷開這個方向的連接。
因此很多時候FIN和ACK需要在兩個數(shù)據(jù)包中發(fā)送,因此需要四次握手
DOS攻擊和SYN洪水攻擊
DOS攻擊利用合理的服務(wù)請求占用過多的服務(wù)資源,使正常用戶的請求無法得到相應(yīng)。
常見的DOS攻擊有計算機網(wǎng)絡(luò)帶寬攻擊和連通性攻擊。
帶寬攻擊指以極大的通信量沖擊網(wǎng)絡(luò),使得所有可用網(wǎng)絡(luò)資源都被消耗殆盡,最后導(dǎo)致合法的用戶請求無法通過。
連通性攻擊指用大量的連接請求沖擊計算機,使得所有可用的操作系統(tǒng)資源都被消耗殆盡,最終計算機無法再處理合法用戶的請求。
SYN洪水攻擊
SYN洪水攻擊屬于DOS攻擊的一種,它利用TCP協(xié)議缺陷,通過發(fā)送大量的半連接請求,耗費CPU和內(nèi)存資源。
客戶端在短時間內(nèi)偽造大量不存在的IP地址,向服務(wù)器不斷地發(fā)送SYN報文,服務(wù)器回復(fù)ACK確認報文,并等待客戶的確認,由于源地址是不存在的,服務(wù)器需要不斷的重發(fā)直至超時,這些偽造的SYN報文被丟棄,目標系統(tǒng)運行緩慢,嚴重者引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓。