天天看點

如何使用netty自帶的編解碼器解決粘包/拆包問題?

世界上并沒有完美的程式,但是我們并不是以而沮喪,因為寫程式就是一個不斷追求完美的過程。

TCP以位元組流的形式進行傳輸,是以請求之間沒有分隔,是以要擷取準确的請求,需要解決請求的分段。

在這裡不做其他讨論,隻是提供一個親測可行的解決方案。

Server 和 Client 的Initializer中添加如下編解碼器:

channel.pipeline().addLast(new StringEncoder(Charset.forName("utf8")));
channel.pipeline().addLast(new LineBasedFrameDecoder(Integer.MAX_VALUE));
channel.pipeline().addLast(new StringDecoder(Charset.forName("utf8")));
           

有一點,注意順序,因為是職責鍊的調用模式,LineBasedFrameDecoder 一定在 StringDecoder 之前。

寫入資料時:

public void wt(ChannelHandlerContext ctx, String re) {
        re += "\n";
        ctx.writeAndFlush(re);
}
           

LineBasedFrameDecoder 是根據字元串末尾的 “\n” 或 “\r” 判斷是否同一請求的,是以每個請求寫入都以 “\n” 結尾,并且寫入的字元串中不能含有這兩個轉義字元。

讀取資料:

public String rd(Object msg) {
        return (String) msg;
 }