TCP流重組的研究

2021-07-02 20:08:26 字數 2597 閱讀 8975

然後介紹重灌tcp資料段的方法:

1.每到來乙個tcp資料報(pkt),我先將該資料報的源ip位址、目的ip位址、源埠號、目的埠號取出來在重灌表(tpq_tbl)中縱向的鍊錶中查詢有沒有與它相匹配的鍊錶(fp)存在,如果有,就把pkt資料報放入與它有相同socket對的fp鏈中,放入鍊錶的時,我先查詢pkt的順序號在鍊錶中的適當位置,然後才放入;如果沒有,則在tpq_tbl中新建立乙個該型別的煉表頭節點,然後再將其放入新建立的鍊錶中。

2.每當在fp中放入乙個tcp資料段後,我就檢查fp鍊錶中的資料段是否已經到齊了(判斷方法下面介紹),若到齊,就將個鍊錶中所有資料段的資料部分拼接到一起,得到應用層報文,然後釋放該鍊錶,然後重複1-2步驟;若沒到齊,直接重複1-2步驟。

關於判斷乙個鍊錶中tcp資料段是否到齊的方法:

使用的變數說明:

count計數器,表示當前鍊錶中的所有tcp資料段資料部分的長度之和。每當在該鍊錶中加入乙個新tcp資料段時,我都會將count累加上該tcp資料段的資料部分的長度。

syn_seq,表示本次tcp連線的第乙個資料報的順序號,也就是建立tcp連線時的第一次握手的syn包的順序號。

fin_seq,表示本次tcp連線的最後乙個資料報的順序號,也就是關閉tcp連線時的第二個fin包的順序號。

判斷:當(fin_seq - syn_seq)與count相等時,就說明tcp資料段已經到齊,否則就是沒有到齊。

「tcp segment of a reassembled pdu」指tcp層收到上層大塊報文後分解成段後發出去。於是有個疑問,tcp層完全可以把大段報文丟給ip層,讓ip層完成分段,為什麼要在tcp層分呢? 其實這個是由tcp的mss(maximum segment size,最大報文段長度)決定的,tcp在發起連線的第乙個報文的tcp頭里通過mss這個可選項告知對方本端能夠接收的最大報文(當然,這個大小是tcp淨荷的大小),乙太網上這個值一般設定成1460,因為1460byte淨荷+20byte tcp頭+20byte ip頭 = 1500位元組,正好符合鏈路層最大報文的要求。

至於收到乙個報文後如何確定它是乙個"tcp segment"?如果有幾個報文的ack序號都一樣,並且這些報文的sequence number都不一樣,並且後乙個sequence number為前乙個sequence number加上前乙個報文大小再加上1的話,肯定是tcp segment了,對於沒有ack標誌時,則無法判斷。

另外有不太一樣的說法,**

mtu和mss

本文用到的抓包工具為wireshark

,它的前身是赫赫有名的ethereal。wireshark乙太網幀的封包格式為:

frame= ethernet header + ip header + tcp header + tcp segment data

(1)ethernet header =14byte = dst physical address(6 byte)+ src physical address(6 byte)+ type(2 byte),乙太網幀頭以下稱之為資料幀

(2)ip header =20byte(without options field),資料在ip層稱為datagram,分片稱為fragment

(3)tcp header =20byte(without options field),資料在tcp層稱為stream,分段稱為segment(udp中稱為message)。

(4)54個位元組後為tcp資料負載部分(data portion),即應用層使用者資料。

ethernet header以下的ip資料報最大傳輸單位為mtu(maximum transmission unit,effect of short board),對於大多數使用乙太網的區域網來說,mtu=1500。

tcp資料報每次能夠傳輸的最大資料分段為mss,為了達到最佳的傳輸效能,在建立

tcp連線時雙方協商mss值,雙方提供的mss值的最小值為這次連線的最大mss值。mss往往基於mtu計算出來,通常mss=mtu-sizeof(ip header)-sizeof(tcp header)=1500-20-20=1460。

這樣,資料經過本地tcp層分段後,交給本地ip層,在本地ip層就不需要分片了。但是在下一跳路由(next hop)的鄰居路由器上可能發生ip分片!因為路由器的網絡卡的mtu可能小於需要**的ip資料報的大小。這時候,在路由器上可能發生兩種情況:

(1).如果源傳送端設定了這個ip資料報可以分片(may fragment,df=0),路由器將ip資料報分片後**。

(2).如果源傳送端設定了這個ip資料報不可以分片(don』t fragment,df=1),路由器將ip資料報丟棄,並傳送icmp分片錯誤訊息給源傳送端。

關於mtu的探測,參考《path

mtudiscovery

》。我們可以通過基於icmp協議的ping命令來探測從本機出發到目標機器上路由上的mtu,詳見下文。

TCP資料報重組實現分析

參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料段第一位元組的序號 資...

TCP資料報重組實現分析

tcp重組資料報分析 參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料...

瀑布流研究

0.前言 以前看過瀑布流,但是沒有自己動手寫 最近偶然又看到了,那索性就自己動手寫寫 瀑布流的實現方式大致上有三種 固定列數的浮動布局 自適應的絕對定位布局 css3的多列布局,下面就分別描述。1.固定列數的浮動布局 該方法比較簡單 計算出高度最小的那一列,然後 2.絕對定位 思考 1.計算可以當前...