当前位置: 首页 > news >正文

netty

首先写在最前面的一点,关于netty5的用户指南,可以参照这里

img_aec7a0273952ad636d945144c1419362.png

img_a21ca7a7e2745d4614adf495d5a7eaef.png

img_523e8094d552dd3ab2a8d4bb000a1cf7.png

Netty的hello world

img_ef661cf5ddb04cc603466be438631fec.png

img_91c6721aeb986b5224a450de98be0178.png

一个经典的hello world程序有四个类,分布是Client,ClientHandler,Server,ServerHandler,下面是它们的代码

Client.java

package bhz.netty.helloworld;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
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 Client {

    public static void main(String[] args) throws Exception{
        
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(group)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                sc.pipeline().addLast(new ClientHandler());
            }
        });
        
        ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync();
        //ChannelFuture cf2 = b.connect("127.0.0.1", 8764).sync();
        //发送消息
        Thread.sleep(1000);
        cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes()));
        cf1.channel().writeAndFlush(Unpooled.copiedBuffer("666".getBytes()));
        //cf2.channel().writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));
        Thread.sleep(2000);
        cf1.channel().writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));
        //cf2.channel().writeAndFlush(Unpooled.copiedBuffer("666".getBytes()));
        
        cf1.channel().closeFuture().sync();
        //cf2.channel().closeFuture().sync();
        group.shutdownGracefully(); 
    }
}

ClientHandler.java

package bhz.netty.helloworld;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.util.ReferenceCountUtil;

public class ClientHandler extends ChannelHandlerAdapter{


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf buf = (ByteBuf) msg;
            
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            
            String body = new String(req, "utf-8");
            System.out.println("Client :" + body );
            String response = "收到服务器端的返回信息:" + body;
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

    }

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

}

Server.java

package bhz.netty.helloworld;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Server {

    public static void main(String[] args) throws Exception {
        //1 创建线两个程组 
        //一个是用于处理服务器端接收客户端连接的
        //一个是进行网络通信的(网络读写的)
        EventLoopGroup pGroup = new NioEventLoopGroup();
        EventLoopGroup cGroup = new NioEventLoopGroup();
        
        //2 创建辅助工具类,用于服务器通道的一系列配置
        ServerBootstrap b = new ServerBootstrap();
        b.group(pGroup, cGroup)     //绑定俩个线程组
        .channel(NioServerSocketChannel.class)      //指定NIO的模式
        .option(ChannelOption.SO_BACKLOG, 1024)     //设置tcp缓冲区
        .option(ChannelOption.SO_SNDBUF, 32*1024)   //设置发送缓冲大小
        .option(ChannelOption.SO_RCVBUF, 32*1024)   //这是接收缓冲大小
        .option(ChannelOption.SO_KEEPALIVE, true)   //保持连接
        .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                //3 在这里配置具体数据接收方法的处理
                sc.pipeline().addLast(new ServerHandler());
            }
        });
        
        //4 进行绑定 
        ChannelFuture cf1 = b.bind(8765).sync();
        //ChannelFuture cf2 = b.bind(8764).sync();
        //5 等待关闭
        cf1.channel().closeFuture().sync();
        //cf2.channel().closeFuture().sync();
        pGroup.shutdownGracefully();
        cGroup.shutdownGracefully();
    }
}

ServerHandler.java

package bhz.netty.helloworld;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class ServerHandler extends ChannelHandlerAdapter {


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("server channel active... ");
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "utf-8");
            System.out.println("Server :" + body );
            String response = "进行返回给客户端的响应:" + body ;
            ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
            //.addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx)
            throws Exception {
        System.out.println("读完了");
        ctx.flush();
    }

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

拆包粘包问题

img_ad55a9dbf9e44e2b718652bef9931e75.png

img_949f2b447fdd2e4ca0d5139a06d6dbf1.png

img_fdc709617b5d139c31aecf91ff9a0ee1.png

数据通信

心跳检测

数据上传下载

相关文章:

  • C++ 0x 之左值与右值、右值引用、移动语义、传导模板
  • Win2008学习(十一),解决Remote App Web访问的证书问题
  • 总结第一波~~~
  • Oracle数据库导出报componet'SET_NO_OUTLINES'must be declared的错
  • 关于java集合类TreeMap的理解(转)
  • 2018.10月iOS优质开源项目
  • 从数据出发
  • 树莓派 安装 刷Android Things 小结
  • mongoose 之ShemaType
  • ES6 的 Symbol 超出你想象的强大
  • poj1062
  • 解决iview多表头动态更改列元素发生的错误
  • 比特币淘金热席卷中国专业“挖矿机”受疯抢
  • Python的变量和常量
  • PHP——自定义比较算法
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • ComponentOne 2017 V2版本正式发布
  • HashMap ConcurrentHashMap
  • interface和setter,getter
  • spark本地环境的搭建到运行第一个spark程序
  • swift基础之_对象 实例方法 对象方法。
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Yeoman_Bower_Grunt
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 程序员该如何有效的找工作?
  • 从输入URL到页面加载发生了什么
  • 服务器从安装到部署全过程(二)
  • 欢迎参加第二届中国游戏开发者大会
  • 机器学习 vs. 深度学习
  • 目录与文件属性:编写ls
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • hi-nginx-1.3.4编译安装
  • 仓管云——企业云erp功能有哪些?
  • #include
  • #includecmath
  • #Java第九次作业--输入输出流和文件操作
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (1)bark-ml
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (排序详解之 堆排序)
  • (学习日记)2024.01.09
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • .gitattributes 文件
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .Net Remoting常用部署结构
  • .NET 解决重复提交问题
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)