Java进阶作业五:使用Netty写一个EchoServer

写在开头

本文使用网络通信框架Netty实现一个EchoSever。所谓EchoServer就是服务器将客户端发送的消息原样返回给客户端。运行下面的代码需要提前准备Netty依赖包,我这里使用的是Netty 4.x。

服务端

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyEchoSever {

    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                           // 配置消息处理器
                            socketChannel.pipeline().addLast(new MsgHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // 启动服务器
            ChannelFuture f = b.bind(8888).sync();
            System.out.println("server start....");
            f.channel().closeFuture().sync();

        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    static class MsgHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            // 消息处理器做的事情就是将收到的数据原样发送给客户端
            ctx.writeAndFlush(msg);
        }
    }
}

客户端

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class NettyEchoClient {

    public static void main(String[] args) throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 配置一个消息处理器
                            socketChannel.pipeline().addLast(new MsgSendHandler());
                        }
                    });

            // 连接服务器
            ChannelFuture f = b.connect("127.0.0.1", 8888).sync();
            f.channel().closeFuture().sync();

        }finally {
            group.shutdownGracefully();
        }
    }

    static class MsgSendHandler extends ChannelInboundHandlerAdapter {

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            // 连接建立之后,读取控制台输入,发送给服务器
            sendMsgToServer(ctx);
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            // 打印服务器的响应
            ByteBuf rcvBuf = (ByteBuf) msg;
            String resp = rcvBuf.toString(StandardCharsets.UTF_8);
            System.out.println("server resp:" + resp);
            rcvBuf.release();

            // 发送消息给服务器
            sendMsgToServer(ctx);
        }

        private void sendMsgToServer(ChannelHandlerContext ctx) {
            Scanner in = new Scanner(System.in);
            System.out.print("send msg to server:");
            String input = in.nextLine();
            ByteBuf buf = ctx.alloc().buffer(1024);
            buf.writeBytes(input.getBytes());
            ctx.writeAndFlush(buf);
        }
    }
}

运行结果

posted @ 2021-06-01 12:44  陈玉林  阅读(208)  评论(0编辑  收藏  举报