Netty學習之分隔符解決TCP粘包
阿新 • • 發佈:2019-01-04
package com.phei.netty.s20160424; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * 服務端 * @author renhj * */ public class TimeServer { public void bind(int port) throws Exception{ //第一個使用者伺服器接收客戶端的連線 EventLoopGroup bossGroup = new NioEventLoopGroup(); //第二個使用者SocketChannel的網路讀寫 EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ //建立ServerBootstrap物件,啟動 NIO服務端的輔助啟動類 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup). //設定為NIO channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChildChannelHandler()); //繫結埠,同步等待成功 ChannelFuture f = b.bind(port).sync(); //等待伺服器監聽埠關閉 f.channel().closeFuture().sync(); }finally{ //釋放執行緒池資源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel arg0) throws Exception { //解決TCP粘包問題,以"$_"作為分隔 ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes()); arg0.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter)); arg0.pipeline().addLast(new StringDecoder()); arg0.pipeline().addLast(new TimeServerHandler()); } } public static void main(String[] args) throws Exception { int port = 8080; if(args != null && args.length>0){ try{ port = Integer.valueOf(args[0]); }catch(Exception e){ //採用預設值 } } new TimeServer().bind(port); } }