欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-27 10:42:02
首先引入 Netty 的依赖 io.netty netty-all 4.1.36.FinalServerpublic class NettyServer { public static vo...

首先引入 Netty 的依赖

<dependency>
     <groupId>io.netty</groupId>
     <artifactId>netty-all</artifactId>
     <version>4.1.36.Final</version>
</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示例(少注释)
【Netty】Socket 编程(C/S):基于Netty的Server、Client示例(少注释)

本文地址:https://blog.csdn.net/weixin_43935927/article/details/111993298