Skip to content

Commit fe15ca2

Browse files
netty基础
1 parent dc01d17 commit fe15ca2

3 files changed

Lines changed: 273 additions & 0 deletions

File tree

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
<version>1.0-SNAPSHOT</version>
1010

1111
<dependencies>
12+
<dependency>
13+
<groupId>io.netty</groupId>
14+
<artifactId>netty-all</artifactId>
15+
<version>4.1.52.Final</version>
16+
</dependency>
17+
1218
<!-- 导入Mysql数据库链接jar包 -->
1319
<dependency>
1420
<groupId>mysql</groupId>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.netty;
2+
3+
import io.netty.bootstrap.Bootstrap;
4+
import io.netty.buffer.ByteBuf;
5+
import io.netty.buffer.Unpooled;
6+
import io.netty.channel.*;
7+
import io.netty.channel.nio.NioEventLoopGroup;
8+
import io.netty.channel.socket.SocketChannel;
9+
import io.netty.channel.socket.nio.NioSocketChannel;
10+
import io.netty.util.CharsetUtil;
11+
12+
13+
/**
14+
*
15+
* 详情见: https://mp.weixin.qq.com/s?__biz=MzI5MTU1MzM3MQ%3D%3D&chksm=ec0fb874db783162d60a288a1b4e4ef008852d773693a77bfc58608fae380fd0a14a40e96195&idx=1&mid=2247487808&scene=21&sn=043e5e674b798d0f02d13639cba547b6#wechat_redirect
16+
*
17+
*/
18+
public class NettyClientDemo {
19+
public static void main(String[] args) throws InterruptedException {
20+
21+
// 客户端只需要一个事件循环组,可以看做 BossGroup
22+
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
23+
24+
try {
25+
// 创建客户端的启动对象
26+
Bootstrap bootstrap = new Bootstrap();
27+
// 配置参数
28+
bootstrap
29+
// 设置线程组
30+
.group(eventLoopGroup)
31+
// 说明客户端通道的实现类(便于 Netty 做反射处理)
32+
.channel(NioSocketChannel.class)
33+
// handler()方法用于给 BossGroup 设置业务处理器
34+
.handler(
35+
// 创建一个通道初始化对象
36+
new ChannelInitializer<SocketChannel>() {
37+
// 向 Pipeline 添加业务处理器
38+
@Override
39+
protected void initChannel(
40+
SocketChannel socketChannel
41+
) throws Exception {
42+
socketChannel.pipeline().addLast(
43+
new NettyClientHandler()
44+
);
45+
46+
// 可以继续调用 socketChannel.pipeline().addLast()
47+
// 添加更多 Handler
48+
}
49+
}
50+
);
51+
52+
System.out.println("client is ready...");
53+
54+
// 启动客户端去连接服务器端,ChannelFuture 涉及到 Netty 的异步模型,后面展开讲
55+
ChannelFuture channelFuture = bootstrap.connect(
56+
"127.0.0.1",
57+
8080).sync();
58+
// 对通道关闭进行监听
59+
channelFuture.channel().closeFuture().sync();
60+
} finally {
61+
eventLoopGroup.shutdownGracefully();
62+
}
63+
}
64+
65+
/**
66+
* 自定义一个 Handler,需要继承 Netty 规定好的某个 HandlerAdapter(规范)
67+
* InboundHandler 用于处理数据流入本端(客户端)的 IO 事件
68+
* InboundHandler 用于处理数据流出本端(客户端)的 IO 事件
69+
*/
70+
static class NettyClientHandler extends ChannelInboundHandlerAdapter {
71+
/**
72+
* 通道就绪时执行
73+
*
74+
* @param ctx 上下文对象
75+
* @throws Exception
76+
*/
77+
@Override
78+
public void channelActive(ChannelHandlerContext ctx)
79+
throws Exception {
80+
// 向服务器发送数据
81+
ctx.writeAndFlush(
82+
// Unpooled 类是 Netty 提供的专门操作缓冲区的工具
83+
// 类,copiedBuffer 方法返回的 ByteBuf 对象类似于
84+
// NIO 中的 ByteBuffer,但性能更高
85+
Unpooled.copiedBuffer(
86+
"hello server!",
87+
CharsetUtil.UTF_8
88+
)
89+
);
90+
}
91+
92+
/**
93+
* 当通道有数据可读时执行
94+
*
95+
* @param ctx 上下文对象
96+
* @param msg 服务器端发送的数据
97+
* @throws Exception
98+
*/
99+
@Override
100+
public void channelRead(ChannelHandlerContext ctx, Object msg)
101+
throws Exception {
102+
// 接收服务器端发来的数据
103+
104+
System.out.println("server address: "
105+
+ ctx.channel().remoteAddress());
106+
107+
// ByteBuf 是 Netty 提供的类,比 NIO 的 ByteBuffer 性能更高
108+
ByteBuf byteBuf = (ByteBuf) msg;
109+
System.out.println("data from server: "
110+
+ byteBuf.toString(CharsetUtil.UTF_8));
111+
}
112+
113+
/**
114+
* 发生异常时执行
115+
*
116+
* @param ctx 上下文对象
117+
* @param cause 异常对象
118+
* @throws Exception
119+
*/
120+
@Override
121+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
122+
throws Exception {
123+
// 关闭与服务器端的 Socket 连接
124+
ctx.channel().close();
125+
}
126+
}
127+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package com.netty;
2+
3+
import io.netty.bootstrap.ServerBootstrap;
4+
import io.netty.buffer.ByteBuf;
5+
import io.netty.buffer.Unpooled;
6+
import io.netty.channel.*;
7+
import io.netty.channel.nio.NioEventLoopGroup;
8+
import io.netty.channel.socket.SocketChannel;
9+
import io.netty.channel.socket.nio.NioServerSocketChannel;
10+
import io.netty.util.CharsetUtil;
11+
12+
13+
/**
14+
* 详情见: https://mp.weixin.qq.com/s?__biz=MzI5MTU1MzM3MQ%3D%3D&chksm=ec0fb874db783162d60a288a1b4e4ef008852d773693a77bfc58608fae380fd0a14a40e96195&idx=1&mid=2247487808&scene=21&sn=043e5e674b798d0f02d13639cba547b6#wechat_redirect
15+
*/
16+
public class NettyServerDemo {
17+
public static void main(String[] args) throws InterruptedException {
18+
// 创建 BossGroup 和 WorkerGroup
19+
// 1. bossGroup 只处理连接请求
20+
// 2. 业务处理由 workerGroup 来完成
21+
EventLoopGroup bossGroup = new NioEventLoopGroup();
22+
EventLoopGroup workerGroup = new NioEventLoopGroup();
23+
24+
try {
25+
// 创建服务器端的启动对象
26+
ServerBootstrap bootstrap = new ServerBootstrap();
27+
// 配置参数
28+
bootstrap
29+
// 设置线程组
30+
.group(bossGroup, workerGroup)
31+
// 说明服务器端通道的实现类(便于 Netty 做反射处理)
32+
.channel(NioServerSocketChannel.class)
33+
// 设置等待连接的队列的容量(当客户端连接请求速率大
34+
// 于 NioServerSocketChannel 接收速率的时候,会使用
35+
// 该队列做缓冲)
36+
// option()方法用于给服务端的 ServerSocketChannel
37+
// 添加配置
38+
.option(ChannelOption.SO_BACKLOG, 128)
39+
// 设置连接保活
40+
// childOption()方法用于给服务端 ServerSocketChannel
41+
// 接收到的 SocketChannel 添加配置
42+
.childOption(ChannelOption.SO_KEEPALIVE, true)
43+
// handler()方法用于给 BossGroup 设置业务处理器
44+
// childHandler()方法用于给 WorkerGroup 设置业务处理器
45+
.childHandler(
46+
// 创建一个通道初始化对象
47+
new ChannelInitializer<SocketChannel>() {
48+
// 向 Pipeline 添加业务处理器
49+
@Override
50+
protected void initChannel(
51+
SocketChannel socketChannel
52+
) throws Exception {
53+
socketChannel.pipeline().addLast(
54+
new NettyServerHandler()
55+
);
56+
57+
// 可以继续调用 socketChannel.pipeline().addLast()
58+
// 添加更多 Handler
59+
}
60+
}
61+
);
62+
63+
System.out.println("server is ready...");
64+
65+
// 绑定端口,启动服务器,生成一个 channelFuture 对象,
66+
// ChannelFuture 涉及到 Netty 的异步模型,后面展开讲
67+
ChannelFuture channelFuture = bootstrap.bind(8080).sync();
68+
// 对通道关闭进行监听
69+
channelFuture.channel().closeFuture().sync();
70+
} finally {
71+
bossGroup.shutdownGracefully();
72+
workerGroup.shutdownGracefully();
73+
}
74+
}
75+
76+
/**
77+
* 自定义一个 Handler,需要继承 Netty 规定好的某个 HandlerAdapter(规范)
78+
* InboundHandler 用于处理数据流入本端(服务端)的 IO 事件
79+
* InboundHandler 用于处理数据流出本端(服务端)的 IO 事件
80+
*/
81+
static class NettyServerHandler extends ChannelInboundHandlerAdapter {
82+
/**
83+
* 当通道有数据可读时执行
84+
*
85+
* @param ctx 上下文对象,可以从中取得相关联的 Pipeline、Channel、客户端地址等
86+
* @param msg 客户端发送的数据
87+
* @throws Exception
88+
*/
89+
@Override
90+
public void channelRead(ChannelHandlerContext ctx, Object msg)
91+
throws Exception {
92+
// 接收客户端发来的数据
93+
94+
System.out.println("client address: "
95+
+ ctx.channel().remoteAddress());
96+
97+
// ByteBuf 是 Netty 提供的类,比 NIO 的 ByteBuffer 性能更高
98+
ByteBuf byteBuf = (ByteBuf) msg;
99+
System.out.println("data from client: "
100+
+ byteBuf.toString(CharsetUtil.UTF_8));
101+
}
102+
103+
/**
104+
* 数据读取完毕后执行
105+
*
106+
* @param ctx 上下文对象
107+
* @throws Exception
108+
*/
109+
@Override
110+
public void channelReadComplete(ChannelHandlerContext ctx)
111+
throws Exception {
112+
// 发送响应给客户端
113+
ctx.writeAndFlush(
114+
// Unpooled 类是 Netty 提供的专门操作缓冲区的工具
115+
// 类,copiedBuffer 方法返回的 ByteBuf 对象类似于
116+
// NIO 中的 ByteBuffer,但性能更高
117+
Unpooled.copiedBuffer(
118+
"hello client! i have got your data.",
119+
CharsetUtil.UTF_8
120+
)
121+
);
122+
}
123+
124+
/**
125+
* 发生异常时执行
126+
*
127+
* @param ctx 上下文对象
128+
* @param cause 异常对象
129+
* @throws Exception
130+
*/
131+
@Override
132+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
133+
throws Exception {
134+
// 关闭与客户端的 Socket 连接
135+
ctx.channel().close();
136+
}
137+
138+
139+
}
140+
}

0 commit comments

Comments
 (0)