為什么會(huì)發(fā)生TCP粘包驼修、拆包呢?
發(fā)生TCP粘包竟闪、拆包主要是由于下面一些原因:
應(yīng)用程序?qū)懭氲臄?shù)據(jù)大于套接字緩沖區(qū)大小景殷,這將會(huì)發(fā)生拆包溅呢。
應(yīng)用程序?qū)懭霐?shù)據(jù)小于套接字緩沖區(qū)大小,網(wǎng)卡將應(yīng)用多次寫(xiě)入的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上猿挚,這將會(huì)發(fā)生粘包咐旧。
進(jìn)行MSS(最大報(bào)文長(zhǎng)度)大小的TCP分段,當(dāng)TCP報(bào)文長(zhǎng)度-TCP頭部長(zhǎng)度>MSS的時(shí)候?qū)l(fā)生拆包绩蜻。
接收方法不及時(shí)讀取套接字緩沖區(qū)數(shù)據(jù)铣墨,這將發(fā)生粘包。
……
如何處理粘包办绝、拆包問(wèn)題伊约?
知道了粘包、拆包問(wèn)題及根源孕蝉,那么如何處理粘包屡律、拆包問(wèn)題呢?TCP本身是面向流的降淮,作為網(wǎng)絡(luò)服務(wù)器超埋,如何從這源源不斷涌來(lái)的數(shù)據(jù)流中拆分出或者合并出有意義的信息呢?通常會(huì)有以下一些常用的方法:
使用帶消息頭的協(xié)議、消息頭存儲(chǔ)消息開(kāi)始標(biāo)識(shí)及消息長(zhǎng)度信息霍殴,服務(wù)端獲取消息頭的時(shí)候解析出消息長(zhǎng)度媒惕,然后向后讀取該長(zhǎng)度的內(nèi)容。
設(shè)置定長(zhǎng)消息来庭,服務(wù)端每次讀取既定長(zhǎng)度的內(nèi)容作為一條完整消息妒蔚。
設(shè)置消息邊界,服務(wù)端從網(wǎng)絡(luò)流中按消息編輯分離出消息內(nèi)容巾腕。
……
如何基于Netty處理粘包面睛、拆包問(wèn)題絮蒿?
DelimiterBasedFrameDecoder是基于消息邊界方式進(jìn)行粘包拆包處理的尊搬。
FixedLengthFrameDecoder是基于固定長(zhǎng)度消息進(jìn)行粘包拆包處理的。
LengthFieldBasedFrameDecoder是基于消息頭指定消息長(zhǎng)度進(jìn)行粘包拆包處理的土涝。
LineBasedFrameDecoder是基于行來(lái)進(jìn)行消息粘包拆包處理的佛寿。
用戶可以自行選擇規(guī)則然后使用Netty提供的對(duì)應(yīng)的Decoder來(lái)進(jìn)行具有粘包、拆包處理功能的網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)但壮。