2016-05-23 600 views
-1

我剛剛開始編碼Netty 4,發現它似乎只支持單數分隔符,即使它聲稱支持多個分隔符。事實是,它支持交替使用多個分隔符,而不是同時使用。如何在Netty 4中添加頭部和尾部分隔符幀解碼器?

爲什麼我需要頭部和尾部分隔符的原因是爲了在發生包丟失或無序包接收情況下的速度。 例如我的框架看起來像這樣:$ _ {LEN} {DATA} \ r \ n

所以我的頭部分隔符是$ _,而尾部分隔符是\ r \ n。

假設在一幀中接收到多個數據包,而一些中間數據包在傳輸期間丟失,如果沒有$ ,解碼器必須繼續搜索\ r \ n以確定結束。如果\ r \ n也丟失了,那麼它必須搜索下一個\ r \ n而不是擊中導致新消息的$ ...

但是現在的Netty DelimiterBasedFrameDecoder似乎無法支持我想上面。我應該如何實現這個目的?

它看起來對我來說Netty FrameDecoder設計沒有考慮到數據包丟失或打包器無序的情況?對Netty來說,我可能是錯的。如果有人能夠告訴我這件事,請予以諒解。

+0

你使用udp或tcp流嗎?在udp流中,您通常不會重新分配接收到的字節 – Ferrybig

+0

tcp streams:服務器在雲端數據中心運行,客戶端設備通過WiFi LAN或3G/2G SIM移動無線廣域網連接。因此,網絡可能不穩定,容易受到網絡干擾,通常會導致數據包丟失... –

+0

請注意,tcp可以保證您的數據是原樣(因此無需修改)或連接錯誤。這意味着數據包的任何部分都不會丟失。 – Ferrybig

回答

1

爲了簡潔和高效,我最終使用Netty的LengthFieldBasedFrameDecoder來處理客戶端和服務器端數據包幀解碼。我的消息是這種格式:\ r \ n $的LEN $ DATA \ r \ n $的LEN $ DATA

ChannelPipeline p = ch.pipeline(); 
p.addLast(new LengthFieldBasedFrameDecoder(1024,2,4,0,6)); 

根據不同的客戶端環境,Netty的圖書館可能會或可能不會在客戶端的連接和通信應用。但是通過這種消息結構,在編寫相對健壯和高效的幀解碼代碼時總是可以輕鬆實現。

+0

'LengthFieldBasedFrameDecoder'是正確的選擇 – user5698801

0

我認爲DelimiterFrameDecoder假定了一個無損的有序輸入流。如果您的管道中的低層傳輸層不是無損的有序連接,那麼您需要實現自己的幀解碼器,通過實施校驗和和幀ID或其他協議策略來處理丟失的數據和亂序幀。

+0

在嘈雜的無線網絡環境中,數據包丟失或無序可能非常普遍。但我認爲Netty中提供的DelimiterFrameDecoder或其他分隔符幀解碼器支持恢復(我的意思是最終能夠找到正確的開始數據包)來自混合了損壞或丟失字節的傳入字節流。這些解碼器與我之間的主要區別在於它的效率:1)快速定位新的良好起始數據包; 2)獲得良好數據包浪費更少的字節;但是我用LengthFieldBasedFrameDecoder發現了一個更簡單的方法。 –

+0

此外,對於數據包損壞或丟失,我實現了應用級邏輯,通過依靠來自接收方的ACK消息來執行有保證的消息傳遞。當然,消息必須在接收到ACK之前緩存,並且在接收到ACK之後將被刪除。 –