1. 程式人生 > >netty4傳送HttpRequest及HttpReponse太大的問題(半包)

netty4傳送HttpRequest及HttpReponse太大的問題(半包)

netty是對socket的封裝,底下走的TCP還是老一套,太大的HTTP包傳送的時候是要被切分成好幾段的,傳送之後接收就變得很麻煩。網上有人提出多種解決方式,我自己試了試,結果如下:   

1.對於HttpRequest,有人提出在頭部協商訊息體長度。不要輕易相信吶,騷年們,這玩意兒就是一個坑,寫上之後那個不睜眼的TCP照樣剁碎了給發出去!此處紅色警戒!

2.不用TCP剁碎了,自己剁碎了傳過去。此方是否對症,沒試驗。

3.定長訊息。自我感覺不適合HttpRequest及HttpReponse這類東西,所以沒試。

4.其他,如設定傳送緩衝和接收緩衝等,均不管用

所以,從幾個坑裡面爬出來之後,我隆重推出netty的解決方案:用HttpObjectAggregator!!!

首先,在客戶端和服務端的channel下的pipeline啟動之前加上

 <span style="white-space:pre">	</span>ch.pipeline().addLast("aggregator", new HttpObjectAggregator(1024*1024*64));
        ch.pipeline().addLast("chunkedWriter", new ChunkedWriteHandler());  
接收的時候就這樣:
/**
	 	 * 讀取傳過來的訊息,read request message from channel
	 	 */
	    @Override
	    public void channelRead(ChannelHandlerContext ctx, Object msg)
	            throws Exception {
	        if (msg instanceof DefaultHttpRequest) {
	            request = (DefaultHttpRequest) msg;
	        }
	        if (msg instanceof HttpContent) {
	            HttpContent content = (HttpContent) msg;
	            ByteBuf buf = content.content();
	            messageOfClient = buf.toString(io.netty.util.CharsetUtil.UTF_8);
	            if(messageOfClient!=null&&!messageOfClient.contentEquals("")&&!messageOfClient.contains("ping")){
		            messageToSend+= messageOfClient;
	            }else{
	            	System.out.println("channel的數目:"+ServerDataSyncServer.channels.size()+" channelGroupSize");
	            	System.out.println(ctx.channel().remoteAddress().toString());
	            }
	            buf.release();
	            if(content instanceof LastHttpContent){
	            	//此處對其他客戶端的心跳包不予處理,因為服務端掉線之後會客戶端會迴圈偵測連線,客戶端斷掉之後將服務端將不列印輸出資訊
	            	if(messageToSend.length()>12&&messageToSend.substring(0, 2).contentEquals("DB")){

			            //訊息長度符合一定條件,則是需要向其他客戶端傳送的資料庫訊息,呼叫方法轉發
		            	System.out.println("Server已讀取資料庫持久化資訊,將開始向所有客戶端傳送");
		            	ServerDataSyncServer.channels.remove(ctx.channel());
		            	System.out.println("messageToSend   "+messageToSend );
		            	String messageContent = messageToSend;
		            	ServerDataSyncServerSendGroup.sendToAllChannel(messageContent);
		            	messageToSend = "";
		            }
	            }
	        }
	    }

當然,我的傳送客戶端是短連線,
ServerDataSyncServer.channels.remove(ctx.channel());
長連線的對這句可以直接忽略。

這樣就可以了,netty接收到分段的大TCP包之後會自動組裝成完整的HTTPrequest或者HttpResponse,然後逐個讀取分段的訊息體,最後一個是LastHttpContent型別,讀到這個就算是整個包讀完了,再做後續處理即可。

完畢

相關推薦

netty4傳送HttpRequestHttpReponse的問題()

netty是對socket的封裝,底下走的TCP還是老一套,太大的HTTP包傳送的時候是要被切分成好幾段的,傳送之後接收就變得很麻煩。網上有人提出多種解決方式,我自己試了試,結果如下:    1.對於HttpRequest,有人提出在頭部協商訊息體長度。不要輕易相信吶,騷年

java web專案,post請求傳送資料的處理方法

可以設定tomcat,server.xml中Connector中的屬性,maxPostSize的值。 <Connector port="8080" protocol="HTTP/1.1"

JS數字導致的精度丟失問題原因解決方案

JS 數字丟失精度的原因 計算機的二進位制實現和位數限制有些數無法有限表示。就像一些無理數不能有限表示,如 圓周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 規範,採用雙精度儲存(double precision),佔用 64 b

用數表說明,為何蘋果

iphone 蘋果公司 蘋果手機 產品 歷史 不知從什麽時候開始蘋果手機基本上成了標配,雖然外界對蘋果的看衰情況一直存在,並且蘋果本身的手機銷量也在下滑。根據蘋果公司發布的2017財年第二財季業績,蘋果股價收盤上漲,在盤後交易中下跌3.42美元,至144.09美元,跌幅為2.32%。但這份

解決持久化數據,單個節點的硬盤無法存儲的問題;解決運算量,單個節點的內存、CPU無法處理的問題

pro 一致性哈希 普通 .html 價格 str oca 計劃 硬件 需要學習的技術很多,要自學新知識也不是一件容易的事,選擇一個自己比較感興趣的會是一個比較好的開端,於是,打算學一學分布式系統。   帶著問題,有目的的學習,先了解整體架構,在深入感興趣的細節,這是我的

分針網——每日分享:node_modules導致ide很卡

node_modules ide 領取免費IT資料 加群:272292492 更多文章:www.f-z.cn 在使用npm install之後 由於node_modules太大導致ide很卡 解決辦法如下

ZTree id值,ZTree沒有生成樹,ZTree的id值過

生成 如何解決 span image .cn 描述 今天 屬性 bsp ZTree id值太大,ZTree沒有生成樹,ZTree的id值過大 >>>>>>>>>>>>>>>>&

CentOS系統啟動內核破壞模擬實驗

啟動 內核和 管理 講過了centos的啟動流程,此時是不是想來點破壞呢?那就盡情的玩耍吧,記得在實驗之前拍個快照,萬一哪個環節錯誤恢復不回來了呢,畢竟數據無價,話不多說,開始。 一、刪除偽系統根。(ramdisk文件) (1)模擬誤操作刪除ramdisk文件。 ①模擬誤刪除initra

HDU1754 —— 線段樹 單點修改區間最

pre ios -a display 一次 add 分數 線段 play 題目鏈接:https://vjudge.net/problem/HDU-1754 很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。 這讓很多學生很反感。 不管你喜

放端心態,不要給自己的心理壓力。

font 心態 事物 並不是 nbsp 這不 自我反思 有一個 反思 心態好不好,還是要看自己 經常活動活動對自己是有很大的好處的,去一個好的地方散散心,或者是找個妹紙出去逛逛街啊(對哦,程序員哪來的妹子或女朋友啊)。這不都好呀! 幹嘛一直憋在一

系統操作(mac)-文件無法拷貝到U盤

菜單欄 blog 不支持 使用 launchpad 存儲 網速 技術 mman 現在的網速是越來越快了,各種在線傳輸文件還是算比較快了,若遇到像7、8個GB的文件,還是U盤來得實在,但是很的多Mac用戶在向U盤拷貝文件時總會遇到"文件太大,無法拷貝"的錯誤提示: U盤

jvm內存快照dump文件,怎麽分析

目錄 out 類對象 都是 文件太大 html tool 重新 間接 1、場景 通常,使用eclipse的mat圖形化工具打開dump的時候都會內存溢出. 對於比較小的dump,eclipse可以打開,但一旦dump文件太大,eclipse就有點束手無策。

tflearn 數據集無法加載進內存問題?——使用image_preloader 或者是 hdf5 dataset to deal with that issue

icon softmax present text nec ons sample pla actions tflearn 數據集太大無法加載進內存問題? Hi, all! I‘m trying to train deep net on a big dataset

nohup.out追加日誌的文件,文件自動清零的腳本

檢測 5.6 ins web ron 綠色 code null bin 1 #!/bin/bash 2 # clean the nohup.out file of list_domain 3 # author by:guoqian 4 # date:2018-

Dreamweaver 8 您選擇的文檔而不能導入問題

提示 文檔 問題 路徑 excel文件 另存為 weave 多個 表格 我遇到的問題是把excel中的數據直接復制到Dreamweaver中,因為文字太多而提示您選擇的文檔太大而不能導入,建議使用“復制”和“粘貼”將文檔的各個部分內容插入到多個頁面。網上試了好幾種方法,找到

Sql 腳本文件 還原數據庫

寬度 可以關閉 cmd 試圖 腳本 err 提示 級別 輸出 sql腳本太大直接在數據庫中執行會提示內存不足,我們看生成的腳本文件會發現每隔100條會有一個GO來分隔,這就好說了 在我將數據庫的結構連同數據生成一個腳本文件db.sql 後,想在另外的電腦上恢復數據庫,以便編

python知識點面試面試集合

工具 代碼實現 stash exc efault 常見命令 不可 tcp 乘法表 題目來源:武sir--一個很有意思的人,點擊這兒跳轉 一、基礎篇 為什麽學習Python? 通過什麽途徑學習的Python? Python和Java、PHP、C、C#、C++等其他語言的對比

txt文件打不開怎麽辦

日誌文件 bat文件 文本文 軟件 文件 問題 9.png 拆分 生成 #開始   最近在調試代碼的時候,生成了一個400MB的日誌文件 找了很多文本編輯器,都表示太大了打不開 QAQ #解決方案   百度下載 “txt殺手”      用這個軟件把文本文件拆分成小

socket編程 粘 問題的處理

當前 多少 分包 轉義 保存 長連接 完整 過去 高效 一般在socket處理大數據量傳輸的時候會產生粘包和半包問題,有的時候tcp為了提高效率會緩沖N個包後再一起發出去,這個與緩存和網絡有關系。 粘包 為x.5個包 半包 為0.5個包 由於網絡原因 一次可能會來 0.5/

關於SqlServer數據庫C盤占用空間問題

sel com lec server2 mic ace 驗證 驅動 日誌 關於SqlServer數據庫C盤占用空間太大問題 工程需要用上了SQL SERVER2008 ,主要作為數據倉庫使用,使用SSIS包從ORACEL10G中抽取數據到MS SQL中。環境是win200