Netty入门P5

客户端发送数据至服务端

示例代码Client.java

/**
 * @program: learnnetty
 * @description: 客户端发送数据
 * @create: 2020-05-04 10:31
 **/
public class Client {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        Bootstrap bootstrap = new Bootstrap();
        bootstrap
                .group(workerGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel
                                .pipeline()
                                .addLast(new ClientHandler());
                    }
                });

        bootstrap.connect("127.0.0.1", 8080);
    }
}

上述代码中:

  1. SocketChannel.pipline()返回的是这条连接的相关逻辑处理链,采用的是责任链的设计模式;
  2. 通过调用SocketChannel.pipline().addLast()给处理链添加一个逻辑处理器;

示例代码ClientHandler.java

/**
 * @program: learnnetty
 * @description: 业务处理
 * @create: 2020-05-04 10:39
 **/
public class ClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(new Date() + " 客户端写出数据");
        ByteBuf buffer = getByteBuf(ctx, "这是客户端");
        ctx.channel().writeAndFlush(buffer);
    }

    private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
        ByteBuf byteBuf = ctx.alloc().buffer();
        byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
        byteBuf.writeBytes(bytes);
        return byteBuf;
    }
}

上述代码中:

  1. 自定义的逻辑处理器需要继承ChannelInboundHandlerAdapter类,并重写channelActive()方法,此方法会在客户端建立连接成功后被调用;
  2. 在成功连接后,调用channelActive()方法时自定义的逻辑处理器就会发挥作用;
  3. 自定义的逻辑处理器处理业务分为两步:
    1. 获取Netty对二进制数据的抽象ByteBuf,示例代码中通过ChannelHandlerContext.alloc()获取到一个ByteBuf的内存管理器,此内存管理器就是分配一个ByteBuf;
    2. 将字符串按照指定的字符集转换为二进制数据并填充至ByteBuf中,之后再调用ChannelHandlerContext.channel().writeAndFlush()把数据写出;

服务端读取客户端数据

示例代码Server.java

/**
 * @program: learnnetty
 * @description: 服务端
 * @create: 2020-05-04 10:54
 **/
public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel
                                .pipeline()
                                .addLast(new ServerHandler());
                    }
                });
        serverBootstrap.bind(8080);
    }
}

示例代码ServerHandler.java

/**
 * @program: learnnetty
 * @description: 服务端处理
 * @create: 2020-05-04 10:54
 **/
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf)msg;
        System.out.println(new Date() + " :服务端收到:" + byteBuf.toString(StandardCharsets.UTF_8));
    }
}

在上述代码中:

服务端输出:

Mon May 04 11:01:19 CST 2020 :服务端收到:这是客户端

客户端输出:

Mon May 04 11:01:19 CST 2020 客户端写出数据

服务端返回数据给客户端

修改后的ServerHandler.java

/**
 * @program: learnnetty
 * @description: 服务端处理
 * @create: 2020-05-04 10:54
 **/
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //读取数据
        ByteBuf byteBuf = (ByteBuf)msg;
        System.out.println(new Date() + ",服务端收到:" + byteBuf.toString(StandardCharsets.UTF_8));
        //给予反馈
        System.out.println(new Date() + ",服务端写出数据");
        ByteBuf buff = getByteBuf(ctx, "服务端已收到信息");
        ctx.channel().writeAndFlush(buff);
    }

    private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
        byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeBytes(bytes);
        return buf;
    }
}

修改后的ClientHandler.java

/**
 * @program: learnnetty
 * @description: 业务处理
 * @create: 2020-05-04 10:39
 **/
public class ClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf)msg;
        System.out.println(new Date() + ",客户端收到来自服务端的反馈:" + byteBuf.toString(StandardCharsets.UTF_8));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(new Date() + " 客户端写出数据");
        ByteBuf buffer = getByteBuf(ctx, "这是客户端");
        ctx.channel().writeAndFlush(buffer);
    }

    private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
        ByteBuf byteBuf = ctx.alloc().buffer();
        byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
        byteBuf.writeBytes(bytes);
        return byteBuf;
    }
}

服务端输出:

Mon May 04 11:07:52 CST 2020,服务端收到:这是客户端
Mon May 04 11:07:52 CST 2020,服务端写出数据

客户端输出:

Mon May 04 11:07:52 CST 2020 客户端写出数据
Mon May 04 11:07:52 CST 2020,客户端收到来自服务端的反馈:服务端已收到信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值