1. 概述

Netty是由JBOSS提供的一个java开源框架。
Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

  2.体系结构图

Netty的核心结构

Netty是典型的Reactor模型结构,在实现上,Netty中的Boss类充当mainReactor,NioWorker类充当subReactor(默认NioWorker的个数是当前服务器的可用核数)。

在处理新来的请求时,NioWorker读完已收到的数据到ChannelBuffer中,之后触发ChannelPipeline中的ChannelHandler流。

Netty是事件驱动的,可以通过ChannelHandler链来控制执行流向。因为ChannelHandler链的执行过程是在subReactor中同步的,所以如果业务处理handler耗时长,将严重影响可支持的并发数。

发一下Netty的架构

 
Server1

public static void main(String[] args) throws Exception {
//启动server服务
new NettyServer().bind(8089);
}

NettyServer

  public void bind(int port) throws Exception {

EventLoopGroup bossGroup = new NioEventLoopGroup(); //bossGroup就是parentGroup,是负责处理TCP/IP连接的
EventLoopGroup workerGroup = new NioEventLoopGroup(); //workerGroup就是childGroup,是负责处理Channel(通道)的I/O事件

ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128) //初始化服务端可连接队列,指定了队列的大小128
.childOption(ChannelOption.SO_KEEPALIVE, true) //保持长连接
.childHandler(new ChannelInitializer<SocketChannel>() { // 绑定客户端连接时候触发操作
@Override
protected void initChannel(SocketChannel sh) throws Exception {
// sh.pipeline().addLast(new StringEncoder(Charset.forName("gbk")));
// sh.pipeline().addLast(new StringDecoder(Charset.forName("gbk")));
sh.pipeline().addLast("decoder", new MyDecode());
sh.pipeline() .addLast(new ServerHandler()); //使用ServerHandler类来处理接收到的消息
}
});
//绑定监听端口,调用sync同步阻塞方法等待绑定操作完
ChannelFuture future = sb.bind(port).sync();

if (future.isSuccess()) {
System.out.println("服务端启动成功");
} else {
System.out.println("服务端启动失败");
future.cause().printStackTrace();
bossGroup.shutdownGracefully(); //关闭线程组
workerGroup.shutdownGracefully();
}

//成功绑定到端口之后,给channel增加一个 管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程。
future.channel().closeFuture().sync();

}

MyDecode 是我自己编写的一个解析16进制的类,编码器
public class MyDecode extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
byte[] b = new byte[byteBuf.readableBytes()];
//复制内容到字节数组b
byteBuf.readBytes(b);
//字节数组转字符串
String str = new String(b);
list.add(bytesToHexString(b));
}

public String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}

public static String toHexString1(byte[] b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < b.length; ++i) {
buffer.append(toHexString1(b[i]));
}
return buffer.toString();
}

public static String toHexString1(byte b) {
String s = Integer.toHexString(b & 0xFF);
if (s.length() == 1) {
return "0" + s;
} else {
return s;
}
}

public static byte[] hexString2Bytes(String hex) {
if ((hex == null) || (hex.equals(""))){
return null;
}else if (hex.length()%2 != 0){
return null;
}else{
hex = hex.toUpperCase();
int len = hex.length()/2;
byte[] b = new byte[len];
char[] hc = hex.toCharArray();
for (int i=0; i<len; i++){
int p=2*i;
b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p+1]));
}
return b;
}
}

private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}

public static void main(String[] args) throws Exception {
String fan="烦";
String str = URLEncoder.encode(fan, "utf-8").replaceAll("%", "");
System.err.println(str);

}
}

ServerHandler


@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
try {
  System.out.println(msg.toString);
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}

// @Override
// public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// RpcRequest request = (RpcRequest) msg;
// System.out.println("接收到客户端信息:" + request.toString());
// //返回的数据结构
// RpcResponse response = new RpcResponse();
// response.setId(UUID.randomUUID().toString());
// response.setData("server响应结果");
// response.setStatus(1);
// ctx.writeAndFlush(response);
// }

//通知处理器最后的channelRead()是当前批处理中的最后一条消息时调用
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}

//读操作时捕获到异常时调用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}

//客户端去和服务端连接成功时触发
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {

try {
int strLen = 34;
StringBuffer sb = null;
while (classpath.length() < strLen) {
sb = new StringBuffer();
//sb.append("0").append(_16);// 左补0
sb.append(classpath).append("0");//右补0
classpath = sb.toString();
}
System.err.println("sb=" + sb);
String str = "ADBA000160002546323160ACC70014CB142701" + classpath + "FE";
String byte16 = "ADBA000120000B020195FE";
ByteBuf bytebuf = Unpooled.buffer(16);
ByteBuf bytebuf1 = Unpooled.buffer(16);
byte[] bytes = MyDecode.hexString2Bytes(byte16);
byte[] bytes1 = MyDecode.hexString2Bytes(str);
bytebuf1.writeBytes(bytes1);
bytebuf.writeBytes(bytes);
ctx.writeAndFlush(bytebuf);
for (int i = 0; i < 2; i++) {
if (i == 1) {
ctx.writeAndFlush(bytebuf + "\n");
} else {
//ctx.writeAndFlush(bytebuf1 + "\n");
}
}
ctx.flush();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
  代码就上了,这样16进制和读不到的问题就解决了。

Netty介绍与认识的更多相关文章

  1. Netty In Action中文版 - 第一章:Netty介绍

    本章介绍 Netty介绍 为什么要使用non-blocking IO(NIO) 堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照 Java NIO的问题和在Nett ...

  2. 第一章:Netty介绍

    1. Netty介绍  Netty是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端,Netty是基于NIO实现的,所以整个Netty都是异步操作,网络应用 ...

  3. 《精通并发与Netty》学习笔记(01 - netty介绍及环境搭建)

    一.Netty介绍     Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.     ...

  4. Netty快速入门(06)Netty介绍

    前面简单的介绍了Java I/O 和NIO,写了示例程序. Java I/O是阻塞的,为了让它支持多个并发,就要针对每个链接启动线程,这种方式的结果就是在海量链接的情况下,会创建海量的线程,就算用线程 ...

  5. netty介绍与构成

    什么是 Netty Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架.Netty 提供高性能和可扩展性,让你可以自由地专注于你真 ...

  6. Netty 介绍

    本指南对Netty 进行了介绍并指出其意义所在. 1. 问题 现在,我们使用适合一般用途的应用或组件来和彼此通信.例如,我们常常使用一个HTTP客户端从远程服务器获取信息或者通过web service ...

  7. 第2章 netty介绍与相关基础知识

    NIO有一个零拷贝的特性.Java的内存有分为堆和栈,以及还有字符串常量池等等.如果有一些数据需要从IO里面读取并且放到堆里面,中间其实会经过一些缓冲区.我们要去读,它会分成两个步骤,第一块它会把我们 ...

  8. Netty介绍

    Netty是由JBOSS开发的高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输等协议的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Li ...

  9. 002——Netty之Netty介绍

    Netty出现背景 Java NIO难用 据说存在bug 业界其他NIO框架不成熟 Netty主要解决两个相应关注领域 (1)异步和事件驱动的实现. (2)一组设计模式,将应用逻辑与网络层解耦. 特性 ...

  10. Netty 介绍和应用场景(一)

    1.为什么选择Netty 需要了解了Socket通信(IO/NIO/AIO)编程,对于通信模型已经有了一个基本的认识.,果想把这些真正的用于实际工作中,那么还需要不断的完善.扩展和优化.比如经典的TC ...

随机推荐

  1. 鸣人的影分身【按照前i个数,最小数是不是0,建立转移方程】

    鸣人的影分身 题意 鸣人最多有n个分身,m的能量.分身的能量可以为0. 问有多少种方案数. 思路 很容易定义状态:f[i] [j]: 前i个分身,共花费能量j的方案数. 状态转移:刚开始想的枚举第i个 ...

  2. MSSQL数据类型

    数据类型 描述 备注 对应vba类型   字符     char(n) n为1-8000字符之间     nchar(n) n为1-4000 unicode字符之间     nvarchar(max) ...

  3. CentOS基本命令手册

    一.磁盘使用情况 两个命令df .du结合比较直观 df -h #查看整台服务器的硬盘使用情况 du -sh * #查看每个文件夹的大小 二.tar 用法 压缩 tar tar -czvf test. ...

  4. 第3章---数据探索(python数据挖掘)

    1.缺失值分析及箱型图 数据:catering_sale.xls(餐饮日销额数) 缺失值使用函数:describe()函数,能算出数据集的八个统计量 import pandas as pd cater ...

  5. mysql驱动下载

    下载地址:https://dev.mysql.com/downloads/connector/j/ 下载步骤:Select Operating System: Platform Independent

  6. idea 切换database数据库方言

    在适配各种国产数据库时常常遇到存在数据库方言的情况,例如openGauss支持oracle兼容模式.. 在这种情况下,就需要在idea里对方言进行切换,否则无法执行oracle语法的sql. 1.连接 ...

  7. Linux centos7.6 安装 docker

    1.安装官网教程 https://docs.docker.com/engine/install/centos/ 2.卸载之前的 docker sudo yum remove docker \ dock ...

  8. [Lua]敏感字检测

    参考链接: https://zhuanlan.zhihu.com/p/84685657 https://www.cnblogs.com/luguoshuai/p/9254190.html 一开始打算使 ...

  9. mysql 设置查询超时配置

    mysql设置查询超时 mysql5.6: max_statement_time (毫秒) mysql5.7: max_execution_time(毫秒) mariadb: max_statemen ...

  10. JML

    1.JML规格设计策略 我三次作业采用的方法都是从性能与存储大小方面考虑.在满足规格的条件下尽量做到运行速度最快,所用空间最小.因为这个单元的作业如果单单只是照着jml规格来翻译的话就失去了意义(因为 ...