標籤:
原文:http://www.cnblogs.com/CBDoctor/archive/2012/10/17/2727073.html
在TCP/IP協議中,TCP協議提供可靠的串連服務,採用三向交握建立一個串連。
第一次握手:建立串連時,用戶端發送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三向交握:用戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,用戶端和伺服器進入ESTABLISHED狀態,完成三向交握。
完成三向交握,用戶端與伺服器開始傳送資料,在上述過程中,還有一些重要的概念:
未串連隊列:在三向交握協議中,伺服器維護一個未串連隊列,該隊列為每個用戶端的SYN包(syn=j)開設一個條目,該條目表明伺服器已收到SYN 包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的串連在伺服器處於Syn_RECV狀態,當伺服器收到客戶的確認包時,刪除該條目,伺服器 進入ESTABLISHED狀態。
Backlog參數:表示未串連隊列的最大容納數目。
SYN-ACK 重傳次數 伺服器發送完SYN-ACK包,如果未收到客戶確認包,伺服器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超 過系統規定的最大重傳次數,系統將該串連資訊從半串連隊列中刪除。注意,每次重傳等待的時間不一定相同。
半串連存活時間:是指半串連隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半串連存活時間為Timeout時間、SYN_RECV存活時間。
====================================================================
現在,我們來看一個完整的流程,在一個TCP socket上系統調用connect究竟是如何建立起一個到對端的串連的。我們還是以實驗環境172.16.48.2向172.16.48.1的連接埠5002發起串連請求為例。
第一步,172.16.48.2向172.16.48.1發起串連請求,發送一個SYN段,指明目的連接埠5002,通告自己的初始序號(ISN,由協議棧 隨機產生的一個32位元),設定確認序號為0(因為還沒有收到過對端的資料),通告自己的滑動視窗大小為5840(對端是5792,這似乎有問題,有待進 一步細查),視窗擴大因子為2(在首部選項中),通告最大報文段長度為1460(本地區域網路),下面是資料內容(已剝去鏈路層的乙太網路首部和網路層的IP 首部):
資料內容 含義
基本首部
80 0e 源連接埠(32782)
13 8a 目的連接埠(5002)
00 00 07 bc 初始序號ISN
00 00 00 00 確認序號
a 首部長度
0 02 標誌位,SYN=1
16 d0 滑動視窗大小(5840)
64 9e 校正和
00 00 緊急指標
TCP選項
02 04 05 b4 最大報文段長度(1460)
04 02 允許SACK
08 0a 00 0a 79 14 00 00 00 00 時間戳記(0x000a7914),回顯時間戳記(0)
01 佔位。
03 03 02 視窗擴大因子(2)
第二步,172.16.48.1收到請求包,檢查標誌位,發現SYN=1,認為這是一個初始化串連的請求,回應這個SYN,同時也發送自己的SYN段(即 ACK,SYN同時置位)。因為SYN本身要佔用一個序號(還有標誌FIN也要佔用一個序號)。所以,確認序號設定為172.16.48.2的ISN加1 (即172.16.48.1期望收到來自172.16.48.2的下一個包的第一個序號為0x07bd。同時也要通告自己的初始序號,滑動視窗大小,視窗 擴大因子,最大報文段長度等,下面是資料內容:
資料內容 含義
基本TCP首部
13 8a 源連接埠(5002)
80 0e 目的連接埠(32782)
98 8e 40 91 初始序號ISN
00 00 07 bd 確認序號(對端ISN+1)
a 首部長度
0 12 標誌位,ACK=1, SYN=1
16 a0 滑動視窗大小
65 d7 校正和
00 00 緊急指標
TCP選項
02 04 05 b4 最大報文段長度(1460)
04 02 允許SACK
08 0a 00 3c 25 8a 00 0a 79 14 時間戳記(0x003c258a),回顯時間戳記(000a7914)
01 佔位
03 03 02 視窗擴大因子(2)
第三步,172.16.48.2對來自172.16.48.1的SYN段進行確認,至此,TCP三向交握協議完成,串連建立,在172.16.48.2收 到SYN段時,將自己對應的socket的狀態由TCP_SYN_SENT改為TCP_ESTABLISHED,進入串連建立狀態,下面是資料內容:
資料內容 含義
80 0e 源連接埠(32782)
13 8a 目的連接埠(5002)
00 00 07 bd 序號(已不是ISN了)
98 8e 40 92 確認序號(對端ISN+1)
8 首部長度(8*4=32,有12位元組的選項)
0 10 標誌,ACK=1
05 b4 滑動視窗大小(1460,有問題?待確認)
a5 8a 校正和
00 00 緊急指標
01 佔位
01 佔位
08 0a 00 0a 79 14 00 3c 25 8a 時間戳記(0x0a007914), 回顯時間戳記(0x003c258a)
=====================================================================
7、簡述TCP三向交握過程,並說明為什麼要3次握手
TCP 三向交握
TCP 串連是通過三向交握進行初始化的。三向交握的目的是同步串連雙方的序號和確認號並交換 TCP 視窗大小資訊。以下步驟概述了通常情況下用戶端電腦聯絡伺服器電腦的過程:
1. 用戶端向伺服器發送一個SYN置位的TCP報文,其中包含串連的初始序號x和一個視窗大小(表示用戶端上用來儲存從伺服器發送來的傳入段的緩衝區的大小)。
2. 伺服器收到用戶端發送過來的SYN報文後,向用戶端發送一個SYN和ACK都置位的TCP報文,其中包含它選擇的初始序號y、對用戶端的序號的確認x+1和一個視窗大小(表示伺服器上用來儲存從用戶端發送來的傳入段的緩衝區的大小)。
3. .用戶端接收到伺服器端返回的SYN+ACK報文後,向伺服器端返回一個確認號y+1和序號x+1的ACK報文,一個標準的TCP串連完成。
TCP 使用類似的握手過程來結束串連。這可確保兩個主機均能完成傳輸並確保所有的資料均得以接收
TCP Client Flags TCP Server
1 Send SYN (seq=x) ----SYN---> SYN Received
2 SYN/ACK Received <---SYN/ACK---- Send SYN (seq=y), ACK (x+1)
3 Send ACK (y+1) ----ACK---> ACK Received, Connection Established
w: ISN (Initial Sequence Number) of the Client
x: ISN of the Server
==========================================================
握手階段:
序號 方向 seq ack
1 A->B 10000 0
2 B->A 20000 10000+1=10001
3 A->B 10001 20000+1=20001
解釋:
1:A向B發起串連請求,以一個隨機數初始化A的seq,這裡假設為10000,此時ACK=0
2:B收到A的串連請求後,也以一個隨機數初始化B的seq,這裡假設為20000,意思是:你的請求我已收到,我這方的資料流就從這個數開始。B的ACK是A的seq加1,即10000+1=10001
3:A收到B的回複後,它的seq是它的上個請求的seq加1,即10000+1=10001,意思也是:你的回複我收到了,我這方的資料流就從這個數開始。A此時的ACK是B的seq加1,即20000+1=20001
資料轉送階段:
序號 方向 seq ack size
23 A->B 40000 70000 1514
24 B->A 70000 40000+1514-54=41460 54
25 A->B 41460 70000+54-54=70000 1514
26 B->A 70000 41460+1514-54=42920 54
解釋:
23:B接收到A發來的seq=40000,ack=30000,size=1514的資料包
24:於是B向A也發一個資料包,告訴B,你的上個包我收到了。B的seq就以它收到的資料包的ACK填充,ACK是它收到的資料包的SEQ加上資料包的大小(不包括乙太網路協議頭,IP頭,TCP頭),以證實B發過來的資料全收到了。
25:A在收到B發過來的seq為41460的資料包時,一看到41460,正好是它的上個資料包的seq加上包的大小,就明白,上次發送的資料包已安全 到達。於是它再發一個資料包給B。這個正在發送的資料包的seq也以它收到的資料包的ACK填充,ACK就以它收到的資料包的seq(70000)加上包 的size(54)填充,即ack=70000+54-54(全是頭長,沒資料項目)。
26:一樣的啊
TCP 三向交握的意義在哪裡?
最好詳細點,考慮全面。
我能想到的:
1.用較短的SYN包來探測目的主機連接埠及中間網路是否工作
2.初始化序號
問題:TCP為什麼要使用隨機初始序號?
我看過解釋是防止串連失效後SOCKET被重用使得以前殘留的包被錯誤的接受。但是現在主機剛剛釋放的SOCKET不都是不可馬上使用的嗎?
3.同步MSS
請各位補充。
1.我認為你說對了一方面,,,還有一方面就是,,,讓server為client預留一部分伺服器資源,,,需要注意的是,,,正是因為這樣,,,就有了大家都知道的Dos(Denial of service)以及衍生出來的DDos(Distributed Dos),,,後者更為可怕和難易分析監測,,,其原理就是,,,向server發出syn,,,然後呢,,,又不跟server進行進一步的通訊,,,這樣,,,就導致server為它白白的分配了很多資源,,,我們可以想想的是,,,當這種syn達到一定數量以後,,,server肯定會爆掉,,,這種攻擊相當之恐怖,,,傳說累計有幾百億美元的損失了吧,,,同時,,,這也是當今網路安全研究的一個熱點,,,
2.首先,我覺得你思考倒要用隨機序號這個問題很厲害,,,
應該是這樣的,,,這個是處於網路安全的角度來做的,,,如果沒有隨機產生tcp的序號的話,,,hacker們就可以輕易的採取某些手段猜測到你和別人通訊的tcp序號,,,並且製造tcp序號攻擊,,,這已經是當今網路上一種常見的攻擊,,,tcp當時的設計者並沒有考慮到這些,,,即便是這樣,,,tcp序號攻擊也是有辦法進行的,,,就為了防止這種攻擊,,,已經有很多tcp序號的產生演算法被提出和改進,,,你可以倒ieee上面去搜下,,,較多,,,據我所知,,,unix這方面做的比windows好
TCP/IP三向交握詳解