【Netty】Socket 编程(C/S):基于Netty的Server、Client示例(简单注释)

首先引入 Netty 的依赖

<dependency>
     <groupId>io.nettygroupId>
     <artifactId>netty-allartifactId>
     <version>4.1.36.Finalversion>
dependency>

Server

public class NettyServer {
     
    public static void main(String[] args) {
     
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();

        try {
     
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            
            serverBootstrap.group(bossGroup,workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new NettyServerInitailizer())
                    .option(ChannelOption.SO_BACKLOG, 128);

            ChannelFuture channelFuture = serverBootstrap.bind(8000).sync();
            System.out.println("Netty Server started...");

            channelFuture.channel().closeFuture().sync();
        } catch (Exception e){
     
            e.printStackTrace();
        } finally {
     
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }

}
public class NettyServerInitailizer extends ChannelInitializer<SocketChannel> {
     
    @Override
    protected void initChannel(SocketChannel socketChannel) {
     
        ChannelPipeline pipeline = socketChannel.pipeline();
//        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
//        pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyServerHandler());
    }
}
/**
* SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter 的子类
*/
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
     
	
	/**
     * 有新的客户端连接时触发
     *
     * @param ctx 上下文对象, 含有通道channel,管道pipeline
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
     
        System.out.println("新的客户端..." + ctx.channel().remoteAddress());
    }
	
	/**
     * 读取客户端发送的数据
     *
     * @param ctx 上下文对象, 含有通道channel,管道pipeline
     * @param msg 就是客户端发送的数据
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
     
    	// 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
        System.out.println(ctx.channel().remoteAddress() +":" + msg);
        ctx.channel().writeAndFlush("Hello Client --"+ UUID.randomUUID().toString().substring(0,7));
    }
    
    /**
     * 处理异常, 一般是需要关闭通道
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
     
        cause.printStackTrace();
        ctx.close();
    }
}

Client

public class NettyClient {
     
    public static void main(String[] args){
     
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        
        try {
     
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new NettyClientInitailizer())
					
            ChannelFuture channelFuture = bootstrap.connect("localhost",8000).sync();
            System.out.println("Netty Client started...");

            channelFuture.channel().closeFuture().sync();
        } catch (Exception e){
     
            e.printStackTrace();
        }
        finally {
     
            eventLoopGroup.shutdownGracefully();
        }
    }
}
public class NettyClientInitailizer extends ChannelInitializer<SocketChannel> {
     
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
     
        ChannelPipeline pipeline = socketChannel.pipeline();
//        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
//        pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyClientHandler());
    }
}
public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
     
	
	/**
     * 当客户端连接服务器完成就会触发该方法
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
     
        System.out.println("成功连接到服务端..." + ctx.channel().remoteAddress());
        // 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
        ctx.writeAndFlush("Hello Server!");
    }
	
	/**
     * 当通道有读取事件时会触发,即服务端发送数据给客户端
     *
     * @param ctx 上下文对象, 含有通道channel,管道pipeline
     * @param msg 就是客户端发送的数据
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
     
        System.out.println("Server:"+ msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
     
        cause.printStackTrace();
        ctx.close();
    }
}

先后启动 Server 和 Client,结果如下:

【Netty】Socket 编程(C/S):基于Netty的Server、Client示例(简单注释)_第1张图片
【Netty】Socket 编程(C/S):基于Netty的Server、Client示例(简单注释)_第2张图片

你可能感兴趣的:(#,Netty,netty)