2012年10月7日 星期日

TCP封包

一直以來﹐人們總愛將TCP和IP合在一起來講﹐是因為它們之間的密切關係所至。同時﹐我們也知道IP工作於網路層﹐而TCP則工作於傳送層﹐故此﹐它們的封包格式卻是不一樣的。
TCP封包格式
下面就讓我們看一看TCP封包的格式﹕
Source Port (16)Destination Port (16)
Sequence Number (32)
Acknowledgment Number (32)
Data
Offset(4)
Reserved (6)
U
G
R
A
C
K
P
S
H
R
S
T
S
Y
N
F
I
N
Window
(16)
Checksum (16)Urgent Pointer (16)
Options (0 or more 32 bit words + padding)
DATA
...

今次我不再為每一個TCP封包部件擷取樣板了﹐只打算略略討論一下它們的名稱和定義﹕

Source Port & Destination Port
如果我們將IP比喻成地址﹐那麼Port可以說是門口了﹐試想一下﹕一座大樓有前門﹑後門﹑側門﹑送貨的門﹑出貨的門﹑倒垃圾的門﹑扔死屍的門﹑等等亂七八糟的門...... 那麼﹐一個IP地址也有著好多個各種功能的port﹐而每一個port都被不同的服務傾聽著﹐就好比看門人一樣。下面是一些常用port和其對應的服務﹐有興趣的朋友可以在Linux的/etc/services這個檔案找到它們﹕
ftp-data    20/tcp
ftp         21/tcp
telnet      23/tcp
smtp        25/tcp      mail
www         80/tcp      http        # WorldWideWeb HTTP
www         80/udp                  # HyperText Transfer Protocol
pop-3       110/tcp                 # POP version 3
pop-3       110/udp

其實port號碼可以隨您喜歡任意指定給哪些服務使用﹐但為了避免“找錯門口”的情形出現(除非您故意想躲起來)﹐人們將一些比較常用的服務(Well known services)的port號碼固定下來了。但是﹐在TCP資料傳送過程中﹐可能同時要處理一個以上的封包﹐程式也會建立多個port來避免衝突。在兩台主機進行資料傳送的時候﹐來源地的port和目的地的port都必須讓TCP知道才行。

Sequence Number
發送序號。當資料要從一台主機傳送去另一台主機的時候﹐發送端會為封包建立起一個初始號碼﹐然後按照所傳送的位元組數﹐依次的遞增上去﹔那麼下一個封包的序號就會使用遞增之後的值來作為它的序號了。這樣﹐接收端就可以根據序號來檢測資料是否接收完整了。

Acknowledgement Number
回應序號。當接收端接收到TCP封包之後﹐通過檢驗確認之後﹐然後會依照發送序號產生一個回應序號﹐發出一個回應封包給發送端﹐這樣接收端就知道剛才的封包已經被成功接收到了。
可是﹐如果由於網路狀況或其它原因﹐當封包的TTL值達到期限時﹐接收端還沒接收到回應序號﹐就會重發該個被以為丟失了的封包。但如果剛好重發封包之後才接收到回應呢﹖這時候接收端就會根據序號來判斷該封包是否被重複發送﹐如果是的話﹐很簡單﹐將之丟棄不做任何處理就是了。

Data Offset
這是用來記錄標頭固定長度用的﹐和IP封包的IHL差不多﹕如果options沒設定的話﹐其長度就是20byte﹐用十六進位表示就是 0x14了。

Reserved
這是保留區間﹐暫時還沒被使用。

Contral Flag
控制標記。一個有六個﹐它們分別是﹕
Urgent data
當URG被設定為1的時候﹐就表示這是一個攜有緊急資料的封包。

Acknowledgment field significant
當ACK為1的時候﹐表示此封包屬於一個要回應的封包﹐一般都會為1。

Push function
如果PSH為1的時候﹐此封包所攜帶的資料就會被直接上遞給上層的應用程式﹐而無需經過TCP處理了。

Reset
如果RST為1的時候﹐表示要求重新設定封包﹐再重新傳遞。

Synchronize sequence number
如果SYN為1時﹐表示要求雙方進行同步溝通。

No more data fro sender (Finish)
如果封包的FIN為1的時候﹐就表示傳送結束﹐然後雙方發出結束回應﹐進而正式終止一個TCP傳送過程。
Window
我們都知道MS Windows是什麼東西﹐但這裡的Window卻非作業系統的“視窗”哦﹐我們稱這裡的視窗為“滑動視窗(Sliding Window)”。為什麼我們需要使用視窗呢﹖
正如您剛才看到的﹐TCP封包會通過SQN和ACK序號來確保傳送的正確性﹐但如果每一個封包都要等上一個封包的回應才被發送出去的話﹐實在是太慢和難以接受的。這樣﹐我們可以利用Sliding Window在傳送兩端劃分出一個緩衝範圍﹐規定出可以一次性發送的最大封包數目﹕

當TCP傳送建立起來之後﹐兩端都會將window的設定值還原到初始值﹐比方說﹕每次傳送3個封包。然後發送端就一次過發送三個封包出去﹐然後視窗則會往後移動三個封包﹐填補發送出去之封包的空缺。如果接收端夠順利﹐也能一次處理接收下來的三個封包的話﹐就會告訴發送端的window值為3﹔但如果接收端太忙﹐或是其它因素影響﹐暫時只能處理兩個封包﹐那麼﹐在視窗裡面就剩下一個封包﹐然後就會告訴發送端window值為2。這個時候﹐發送端就只送出兩個封包﹐而視窗就會往後移動兩個封包﹐填補發送出去的空缺。您明白為什麼這個視窗會“滑動”了吧﹗

Chechsum
當資料要傳送出去的時候﹐發送端會計算好封包資料大小﹐然後得出這個檢驗值封包一起發送﹔當接收端收到封包之後﹐會再對資料大小進行計算﹐看看是否和檢驗值一致﹐如果結果不相稱則被視為殘缺封包﹐會要求對方重發該個封包。

Urgent Pointer
還記得剛才講到Control Flag的時候我們提到一個URG的標記嗎﹖如果URG被設定為一的時候﹐這裡就會指示出緊急資料所在位置。不過這種情形非常少見﹐例如當資料流量超出頻寬的時候﹐系統要求網路主機暫緩發送資料﹐所有主機收到這樣的信息﹐都需要優先處理。

Option
這個選項也比較少用。當那些需要使用同步動作的程式﹐如Telnet﹐要處理好終端的交互模式﹐就會使用到option來指定資料封包的大小﹐因為telnet使用的資料封包都很少﹐但又需要即時回應。
Option的長度要麼是0﹐要麼就是32bit的整倍數﹐即使資料不足數﹐也要使用標頭中沒有的資料來填夠。
下面我們擷取一個TCP封包﹐看看您能從其中解讀出什麼意思﹖



UDP還是TCP﹖
在TCP/IP的網路﹐IP封包會透過ICMP協定來檢測對方的存在﹐而確保最大可能性的正確傳送。不過在傳送層裡面﹐除了TCP這個協定之外﹐我們還使用另一個傳輸協定﹕就是UDP (User Datagram Protocol)﹐他和TCP最大的分別是不偵測對方的存在就直接將資料送給對方﹐而假設對方會自行接收。
這樣對那些需要大樓資料存取而又不要求可靠傳輸的程式﹐如﹕聲音傳遞﹐可以省卻雙方的溝通和確認時間﹐從而提高資料傳輸量。使用UDP的程式協定例如有﹕DNS﹑SNMP﹑NFS﹑BOOTP﹑等等。
協定優點缺點
TCP傳送穩定﹐資料傳送成功率高。速度比較慢。
UDP傳輸量大﹐迅速。不穩定﹐容易遺失資料。


 資料來源: http://www.study-area.org/network/network_tcp.htm

沒有留言:

張貼留言