范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

认识Netty之helloworld

  最近一直在看与IM相关的东西说到这个java中应该要说到netty,下面来认识一下netty.
  开始了解netty之前我们先了解下传统的IO编程.IO编程
  我们来做一个比较简单的demo:客户端每隔5秒发送一条消息到服务端,服务端收到消息打印出来.服务端实现
  Server 端首先创建了一个 serverSocket  来监听 8000 端口,然后创建一个线程,线程里面不断调用阻塞方法  serversocket.accept();  获取新的连接,当获取到新的连接之后,给每条连接创建一个新的线程,这个线程负责从该连接中读取数据,然后读取数据是以字节流的方式。 package com.pine.springbootdemo01.netty;  import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket;  /**  * @author anziyang  * @version V1.0  * @date 2022/3/1 11:53 上午  **/ public class IOServer {      public static void main(String[] args) throws Exception {          ServerSocket serverSocket = new ServerSocket(8000);          // 接收新连接线程         new Thread(() -> {             while (true) {                 try {                     // 阻塞方法获取新的连接                     Socket socket = serverSocket.accept();                      // 每一个新的连接都创建一个线程,负责读取数据                     new Thread(() -> {                         try {                             int len;                             byte[] data = new byte[1024];                             InputStream inputStream = socket.getInputStream();                             // 按字节流方式读取数据                             while ((len = inputStream.read(data)) != -1) {                                 System.out.println(new String(data, 0, len));                             }                         } catch (IOException e) {                             System.err.println(e);                         }                     }).start();                  } catch (IOException e) {                     System.err.println(e);                 }              }         }).start();     } } 客户端实现
  启动一个线程连接到服务端,循环中每次睡眠五秒也就是每隔五秒发送一次消息.package com.pine.springbootdemo01.netty;  import java.io.IOException; import java.net.Socket; import java.util.Date;  /**  * @author anziyang  * @version V1.0  * @date 2022/3/1 11:54 上午  **/ public class IOClient {      public static void main(String[] args) {         // 启动一个线程         new Thread(() -> {             try {                 Socket socket = new Socket("127.0.0.1", 8000);                 while (true) {                     try {                         socket.getOutputStream().write((new Date() + ": hello world socket").getBytes());                         // 睡眠5秒                         Thread.sleep(5000);                     } catch (Exception e) {                         System.err.println(e);                     }                 }             } catch (IOException e) {                 System.err.println(e);             }         }).start();     }  }
  先启动server端然后启动client可以看到server收到请求如下:
  上面的 demo,从服务端代码中我们可以看到,在传统的 IO 模型中,每个连接创建成功之后都需要一个线程来维护,每个线程包含一个 while true 死循环,那么 10w 个连接对应 10w 个线程,继而 10w 个 while 死循环,这就带来如下几个问题: 线程资源受限:线程是操作系统中非常宝贵的资源,同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费,操作系统耗不起 线程切换效率低下:单机 CPU 核数固定,线程爆炸之后操作系统频繁进行线程切换,应用性能急剧下降。 除了以上两个问题,IO 编程中,我们看到数据读写是以字节流为单位。
  为了解决这三个问题,JDK 在 1.4 之后提出了 NIO。
  NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。
  NIO编程
  java对于非堵塞I/O的支持是在2002年引入的,位于JDK1.4的java.nio包中.
  IO和NIO的区别: IO是面向字节流和字符流的,而NIO是面向缓冲区的。 IO是阻塞模式的,NIO是非阻塞模式的 NIO新增了选择器的概念,可以通过选择器监听多个通道。
  NIO用的是事件机制。它可以用一个线程把Accept,读,写操作,请求处理的逻辑全干了。如果什么事都没得做,它也不会死循环,它会将线程休眠起来,直到下一个事件来了再继续干活,这样的一个线程称之为NIO线程。
  package com.pine.springbootdemo01.netty;  import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set;  /**  * @author anziyang  * @version V1.0  * @date 2022/3/1 2:29 下午  **/ public class NIOServer {     public static void main(String[] args) throws IOException {         Selector serverSelector = Selector.open();         Selector clientSelector = Selector.open();         // 启动一个线程绑定select 用于监听是否有新的连接         new Thread(() -> {             try {                 // 对应IO编程中服务端启动                 ServerSocketChannel listenerChannel = ServerSocketChannel.open();                 listenerChannel.socket().bind(new InetSocketAddress(8000));                 listenerChannel.configureBlocking(false);                 listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT);                  while (true) {                     // 监测是否有新的连接,这里的1指的是阻塞的时间为 1ms                     if (serverSelector.select(1) > 0) {                         Set set = serverSelector.selectedKeys();                         Iterator keyIterator = set.iterator();                          while (keyIterator.hasNext()) {                             SelectionKey key = keyIterator.next();                              if (key.isAcceptable()) {                                 try {                                     // (1) 每来一个新连接,不需要创建一个线程,而是直接注册到 clientSelector                                     SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();                                     clientChannel.configureBlocking(false);                                     clientChannel.register(clientSelector, SelectionKey.OP_READ);                                 } finally {                                     keyIterator.remove();                                 }                             }                          }                     }                 }             } catch (IOException e) {                 System.err.println(e);             }          }).start();          // 启动一个线程绑定select 用于监听哪些连接有数据可读         new Thread(() -> {             try {                 while (true) {                     // (2) 批量轮询是否有哪些连接有数据可读,这里的1指的是阻塞的时间为 1ms                     if (clientSelector.select(1) > 0) {                         Set set = clientSelector.selectedKeys();                         Iterator keyIterator = set.iterator();                          while (keyIterator.hasNext()) {                             SelectionKey key = keyIterator.next();                              if (key.isReadable()) {                                 try {                                     SocketChannel clientChannel = (SocketChannel) key.channel();                                     ByteBuffer byteBuffer = ByteBuffer.allocate(1024);                                     // (3) 面向 Buffer                                     clientChannel.read(byteBuffer);                                     byteBuffer.flip();                                     System.out.println(Charset.defaultCharset().newDecoder().decode(byteBuffer)                                             .toString());                                 } finally {                                     keyIterator.remove();                                     key.interestOps(SelectionKey.OP_READ);                                 }                             }                          }                     }                 }             } catch (IOException e) {                 System.err.println(e);             }         }).start();     } }
  从上面的代码中我们可以看到NIO 模型中通常会有两个线程,每个线程绑定一个轮询器 selector ,在我们这个例子中 serverSelector  负责轮询是否有新的连接, clientSelector  负责轮询连接是否有数据可读 服务端监测到新的连接之后,不再创建一个新的线程,而是直接将新连接绑定到 clientSelector  上,这样就不用 IO 模型中 1w 个 while 循环在死等,参见(1) clientSelector  被一个 while 死循环包裹着,如果在某一时刻有多条连接有数据可读,那么通过  clientSelector.select(1)  方法可以轮询出来,进而批量处理,参见(2) 数据的读写面向 Buffer,参见(3)
  启动NIOServer main方法然后启动之前的client可以看到控制打印
  Netty编程
  首先看下netty如何实现服务端的:package com.pine.springbootdemo01.netty;  import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder;  /**  * @author anziyang  * @version V1.0  * @date 2022/3/1 2:41 下午  **/ public class NettyServer {      public static void main(String[] args) {         ServerBootstrap serverBootstrap = new ServerBootstrap();          NioEventLoopGroup boss = new NioEventLoopGroup();         NioEventLoopGroup worker = new NioEventLoopGroup();         serverBootstrap.group(boss, worker).channel(NioServerSocketChannel.class)                 .childHandler(new ChannelInitializer() {                     protected void initChannel(NioSocketChannel ch) {                         ch.pipeline().addLast(new StringDecoder());                         ch.pipeline().addLast(new SimpleChannelInboundHandler() {                                                         @Override                             protected void channelRead0(ChannelHandlerContext ctx,                                                         String msg) {                                 System.out.println(msg);                             }                                                      });                     }                 }).bind(8000);     }  }
  上面代码明显比前面的NIO少很多代码,优雅了不少.
  可以看到netty服务端输出内容:
  本文就先聊这么多,主要是熟悉下netty编程,看下经典的hello world.
  感觉有收获点个赞,转发下哦
  参考文档:
  https://juejin.cn/book/6844733738119593991/section/6844733738270588942
  https://www.jianshu.com/p/432d5557a19e
  https://www.cnblogs.com/flyingeagle/articles/11031163.html

可能你并不了解的关于房车的一些通用知识点1。电池与工频逆变器断开后需要重新连接时,必须遵守以下流程切断电池空开到OFF把1456行车充电器的输出端,连接(悬挂)到逆变器正负极启动汽车引擎引擎运行三十秒到一分钟后,测量逆变航天龙梦将协同信创产业更多生态伙伴开展核心技术联合攻关10月28日,以同芯同行,共创未来为主题的2021全国信创产业发展金华论坛在金华市金义保税区会展中心顺利召开。活动邀请了部委领导专家院士龙头企业代表,通过现场考察展览展示主旨演讲成转型新征程共创好公司富德生命人寿2021年五四青年节演讲比赛初赛河南分公司赛区活动成功举办为弘扬转型攻坚发展的组织文化,提升干部员工对专业化转型的认知水平和专业能力,4月8日,转型新征程?共创好公司富吉利牵手蔚来改造路特斯,前途光明又黑暗?这更像路特斯给自己重新划了一遍重点。8月31日,路特斯科技正式宣布其全球总部落户中国武汉。该总部位于武汉经济技术开发区,占地面积约186亩,建筑面积约39万平方米,距离位于汉南区的银保监会就意外伤害保险业务监管办法征求意见银保监会今日向各保险公司下发了意外伤害保险业务监管办法(征求意见稿),对意外伤害保险的经营行为进行规范。征求意见稿明确,意外险按保险期限分为长期意外险和短期意外险。长期意外险是指保经开区管委会开展美丽河南我是行动者文明行为主题培训中国公益在线郑州讯(公益记者张文孟)为助力郑州市全国文明城市创建工作顺利推进,全面提升经开区各单位机关干部文明程度,倡导文明健康的生活方式增强大家的环保意识。3月31日,区文明办邀青春心向党厚植爱国情2021年是中国共产党成立100周年,扎实推动党史学习教育走进青少年儿童至关重要。为厚植辖区青少年儿童的爱国意识爱党意识,坚定孩子们的爱国心入党情,4月4日下午郑州市丰庆路街道杲村解散谣言背后,上汽斯柯达危机难掩?继铃木之后,下一个退出中国的品牌,是哪一个?斯柯达,成为了传闻中的主角。近期,有汽车媒体报道称,斯柯达已经解散了在华营销团队,后续研发团队也将解散,并且这一消息得到了多方证实。不过未量产或破产,拜腾的造车故事并不凄凉?近年来,拜腾汽车的每次出场似乎都有丝凄凉。7月12日,公开信息显示,拜腾汽车关联公司南京知行新能源汽车技术开发有限公司被申请破产重整,申请人是上海华讯网络系统有限公司。对此,拜腾汽加冕设计界奥斯卡!恒大如何步步为营造好车?恒大汽车的产品创新力再获认可。近日,恒驰1凭借惊艳造型,摘得2021年德国红点设计大奖。分析认为,恒驰首次参评便斩获大奖,展现了恒大汽车在汽车造型设计领域的强大实力。近年来,处于风富德生命人寿郑州中支开展总经理接待日活动为了保障消费者的合法权益,切实维护国家和消费者利益,富德生命人寿郑州中支于2021年8月6日开展8月份总经理接待日活动,旨在通过有效沟通,现场处理各类咨询与投诉,并广泛听取客户意见
win10win7家庭版系统共享打印机不可缺少的设置家庭版系统减少了很多功能,只能满足日常使用,大家有没有发现,比如共享打印机无法连接,这时候就用到组策略了,但是打开组策略提示找不到文件,那么这时候就需要给系统添加组策略功能了必备的AppleWatch摔撞功能救人先进事迹,闲置回收上正二品AppleWatch健康功能是一部分消费者购买它的一大原因,其急救功能在关键时刻十分重要。近日,AppleWatch紧急呼叫功能拯救骑手事件被推上头条,实际证明AppleWatch小米手机公布二次元形象?仅一天官方就删帖,评论区又被阿宅开冲导读小米手机二次元,按理说这两个貌似没有什么直接联系。但是近期,小米手机在阿哔上的官号却被二次元的阿宅们开冲了,也让众多粉丝纷纷取关,这又是怎么一回事呢?雷军的小米的手机,在业界一红米手机当时的销量之最?千元机的标杆手机红米是小米旗下的追求性价比的品牌,最先是跟着老大哥小米的脚步,干翻了千元以下的山寨机,2019年红米传承了小米的性价比衣钵,正式掌握了小米的性价比市场,开启了红米性价比元年,小米则只卖了2000辆,竟扬言吊打特斯拉!贾跃亭昔日的偶像,还在忽悠?文金错刀中国新能源车企,真是越来越有底气(嚣张)了。有这样一家车企,2017年才成立,就敢跑到北京上海纽约伦敦东京,打广告,高调挑战世界巨头。而且,一口气挑战了三大巨头!HiTes你有没有思考过,特斯拉为什么先进?图片来源unsplash文丨锦缎特斯拉(NASDAQTSLA)在中国,就像折耳根在中国小吃界的地位,有人深爱,也有人痛绝。有人认为特斯拉就是工业垃圾,粗糙的内饰,门缝都对不齐的做工4亿套走董明珠26亿,魏银仓卷10亿出走美国,烂摊子却成世界500强大家都知道格力的董明珠是业内的女强人,其经营能力和个人水平几乎是女性企业家的典范,但即便如此,在国内仍有一个人通过画饼的方式,骗了董明珠26亿,这是怎么回事呢?董明珠的造车梦随着国花20多万买纯电动汽车,10年之后算一笔账,看到结果还会选电车吗两任纯电动汽车车主,开了6年多的纯电动汽车,有话想吐槽,谈谈5点真实的用车感受,纯电动汽车3点优势很明显,但两大缺点才是硬伤,如果只是单纯为了省钱而选择纯电动车,那奉劝车友三思而后重心向东南亚转移受挫,国内市场也失守,郭台铭被库克坑惨了众所周知,富士康和苹果的关系十分的密切,富士康就是为苹果而生,每年都要从苹果手机获得大量的订单。富士康在代工领域能做到全球第一,很大原因是因为苹果。所以一直以来富士康对苹果都是言听中国量子计算机太强了比世界第一超算还快一亿亿亿倍量子计算机,一直是我国引领世界的领域,九章量子计算机则是这个领域的标杆。不过最近我国的工程技术人员再一次刷新了这个标杆。去年12月,中国研制成功的量子计算机九章,求解高斯玻色取样数这是一款80年代根德公司推出的Satellit2400SL多波段便携式收音机这款根德GrundigSatellit2400SL便携式收音机制造于1980年,在技术和光学方面都处于非常好的状态,这种形状很难找到第二个。这款坚固且非常重的收音机带有黑色收音机机