基于Netty的计算器

基于Netty的计算器

服务器端:

  • NettyServer.java
package com.tust.netty;

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 NettyServer {
    public static void main(String[] args) throws Exception {
        //创建BossGroup 和 WorkerGroup
        //1.创建两个线程组,bossGroup 和 workerGroup
        //2. bossGroup 只是处理连接请求,workerGroup 处理和客户端有关的业务
        //3.两个都是无限循环
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //创建服务器端的启动对象,配置参数
            ServerBootstrap bootstrap = new ServerBootstrap();

            //使用链式编程来进行设置
            bootstrap.group(bossGroup,workerGroup)  //设置两个线程组
                    .channel(NioServerSocketChannel.class)    //使用 NioServerSocketChannel 作为服务器的通道实现
                    .option(ChannelOption.SO_BACKLOG,128)   //设置线程队列得到的连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE,true)   //设置保持活动连接状态
                    .childHandler(new ChannelInitializer<SocketChannel>() { //创建一个通道初始化对象(匿名对象)
                        //给 pipeline 设置处理器
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new NettyServerHandler());
                        }
                    }); //给我们的 workerGroup 的EventLoop 对应的管道设置处理器

            System.out.println("......服务器端 启动成功......");

            //绑定一个端口并且同步,生成了一个 ChannelFuture 对象
            //启动服务器(并绑定端口)
            ChannelFuture cf = bootstrap.bind(6668).sync();

            //对关闭通道进行监听
            cf.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

  • NettyServerHandler.java
package com.tust.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;


public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    //读取数据事件(这里我们可以读取客户端发送的消息)
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();
        //将 msg 转成一个 ByteBuf
        ByteBuf buf = (ByteBuf) msg;
        String mess = buf.toString(CharsetUtil.UTF_8);
        if (mess.equalsIgnoreCase("hello")){
            //给客户端发消息告诉它连接上服务器了
            ctx.writeAndFlush(Unpooled.copiedBuffer("world",CharsetUtil.UTF_8));
            return;
        }
        System.out.println(channel.remoteAddress().toString().substring(1)+" 发送的消息是:"+mess);
        String[] list = mess.split(" ");
        String result;
        //加法
        if(list.length == 3 && list[1].equals("+")){
            int leftNumber = Integer.parseInt(list[0]);
            int rightNumber = Integer.parseInt(list[2]);
            int sum = leftNumber + rightNumber;
            result = "计算结果是:" + mess+" = " + sum;
            System. out. println(result) ;
            ctx.writeAndFlush(Unpooled.copiedBuffer(result,CharsetUtil.UTF_8));
        }
        //减法
        if(list.length == 3 && list[1].equals("-")){
            int leftNumber = Integer.parseInt(list[0]);
            int rightNumber = Integer.parseInt(list[2]);
            int sum = leftNumber - rightNumber;
            result = "计算结果是:" + mess+" = " + sum;
            System. out. println(result) ;
            ctx.writeAndFlush(Unpooled.copiedBuffer(result,CharsetUtil.UTF_8));
        }
        //乘法
        if(list.length == 3 && list[1].equals("*")){
            int leftNumber = Integer.parseInt(list[0]);
            int rightNumber = Integer.parseInt(list[2]);
            int sum = leftNumber * rightNumber;
            result = "计算结果是:" + mess+" = " + sum;
            System. out. println(result) ;
            ctx.writeAndFlush(Unpooled.copiedBuffer(result,CharsetUtil.UTF_8));
        }
        //除法
        if(list.length == 3 && list[1].equals("/")){
            int leftNumber = Integer.parseInt(list[0]);
            int rightNumber = Integer.parseInt(list[2]);
            double sum = leftNumber / rightNumber;
            result = "计算结果是:" + mess+" = " + sum;
            System. out. println(result) ;
            ctx.writeAndFlush(Unpooled.copiedBuffer(result,CharsetUtil.UTF_8));
        }
    }

    //处理异常,一般是需要关闭通道的
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}

客户端:

  • NettyClient.java
package com.tust.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;


public class NettyClient {
    public static void main(String[] args) throws InterruptedException {
        //客户端需要一个事件循环组
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            //创建客户端启动对象
            //注意客户端使用的不是 ServerBootstrap 而是 Bootstrap
            Bootstrap bootstrap = new Bootstrap();

            //设置相关参数
            bootstrap.group(group) //设置线程组
                    .channel(NioSocketChannel.class) //设置客户端通道的实现类(反射)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new NettyClientHandler());    //加入自己的处理器
                        }
                    });

            System.out.println("......客户端 启动成功......");

            //启动客户端去连接服务器端
            //关于 ChannelFuture 要分析,涉及到 netty 的异步模型
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();
            //给关闭通道进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }

    }
}

  • NettyClientHandler
package com.tust.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.Scanner;


public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    //当通道就绪就会触发该方法
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //System.out.println("client ctx= "+ctx);
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello", CharsetUtil.UTF_8));
    }

    //当通道有读取事件时,会触发
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        String mess = buf.toString(CharsetUtil.UTF_8);
        if (mess.equalsIgnoreCase("world")){
            System.out.println("客户端已经连接上服务器了。");
        }else{
            System.out.println(mess);
        }

        //发送信息
        Scanner scanner = new Scanner(System.in);
        System.out.print("发送:");
        String str = scanner.nextLine();
        ctx.writeAndFlush(Unpooled.copiedBuffer(str,CharsetUtil.UTF_8));
    }

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

展示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值