zoukankan      html  css  js  c++  java
  • netty Demo

    今天写了一个helloworld版本的netty程序,跟大家分享一下:

    首先需要的包是:netty-all-4.1.25.Final.jar

    客户端:

    StrClient.java

    package client;

    import java.net.InetSocketAddress;

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

    /**
    *1. 搞一个Bootstrop 对象
    *
    *2. 封装Bootstrop 对象
    *
    *3. 写Handler类 也就是所有的业务逻辑
    *
    * @author zx
    *
    */
    public class StrClient {
    //分配一个ip和端口号
    private String host;
    private int port;
    private NioEventLoopGroup nioEventLoopGroup;
    public StrClient(String host, int port) {
    this.host = host;
    this.port = port;
    }

    //启动项目 ip地址是 本地 端口号是888
    public static void main(String[] args) throws InterruptedException {
    new StrClient("localhost", 888).start();
    }

    public void start() throws InterruptedException {
    try {
    //客户端的引导类,启动网络客户端 Bootstrap有很多客户端的属性
    Bootstrap bootstrap = new Bootstrap();
    //可以理解成是一个线程池,用这个线程池来处理连接和接收数据
    nioEventLoopGroup = new NioEventLoopGroup();
    bootstrap.group(nioEventLoopGroup) //多线程处理,注册一下这个组
    .channel(NioSocketChannel.class) //制定通道类型是NioSocketChannel
    .remoteAddress(new InetSocketAddress(host, port)) //注册远程服务器的地址
    .handler(new ChannelInitializer<SocketChannel>() {
    //////////////↑模板代码/////////////
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
    //业务逻辑
    ch.pipeline().addLast(new StrClientHandler());
    }
    //////////////↓模板代码/////////////
    });
    //开始连接服务器
    ChannelFuture channelFuture = bootstrap.connect().sync(); //等到连接成功,否则一直阻塞线程
    channelFuture.channel().closeFuture().sync(); //接收数据之后阻塞
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    nioEventLoopGroup.shutdownGracefully().sync();
    }
    }
    }

    StrClientHandler.java

    package client;

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;

    public class StrClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    //客户端连接服务器后会调用 这里面可以发送请求
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    System.out.println("client -> 开始连接服务器发送数据...");
    byte[] bytes = "get current time".getBytes();
    ByteBuf buffer = Unpooled.buffer(bytes.length); //构造一个数组存数据
    buffer.writeBytes(bytes); //给buffer写数据 在数组里面写入的数据
    ctx.writeAndFlush(buffer); //将这个信息交给上下文 进入pipline 如果有第二个Handler也会把这个数据给这第二个Handler
    }

    //从服务器端接到数据之后
    @Override
    protected void channelRead0(ChannelHandlerContext ch, ByteBuf msg) throws Exception {
    System.out.println("client -> 读取服务器返回的对象...");
    //反序列化
    byte [] bytes = new byte [msg.readableBytes()]; //将这个2进制的数据写入数组里
    msg.readBytes(bytes); //实际上是写入数组中
    String messageBody = new String (bytes,"UTF-8");
    System.out.println("client -> 接到数据,内容是: " + messageBody);
    }

    //发生异常的时候会调用
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    //打印出错的原因
    cause.printStackTrace();
    //发生异常的时候就会关闭这个上下文,中断数据的传输
    ctx.close();
    }

    }

    服务端:

    StrServer.java

    package server;

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;

    public class StrServer {
    private int port;
    private NioEventLoopGroup nioEventLoopGroup;

    public StrServer(int port) {
    this.port = port;
    }

    public static void main(String[] args) throws InterruptedException {
    new StrServer(888).start();
    }

    private void start() throws InterruptedException {
    try {
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    nioEventLoopGroup = new NioEventLoopGroup();
    serverBootstrap.group(nioEventLoopGroup)
    .channel(NioServerSocketChannel.class)
    .localAddress("localhost", port)
    .childHandler(new ChannelInitializer<Channel>() {
    //业务逻辑
    @Override
    protected void initChannel(Channel ch) throws Exception {
    ch.pipeline().addLast(new StrServerHandler());
    }
    });
    ChannelFuture channelFuture = serverBootstrap.bind().sync();
    System.out.println("Server -> 服务启动成功 监听端口, " + port);
    channelFuture.channel().closeFuture().sync();
    }catch (Exception e) {
    e.printStackTrace();
    } finally {
    nioEventLoopGroup.shutdownGracefully().sync();
    }
    }
    }

    StrServerHandler.java

    package server;

    import java.util.Date;

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

    public class StrServerHandler extends ChannelInboundHandlerAdapter {

    /**
    *
    *@param ctx 上下文
    *@param msg 传来的具体的数据
    *
    */
    //读取客户端发来的数据 这个方法会被调起,在服务器读取数据的时候
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    System.out.println("Server -> 接到数据,开始处理...");
    ByteBuf buf = (ByteBuf)msg; //将传过来的ByteBuf强制转换
    byte [] req = new byte[buf.readableBytes()]; //2进制数组
    buf.readBytes(req); //将req的内容写到buf中
    //反序列化
    String requestbody = new String (req, "UTF-8");
    System.out.println("Server -> 客户端请求数据是: " + requestbody);
    System.out.println("Server -> 开始写回数据");
    String currentTime = new Date().toString();
    //封装了数据的输出
    ByteBuf copiedBuffer = Unpooled.copiedBuffer(currentTime.getBytes());
    ctx.write(copiedBuffer);

    }

    //数据读取完成会调起
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    ctx.flush();
    }


    //发生异常会被调用
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    ctx.close();
    cause.printStackTrace();
    }
    }

    运行服务端和客户端的main即可启动服务,

    1. 服务端准备接受客户端的请求信息;

    2. 客户端请求: get currentTime 

    3. 服务端获取到请求信息:get currentTime

    4. 服务端准备返回数据: String responseBody = new Date() . toString();

    5. 服务端返回数据

    6. 客户端获取服务端返回的数据

  • 相关阅读:
    Atitit 经济学常见的流派 古典主义与凯恩斯主义
    Atitit 学习方法 体系化学习方法 Excel 科目,分类,专业 三级分类。。 知识点。。 课程就是每一个知识点的详细化。。 比如经济学 类别 专业 xx概论知识点 3、金
    atiitt it学科体系化 体系树与知识点概念大总结.xlsx
    Atitit 减少财政支出普通人如何蹭政府补贴措施 attilax大总结.docx
    Atitit 信用管理概论 attilax学习心得
    Atitit.月度计划日程表 每月流程表v5
    Atitit 企业6大职能 attilax总结
    Atitit 常见每日流程日程日常工作.docx v8 ver ampm imp 签到 am y 天气情况检查 am y 晨会,每天或者隔天 am 每日计划(项目计划,日计划等。 am
    Atitit 财政赤字解决方案
    Atitit 建设自己的财政体系 attilax总结 1.1. 收入理论 2 1.2. 收入分类 2 1.3. 2 1.4. 非货币收入 2 1.5. 2 1.6. 降低期望 2 1.7.
  • 原文地址:https://www.cnblogs.com/zx947240023/p/9178843.html
Copyright © 2011-2022 走看看