Netty:简单使用
Netty是什么东西
Netty是一个封装很好的异步事件驱动框架,让我们快速的部署服务端和客户端的网络应用,进行异步IO通信。
1、什么是IO通信
IO就是input 和 output,是一种在两台主机、两个进程或者两个线程之间传输数据的方法
2、什么是异步
异步和同步相对应,同步 举个例子就是:a线程和b线程通信时,a每次准备要读取b的数据时,得在原地等b将数据传过来,不能进行其他操作(b等a也一样)
异步 就是:线程a每次只需要看看线程b有没有传数据过来,有就读取,没有就执行其他操作。
感觉就类似于:a和b两个人要约会,同步情况下,先到约会地点的人得一直在原地等待还没到的人
异步情况下,先到约会地点的人可以一边跟路边的美女(帅哥)搭讪,一边看看对方到了没
所以在同步情况下,服务端的一个线程只能管理一个连接,
在异步情况下,服务端的一个线程可以管理多个连接
Netty怎么使用
Netty怎么用取决于我们要用它做什么
数据传输
数据传输我们要进行IO通信是为了要传输数据
Netty将数据传输的方法封装到了ChannelInboundHandlerAdapter中,继承这个类然后实现里面的方法就可以进行数据传输(应该有点适配器模式)
下面代码中的两个类就是进行数据传输的Handler,其中服务端在连接建立时发送时间,客户端收到数据后打印(来自官方文档)
承载我们要传输的信息、进行传输的数据类型是ByteBuf类型,ByteBuf是一种引用计数的对象,所以我们使用完后,需要注意释放对象。
1 import io.netty.buffer.ByteBuf;
2 import io.netty.channel.ChannelFuture;
3 import io.netty.channel.ChannelFutureListener;
4 import io.netty.channel.ChannelHandlerContext;
5 import io.netty.channel.ChannelInboundHandlerAdapter;
6
7 public class TimeServerHandler extends ChannelInboundHandlerAdapter {
8
9 //在连接建立之后调用该方法
10 @Override
11 public void channelActive(ChannelHandlerContext ctx) throws Exception {
12 final ByteBuf time = ctx.alloc().buffer(4); // (2)
13 time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
14
15 final ChannelFuture f = ctx.writeAndFlush(time); // (3)
16 f.addListener(new ChannelFutureListener() {
17 @Override
18 public void operationComplete(ChannelFuture future) {
19 if (f == future) {
20 ctx.close();
21 }
22 }
23 });
24 }
25 //捕捉数据传输过程中的异常
26 @Override
27 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
28 cause.printStackTrace();
29 ctx.close();
30 }
31 }
1 import io.netty.buffer.ByteBuf;
2 import io.netty.channel.ChannelHandlerContext;
3 import io.netty.channel.ChannelInboundHandlerAdapter;
4
5 import java.util.Date;
6
7 public class TimeClientHandler extends ChannelInboundHandlerAdapter {
8
9 //收到发送过来的数据之后调用该方法
10 @Override
11 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
12
13 ByteBuf m = (ByteBuf) msg; // (1)
14 try {
15 long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L;
16 System.out.println(new Date(currentTimeMillis));
17 ctx.close();
18 } finally {
19 m.release();
20 }
21 }
22
23 @Override
24 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
25
26 cause.printStackTrace();
27 ctx.close();
28 }
29 }
我们的目的,数据传输的操作已经有了,但现在只是知道了要传输什么,然后还得建立连接来进行传输
建立连接
我们需要使用线程来建立连接(可能协程也可以)
我们不用自己创建线程池,因为Netty提供了线程组(EventLoopGroup类)的方式来建立线程
服务端一般会使用两个线程组,一个用来接收连接,一个用来传输数据;客户端使用一个线程组用来传输数据
现在需要有一个东西把线程组和传输数据的Handler组合起来,为了方便就使用了Bootstrap类,
服务端是ServerBootstrap,客户端是Bootstrap,因为服务端有两个线程组,所以得进行区分
下面是代码中建立连接的类,加上面的Handler就是Netty连接完整的(客户端连接服务端获取时间的)demo
1 import io.netty.bootstrap.ServerBootstrap;
2 import io.netty.channel.*;
3 import io.netty.channel.nio.NioEventLoopGroup;
4 import io.netty.channel.socket.SocketChannel;
5 import io.netty.channel.socket.nio.NioServerSocketChannel;
6
7 public class TimeServer {
8
9 private int port;
10
11 public TimeServer(int port){
12 this.port = port;
13 }
14
15 public void run(){
16
17 //称为父线程组
18 EventLoopGroup bossGroup = new NioEventLoopGroup();
19 //子线程组
20 EventLoopGroup workerGroup = new NioEventLoopGroup();
21
22 try{
23 //也可以使用channel直接创建连接
24 ServerBootstrap serverBoostrap = new ServerBootstrap();
25 serverBoostrap.group(bossGroup,workerGroup)
26 //通道类型有NioServerSocketChannel、OioServerSocketChannel、NioSctpServerChannel(linux平台)
27 //设置服务端通道实现类型
28 .channel(NioServerSocketChannel.class)
29 .childHandler(new ChannelInitializer<SocketChannel>() {
30 @Override
31 protected void initChannel(SocketChannel socketChannel) throws Exception {
32
33 // ChannelPipeline用于管理Handler
34 socketChannel.pipeline().addLast(new TimeServerHandler());
35 }
36 })
37 //设置线程队列的连接个数
38 .option(ChannelOption.SO_BACKLOG,128)
39 //对子线程组的配置,设置保持活动连接状态,默认为false,会主动探测空闲连接的有效性
40 .childOption(ChannelOption.SO_KEEPALIVE,true);
41
42 //ChannelFuture是指尚未执行的操作,因为netty是异步操作
43 ChannelFuture channelFuture = serverBoostrap.bind(port).sync();
44 //可以得到channle的各种状态
45 channelFuture.channel().isOpen();
46 channelFuture.channel().isActive();
47
48 //直到服务器socket关闭的时候执行。
49 channelFuture.channel().closeFuture().sync();
50
51 } catch (InterruptedException e) {
52 e.printStackTrace();
53 } finally {
54 //关闭线程组
55 bossGroup.shutdownGracefully();
56 workerGroup.shutdownGracefully();
57 }
58
59 }
60
61 public static void main(String[] args) {
62 TimeServer timeServer = new TimeServer(8989);
63 timeServer.run();
64 }
65
66
67 }
1 import io.netty.bootstrap.Bootstrap;
2 import io.netty.channel.ChannelFuture;
3 import io.netty.channel.ChannelInitializer;
4 import io.netty.channel.ChannelOption;
5 import io.netty.channel.EventLoopGroup;
6 import io.netty.channel.nio.NioEventLoopGroup;
7 import io.netty.channel.socket.SocketChannel;
8 import io.netty.channel.socket.nio.NioSocketChannel;
9
10 public class TimeClient {
11
12 public static void main(String[] args) {
13 String host = "127.0.0.1";
14 int port = Integer.parseInt("8989");
15 EventLoopGroup workerGroup = new NioEventLoopGroup();
16
17 try {
18 Bootstrap b = new Bootstrap();
19 b.group(workerGroup);
20 b.channel(NioSocketChannel.class);
21 b.option(ChannelOption.SO_KEEPALIVE, true);
22 b.handler(new ChannelInitializer<SocketChannel>() {
23 @Override
24 public void initChannel(SocketChannel ch) throws Exception {
25 ch.pipeline().addLast(new TimeClientHandler());
26 }
27 });
28
29
30 ChannelFuture f = b.connect(host, port).sync();
31
32
33 f.channel().closeFuture().sync();
34 } catch (InterruptedException e) {
35 e.printStackTrace();
36 } finally {
37 workerGroup.shutdownGracefully();
38 }
39 }
40 }
Netty:简单使用的更多相关文章
- Netty——简单创建服务器、客户端通讯
Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程 ...
- Netty简单的HTTP服务器
本文转载自:https://www.cnblogs.com/luangeng/p/7875710.html HTTP协议:略 基于Netty的HTTP协议栈可以方便的进行异步非阻塞的HTTP服务器的开 ...
- Netty简单使用
目录 丢弃服务器 DiscardServerHandler DiscardServer 测试 应答服务器 时间服务器 TimeServerHandler TimeClient TimeClientHa ...
- Netty简单的重连机制
其实重连机制并不是多么多高深的技术,其实就是一个在客户端做一个简单的判断,如果连接断了,那么就重新调用连接服务端的代码 当然,我们重连的动作肯定是发生在断连之后发生的,我们可以在上篇的心跳机制的基础上 ...
- Netty简单介绍(非原创)
文章大纲 一.Netty基础介绍二.Netty代码实战三.项目源码下载四.参考文章 一.Netty基础介绍 1. 简介 官方定义为:”Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地 ...
- 【Netty整理01-快速入门】Netty简单使用Demo(已验证)
多处摘抄或手打,为了十积分厚着脸皮标为原创,惭愧惭愧~本篇文章用于快速入门搭建一个简单的netty 应用,如想稍微深入系统的了解,请参照本人下一篇博客,链接: 参考地址: 官方文档:http://ne ...
- JAVA netty 简单使用
实现一个功能,客户端和服务器 轮流对一个数加+1 服务器 public class Server { public static void main(String[] args) { NioEvent ...
- Netty简单认识
简介 Netty 是由JBOSS提供的一个 Java开源框架, 现在是 Github上的开源项目 Netty 是一个异步的.基于事件驱动的网络应用框架式, 用以快速开发高性能.高可靠性的网路IO程序 ...
- netty简单样例
package com.example.demohystrix.process; import io.netty.bootstrap.ServerBootstrap; import io.netty. ...
- Netty简单聊天室
1.创建maven项目,在pom.xml中引入netty的jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xm ...
随机推荐
- 『无为则无心』Python序列 — 18、Python列表概念及常用操作API
目录 1.列表的概念 (1)列表的定义 (2)列表的应用场景 (3)列表的定义格式 2.列表的常用操作 (1)列表的查找 1)通过下标查找 2)通过方法查找 3)判断是否存在 (2)列表的增加 @1. ...
- Gym 101206L Daylight Saving Time 根据年月日计算星期
题意: [3月的第二个周日02:00:00 , 3月的第二个周日03:00:00) 这个区间都不是PST或PDT,[11月的第一个周日01:00:00 , 11月的第一个周日02:00:00) 这个区 ...
- 重新整理 .net core 实践篇————缓存相关[四十二]
前言 简单整理一下缓存. 正文 缓存是什么? 缓存是计算结果的"临时"存储和重复使用 缓存本质是用空间换取时间 缓存的场景: 计算结果,如:反射对象缓存 请求结果,如:DNS 缓存 ...
- Redis:银河麒麟arm服务器安装redis5.0.3,配置开机自启
百度网盘下载地址 链接:https://pan.baidu.com/s/1f2ghL2-0brPt0IodjfqOqQ提取码:9al1 解压tar包 #解压tar包 tar -xvf arm-r ...
- Java:Java的^运算符详解
按位异或运算符(^)是二元运算符,要化为二进制才能进行计算,在两个操作数中,如果两个相应的位相同,则运算结果为0,否则1:例如:int a=15:int b=a^8;运算结果为:a=15:b=7:a( ...
- DawgCTF wp(re和crypto)
简单写写思路,想看详解的..我脚本有些丢失了..师傅请移步. 挂了个vpn,算正式打这种国际赛,全是英文.上去打了两天,昨晚晚上划水了一晚上补作业...,re那时候写出来三道,Potentially ...
- MindSpore模型精度调优实战:常用的定位精度调试调优思路
摘要:在模型的开发过程中,精度达不到预期常常让人头疼.为了帮助用户解决模型调试调优的问题,我们为MindSpore量身定做了可视化调试调优组件:MindInsight. 本文分享自华为云社区<技 ...
- asp.net mvc中的路由
[Route] 路由 [Route("~/")] 忽略路由前缀 [Route("person/{id:int}")] 路由内联约束 [Route("h ...
- C语言:易错题
1. int x=y=z=0;//实际只声明了变量x,而变量y,z并没有声明.可以修改为:int x=0,y=0,z=0; 或int x,y,z; x=y=z=0; 2.int z=(x+y)++;/ ...
- 【技巧】使用PPT更换背景色
主要记述使用PPT来更换图片某一部分的背景色 把想要更改的图片粘贴到PPT里. 依次选择[格式][颜色][设置透明色],然后点击需要更改背景的地方 将自己的目标颜色复制一下,填充上去,选择[置于底层]