本來這一篇是打算寫標頭在分布式平台中的具體變換過程的。其實文章已經寫好了。但是想了這個應該是不能随便發表的。畢竟如果知道了一個包的具體每個位元組的意義。能僞造包來攻擊系統。其次來介紹一個包的具體變換過程意義不大。在每個分布式系統的裡。包的扭轉應該是個有不同。我們着重的應該是一種思想。一種共性。而不是個體的具體實作。
這裡打算就介紹下大包的處理。其實這個更多的是介紹了下TCP切包。跟分布式沒啥關系。。。。 不過這也算是系統的一部分
下面介紹下一個大包的具體處理過程
一、發送請求并分析
1)首先我們在用戶端發送一個超過1M 的包給用戶端處理,結果是服務端隻收了一次recv就拒絕了
2)為了更清晰 我們用tcpdump來抓包處理
注意由于是在本機上發送包接收包。是以走的是回路。即網卡lo 而不是eth0.抓包的時候 需要抓lo 否則看不到資料
|
拿到資料以後放到wireshark裡分析

a)為什麼最大協商是16396 而實際收了16384個位元組
可以看到協商的mss最大傳輸單元為16396
但是顯示netio revc隻收到了16384個位元組。
因為TCP標頭中會帶有12位元組的選項----時間戳
是以實際是16396-12 = 16384
是以neito一次收到的是16384個位元組。
注意這裡的測試環境是本機回路。
如果是在公網上。
一次TCP能承載的最大資料包 應該是 1448(1500MTU-20 IP標頭 -20TCP標頭 -12時間戳)
(具體且包的原理請看下面)
能revc的資料跟TCP的接收緩沖隊列有關。
b)為什麼本機就隻收了一次 mss ?
sysctl -a | grep net.ipv4.tcp_wmem
net.ipv4.tcp_wmem = 4096 16384 81920
第二個值是send預設發送緩沖區位元組的個數
是以send一次 16384個位元組 然後mss的大小剛好協商的是16396。 是以就被recv一次收到了。
正常在公網下。send 的16384個位元組會被TCP切成11個包發到netio。
TCP會在接受端組包。但是不一定會一下都收到這11個包。可能就收到5個 然後組包給recv來處理。然後繼續循環recv。還收下面的6個包.組包給recv
是以netio會根據緩沖隊列已經網路情況 recv到部分位元組或者全部的16384個位元組。
這裡如果send的資料大于 16384 個位元組。那麼就是循環上面的步驟 .
c)為什麼服務端拿到一次recv就之間關閉請求了。
因為我們服務端允許用戶端傳來的請求必須小于1M.是以拿到一次recv以後。就可以解析標頭。發現用戶端到底需要發送多少個位元組。
超過1M 我們認為就是非法包。直接拒絕并關閉用戶端連接配接。
二、接下來我們來分析一個服務端能處理的大包
1、我們發送一個262360 個位元組包給服務端
2、這裡注意下epoll收包的寫法
當recv完一個包的時候。如果正确。就會回到最開始的while循環然後繼續監聽 epoll。然後會觸發E_TCP_CONN事件。
看如下圖。收完一個recv就會跳到while。繼續epoll wait 來收下一包。反複如此直到收完一個完整的包
注意早期的寫法是這樣的。直接在while循環裡收recv。 這是在阻塞機制下的寫法。
我們用到epoll. 可以不用阻塞在recv 可以等待事件觸發讀取。
可以自己比對下
|
3、結果以及分析
|
我們看到每次發送的length都是16384 但是由于滑動視窗win。時大時小。發送的速度。不一樣。導緻recv一次能收到的資料也是不一樣的
收到這些包。把他們組成一個完整的包。即發送端發過來的262360的包
開始跳到int CNetioApp::OnRecv(int iTcpHandle,char* pBuffer,uint32_t nBufLen)處理
後面就是正常邏輯了。丢到container的請求消息隊列。
然後container處理完丢到netio的回包隊列。
最後netio拿到包傳回給前端
這裡最後總結:
1、這裡對分布式平台來說。會有一個專門收包的程序。隻負責收包和轉發。本身沒有業務處理。它收到包以後會打上時間戳或者其他一些基本資訊。然後把包丢給其他業務程序處理。然後等包回來了在把處理完後的包傳回給前端。如果需要請求的服務不再本機。會有另一個轉發器。把請求包發送大分布式中的其他服務處理。這裡先說下大概的功能。後面會單獨開篇介紹我們的netio。
2、收包并不是一次全收完才可以處理。一般一次recv以後。拿到固定標頭資訊就可以來判斷包的一些基本狀态。可以分析是不是系統想要的包、允許的包
3、了解下TCP的一些基本原理。
a)假如我們在TCP層用更大的資料量來打包會有什麼結果呢?
答案是降低了傳輸效率。
分片最大的壞處就是降低了傳輸性能,本來一次可以搞定的事情,分成多次搞定,是以在網絡層更高一層(就是傳輸層)的實作中往往會對此加以注意!
這個就是在以太網上,TCP不發大包,反而發送1448小包的原因。隻要這個值TCP才能對鍊路進行效能最高的利用。
是以TCP在發包的時候已經切好大小剛好的包。不需要IP層再去切包
b)簡單來說 滑動視窗是用來控制發送速度的