2019独角兽企业重金招聘Python工程师标准>>>

java的网络工具netty简介

Netty是一个NIO的客服端服务器框架,它可以简单、快速的搭建器一个协议包客服端服务器的应用程序。它极大的简化了TCP和UDP这类的网络编程。

“快速”和“简单”并不意味着会让你的最终应用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

这里简单记录下学习要点,详细的讲解。可以看官网(github:https://github.com/netty/netty )或者查看李林锋的的系列文章http://ifeve.com/author/linfeng/ 。

体系结构图:

由李林锋讲解的易懂的架构图:

1、两个selector线程:mainReactor处理accpet事件、subReactor处理connection、read、send事件

2、业务处理线程池:包括编码、解码、业务处理。

1、官网案例

  a、处理bytes的serverhandler

/*** @see 进入的channel:用于处理接受时候的事件处理*/
public class TimeServerHandler extends ChannelInboundHandlerAdapter {/*** @see 当一个channel准备好的时候,发送一个32位的数字*/public void channelActive(final ChannelHandlerContext ctx) {// ByteBuf:没有了flip()。它只有2个功能:读、写// 读:// 写:当你写的时候,如果读取下标没有改变,则继续增长final ByteBuf time = ctx.alloc().buffer(4);time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));final ChannelFuture f = ctx.writeAndFlush(time);// 当写如完成的时候,执行f.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture future) throws Exception {// TODO Auto-generated method stubassert f == future;ctx.close();}});}public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

    sever的启动部分

public class TimeServer {private int port;public TimeServer() {this.port = port;}public void runn() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup);b.channel(NioServerSocketChannel.class);b.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new TimeServerHandler());}});b.option(ChannelOption.SO_BACKLOG, 128);b.childOption(ChannelOption.SO_KEEPALIVE, true);ChannelFuture f = b.bind(port).sync();f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) {try {new TimeServer().runn();} catch (Exception e) {e.printStackTrace();}}
}

b、client部分:处理字节

public class TimeDecoder extends ByteToMessageDecoder {/*** @see 定义一个回调的数据累加buff* @see 如果有out,则表示解析成功。*/@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {if (in.readableBytes() < 4) {return;}out.add(in.readBytes(4));}}

client的 channel处理类

public class TimeClientHandler extends ChannelInboundHandlerAdapter {public void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf buf = (ByteBuf) msg;try {long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L;System.out.println(new Date(currentTimeMillis));ctx.close();} catch (Exception e) {e.printStackTrace();} finally {buf.release();}}public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

client的启动类:

public class TimeClient {public static void main(String[] args) throws InterruptedException {String host = args[0];int port = Integer.parseInt(args[1]);EventLoopGroup workerGroup = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();// 启动客服端连接b.group(workerGroup);// 同时用于主线程和工作线程b.channel(NioSocketChannel.class);// 客服端需要的channelb.option(ChannelOption.SO_KEEPALIVE, true); // socketChannel没有父类b.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new TimeClientHandler());}});ChannelFuture f = b.connect(host, port).sync();f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();}}
}

2、stream处理

小型buffer的socket传送流传输依据TCP/IP,接受的数据是储存在一个接受的socket的buffer中。但是,传送的buffer不是一个队列包、而是一个队列btyes。这就意味着,即使你使用两个包去传送两端信息,系统不会将它们视为两端信息,而是作为一串bytes。因此,这不能保证你读去的数据是你远程写入的数据。例如,我们需要使用系统的TCP/IP栈接受到3个数据包。

因为根据流协议,你很有可能在你的应用中读取到你下面的部分

因次,在服务器和客服端的接受部分,对接受数据必须定义一个协议的框架(处理方式),这个框架能够被应用程序使用。接收到的部分必须是下面这种方式。

a、第一种解决方式:

在TIME client的实例中。我们同样是有一个相似的问题,一个非常小的32位bit的整数数据,它不太可能分散。然而,随着流量的增加,问题是它会碎片化。

简单的解决方式,增加一个内部的累加buffer,然后将接受的4bytes传输到这个buffer中。在TimeClientHandler直接修改

public class TimeClientHandler2 extends ChannelInboundHandlerAdapter {private ByteBuf buf;@Overridepublic void handlerAdded(ChannelHandlerContext ctx) {buf = ctx.alloc().buffer(4);}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) {buf.release();buf = null;}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf m = (ByteBuf) msg;buf.writeBytes(m);m.release();if (buf.readableBytes() >= 4) {long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L;System.out.println(new Date(currentTimeMillis));ctx.close();}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

b、第二种就是前面的实例方式、将decode分离出来处理。看起来清晰、方便

3、编解object数据

object

public class UnixTime {private final long value;public UnixTime() {this(System.currentTimeMillis() / 1000L + 2208988800L);}public UnixTime(long value) {this.value = value;}public long value() {return this.value;}public String toString() {return new Date((value() - 2208988800L) * 1000L).toString();}}

object:decode

public class TimeDecoder2 extends ByteToMessageDecoder {/*** @see 定义一个回调的数据累加buff* @see 如果有out,则表示解析成功。*/@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {if (in.readableBytes() < 4) {return;}out.add(new UnixTime(in.readUnsignedInt()));}
}

objec:encode

public class TimeEncoder extends ChannelOutboundHandlerAdapter {public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {UnixTime m = (UnixTime) msg;ByteBuf encoded = ctx.alloc().buffer(4);encoded.writeInt((int) m.value());ctx.write(encoded, promise);}

server:handler

public class TimeServerHandler2 extends ChannelInboundHandlerAdapter {/*** @see 当一个channel准备好的时候,发送一个32位的数字*/public void channelActive(final ChannelHandlerContext ctx) {// ByteBuf:没有了flip()。它只有2个功能:读、写// 读:// 写:当你写的时候,如果读取下标没有改变,则继续增长final ByteBuf time = ctx.alloc().buffer(4);time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));final ChannelFuture f = ctx.writeAndFlush(new UnixTime());// 当写如完成的时候,执行f.addListener(ChannelFutureListener.CLOSE);}public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

client:handler

public class TimeClientHandler3 extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {UnixTime m = (UnixTime) msg;System.out.println(m);ctx.close();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

转载于:https://my.oschina.net/u/2246410/blog/652313

java的网络工具netty简介相关推荐

  1. 你对Java网络编程了解的如何?Java BIO 网络编程 | Netty 前期知识

    一步一步走来,之前去学习了JUC并发编程知识,现在终于到Java IO网络编程啦,难啊. 一.BIO介绍 引入: 随着技术的发展,两个或以上的程序必然需要进行交互,于是提供了一种端到端的通信,相当于对 ...

  2. 你对Java网络编程了解的如何?Java NIO 网络编程 | Netty前期知识(二)

    本文主要讲解NIO的简介.NIO和传统阻塞I/O有什么区别.NIO模型和传统I/O模型之间的对比.以及围绕NIO的三大组件来讲解,理论代码相结合. 很喜欢一句话:"沉下去,再浮上来" ...

  3. java 多版本管理工具_简介linux下的多版本管理工具—alternatives

    alternatives是Unix下重要的版本管理工具,它最早是在debain的系统中出现,因为它强大实用性使得它在各个Unix环境中大量的移植使用,而我们在平时的时候可能最经常使用的是java的op ...

  4. Java代码混淆工具ProGuard

    目录 Java代码混淆工具ProGuard 简介 描述 作用的环境 功能 工作原理 下载 使用时注意事项 版本问题 JDK位数问题 Java的字节码验证问题 关于使用类似于Hibernate的对象关系 ...

  5. Netty:Java 领域网络编程的王者

    一.简介 1. 课程背景 分布式系统的根基在于网络编程,而 Netty 是 Java 领域网络编程的王者. 2. 课程内容 第一部分 NIO 编程,三大组件 第二部分 Netty 入门学习,Event ...

  6. Java网络编程 — Netty入门

    认识Netty Netty简介 Netty is an asynchronous event-driven network application framework for rapid develo ...

  7. Linux 中的 netcat 网络工具简介

    Linux 中的 netcat 网络工具简介 Apr 3, 2020 |  Linux |  linux netcat netcat 是 Linux 系统中的网络工具,其通过 TCP 和 UDP 协议 ...

  8. java 复杂网络分析_基于复杂网络的Java程序分析工具设计与实现思路浅谈

    基于复杂网络的Java程序分析工具设计与 实现思路浅谈 摘要:近年来,随着科学技术的进步,计算机技术发展速度的加快,使得软件价值也逐步提高,不管是软件系统的应用领域,还是其规模均获得了相应的扩大,且软 ...

  9. 网络工具中的瑞士军刀——netcat工具简介

    今天给大家带来netcat这款工具的简单介绍.netcat有着"网络工具中的瑞士军刀"的绰号.它体积小巧,功能却又十分强大.下面的内容包括,man手册翻译.常用参数介绍及例子. 一 ...

最新文章

  1. C语言close函数
  2. 由神经网络的迭代次数计算输出值并评价网络性能
  3. 盘点 12 个 GitHub 上的高仿项目
  4. 【MM 模块】 Optimized Purchasing 优化采购 2
  5. [云炬创业基础笔记]第六章商业模式测试20
  6. matlab自带kfcm函数,kfcmFun.m
  7. Eigen 矩阵计算工具
  8. 1002. 三角形 (
  9. 《研磨设计模式》builder生成器模式(golang)
  10. 人工智能培训机构-光环国际,开课吧,贪心学院,交大,黑马,七月在线,咕泡,百战程序员哪个靠谱?
  11. Gitlab-Runner安装并注册
  12. AES加密解密C语言实现
  13. python提取微信聊天语音_GitHub - dennischancs/wechat-asr: 微信语音批量转文字 python编写 用百度智能云短语音识别API实现 windows下的使用...
  14. DelphiXE Update1
  15. android界面UI美化:沉浸模式、全透明或半透明状态栏及导航栏的实现
  16. 记录自己学习尚硅谷javaweb2022版中遇到的一些问题
  17. Silvaco TCAD仿真8——网格mesh的意义(举例说明)
  18. Vim查找、替换与删除常用命令
  19. win10如何调整计算机时间同步,Win10系统如何设置时间同步间隔?修改时间同步频率的方法...
  20. vue 前端生成二维码,并转换为图片

热门文章

  1. 如何集成Spring和Struts(实例说明)
  2. Android 关闭软键盘
  3. Mariadb的安装与配置
  4. 干得累死,并不见得老板就待见你?
  5. c#操作Xml(八)
  6. 我程序中用到的第一个递归算法
  7. java二叉树 最大值_leetcode刷题笔记-654. 最大二叉树(java实现)
  8. linux桌面服务器系统下载,Ubuntu 14.10 中文桌面版/服务器正式版下载
  9. RabbitMQ工作队列
  10. 回顾线程的竞争机制-重量级锁