Skip to content

Commit d3e51fa

Browse files
author
chenweijie
committed
netty simle demo
1 parent f835f67 commit d3e51fa

File tree

6 files changed

+314
-0
lines changed

6 files changed

+314
-0
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@
125125
</dependency>
126126

127127

128+
<dependency>
129+
<groupId>io.netty</groupId>
130+
<artifactId>netty-all</artifactId>
131+
<version>4.1.10.Final</version>
132+
</dependency>
133+
134+
128135

129136
</dependencies>
130137

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.chen.netty;
2+
3+
/**
4+
*
5+
* https://blog.csdn.net/the_fool_/article/details/80611148
6+
*
7+
* @author : chen weijie
8+
* @Date: 2019-10-18 18:44
9+
*/
10+
public class TestMain {
11+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.chen.netty.client;
2+
3+
import io.netty.bootstrap.Bootstrap;
4+
import io.netty.channel.ChannelFuture;
5+
import io.netty.channel.ChannelInitializer;
6+
import io.netty.channel.ChannelOption;
7+
import io.netty.channel.EventLoopGroup;
8+
import io.netty.channel.nio.NioEventLoopGroup;
9+
import io.netty.channel.socket.SocketChannel;
10+
import io.netty.channel.socket.nio.NioSocketChannel;
11+
12+
/**
13+
* 客户端消费者对象
14+
*
15+
* @author : chen weijie
16+
* @Date: 2019-10-18 20:31
17+
*/
18+
public class ClientTest {
19+
20+
21+
public void connect(String host, int port) {
22+
23+
EventLoopGroup worker = new NioEventLoopGroup();
24+
try {
25+
26+
Bootstrap b = new Bootstrap();
27+
28+
b.group(worker);
29+
30+
b.channel(NioSocketChannel.class);
31+
32+
b.option(ChannelOption.SO_KEEPALIVE, true);
33+
34+
b.handler(new ChannelInitializer<SocketChannel>() {
35+
@Override
36+
protected void initChannel(SocketChannel socketChannel) throws Exception {
37+
socketChannel.pipeline().addLast(new SimpleClientHandler());
38+
}
39+
});
40+
41+
ChannelFuture f = b.connect(host, port).sync();
42+
f.channel().closeFuture().sync();
43+
} catch (InterruptedException e) {
44+
e.printStackTrace();
45+
} finally {
46+
worker.shutdownGracefully();
47+
}
48+
}
49+
50+
public static void main(String[] args) {
51+
ClientTest client = new ClientTest();
52+
client.connect("127.0.0.1", 9999);
53+
}
54+
55+
56+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.chen.netty.client;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.ChannelHandlerContext;
5+
import io.netty.channel.ChannelInboundHandlerAdapter;
6+
7+
/**
8+
* @author : chen weijie
9+
* @Date: 2019-10-18 20:37
10+
*/
11+
public class SimpleClientHandler extends ChannelInboundHandlerAdapter {
12+
13+
14+
/**
15+
* 本方法用于接收服务端发送过来的消息
16+
*
17+
* @param ctx
18+
* @param msg
19+
* @throws Exception
20+
*/
21+
@Override
22+
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
23+
System.out.println("SimpleClientHandler.channelRead");
24+
ByteBuf result = (ByteBuf) msg;
25+
byte[] result1 = new byte[result.readableBytes()];
26+
result.readBytes(result1);
27+
System.out.println("Server said:" + new String(result1));
28+
result.release();
29+
}
30+
31+
/**
32+
* 本方法用于处理异常
33+
*
34+
* @param ctx
35+
* @param cause
36+
* @throws Exception
37+
*/
38+
@Override
39+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
40+
// 当出现异常就关闭连接
41+
cause.printStackTrace();
42+
ctx.close();
43+
}
44+
45+
46+
/**
47+
* 本方法用于向服务端发送信息
48+
*
49+
* @param ctx
50+
* @throws Exception
51+
*/
52+
@Override
53+
public void channelActive(ChannelHandlerContext ctx) throws Exception {
54+
String msg = "hello Server!";
55+
ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
56+
encoded.writeBytes(msg.getBytes());
57+
ctx.write(encoded);
58+
ctx.flush();
59+
}
60+
61+
62+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.chen.netty.server;
2+
3+
import io.netty.bootstrap.ServerBootstrap;
4+
import io.netty.channel.ChannelFuture;
5+
import io.netty.channel.ChannelInitializer;
6+
import io.netty.channel.ChannelOption;
7+
import io.netty.channel.EventLoopGroup;
8+
import io.netty.channel.nio.NioEventLoopGroup;
9+
import io.netty.channel.socket.SocketChannel;
10+
import io.netty.channel.socket.nio.NioServerSocketChannel;
11+
12+
/**
13+
* 服务端生产者对象
14+
* <p>
15+
* Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,
16+
* 例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。
17+
* 深入学习:
18+
* https://www.cnblogs.com/katsura/p/5991428.html
19+
* https://www.cnblogs.com/stevenczp/p/7581940.html
20+
*
21+
* @author : chen weijie
22+
* @Date: 2019-10-18 18:46
23+
*/
24+
public class ServerTest {
25+
26+
27+
/**
28+
* 服务端口
29+
*/
30+
private int port = 9999;
31+
32+
33+
/**
34+
* 开启服务
35+
*/
36+
public void startNetty() {
37+
38+
/**
39+
* 创建两个EventLoop的组,EventLoop 这个相当于一个处理线程,
40+
是Netty接收请求和处理IO请求的线程。不理解的话可以百度NIO图解
41+
相关资料:NioEventLoopGroup是一个处理I/O操作的多线程事件循环。
42+
Netty为不同类型的传输提供了各种EventLoopGroup实现。
43+
在本例中,我们正在实现一个服务器端应用程序,因此将使用两个NioEventLoopGroup。
44+
第一个,通常称为“boss”,接受传入的连接。
45+
第二个,通常称为“worker”,当boss接受连接并注册被接受的连接到worker时,处理被接受连接的流量。
46+
使用了多少线程以及如何将它们映射到创建的通道取决于EventLoopGroup实现,甚至可以通过构造函数进行配置。
47+
*/
48+
49+
EventLoopGroup acceptor = new NioEventLoopGroup();
50+
EventLoopGroup worker = new NioEventLoopGroup();
51+
52+
// 创建启动类
53+
ServerBootstrap bootstrap = new ServerBootstrap();
54+
55+
//2、配置启动参数等
56+
/**设置循环线程组,前者用于处理客户端连接事件,后者用于处理网络IO(server使用两个参数这个)
57+
*public ServerBootstrap group(EventLoopGroup group)
58+
*public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup)
59+
*/
60+
61+
bootstrap.group(acceptor, worker);
62+
63+
64+
/**设置选项
65+
* 参数:Socket的标准参数(key,value),可自行百度
66+
* eg:
67+
* bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
68+
*bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
69+
* */
70+
71+
bootstrap.option(ChannelOption.SO_BACKLOG,1024);
72+
//用于构造socketchannel工厂
73+
bootstrap.channel(NioServerSocketChannel.class);
74+
75+
/**
76+
* 传入自定义客户端Handle(服务端在这里搞事情)
77+
*/
78+
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
79+
@Override
80+
protected void initChannel(SocketChannel socketChannel) throws Exception {
81+
socketChannel.pipeline().addLast(new SimpleServerHandler());
82+
}
83+
});
84+
85+
// 绑定端口,开始接收进来的连接
86+
ChannelFuture f;
87+
try {
88+
f = bootstrap.bind(port).sync();
89+
// 等待服务器 socket 关闭 。
90+
f.channel().closeFuture().sync();
91+
} catch (InterruptedException e) {
92+
e.printStackTrace();
93+
}finally {
94+
acceptor.shutdownGracefully();
95+
worker.shutdownGracefully();
96+
}
97+
}
98+
99+
public static void main(String[] args) {
100+
new ServerTest().startNetty();
101+
102+
}
103+
104+
105+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.chen.netty.server;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.ChannelHandlerContext;
5+
import io.netty.channel.ChannelInboundHandlerAdapter;
6+
7+
/**
8+
* 服务端处理类
9+
*
10+
* @author : chen weijie
11+
* @Date: 2019-10-18 20:15
12+
*/
13+
public class SimpleServerHandler extends ChannelInboundHandlerAdapter {
14+
15+
16+
/**
17+
* 本方法用于读取客户端发送的信息
18+
*
19+
* @param ctx
20+
* @param msg
21+
* @throws Exception
22+
*/
23+
@Override
24+
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
25+
26+
System.out.println("simpleServerHandler.channelRead ");
27+
ByteBuf result = (ByteBuf) msg;
28+
byte[] results1 = new byte[result.readableBytes()];
29+
// msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
30+
result.readBytes(results1);
31+
32+
String resultStr = new String(results1);
33+
System.out.println("client said:" + resultStr);
34+
// 释放资源,这行很关键
35+
result.release();
36+
37+
//向客户端发送信息
38+
String response = "hello client";
39+
// 在当前场景下,发送的数据必须转换成byteBuf数组
40+
ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
41+
encoded.writeBytes(response.getBytes());
42+
ctx.write(encoded);
43+
ctx.flush();
44+
}
45+
46+
47+
/**
48+
* 本方法用作处理异常
49+
*
50+
* @param ctx
51+
* @param cause
52+
* @throws Exception
53+
*/
54+
@Override
55+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
56+
// 当出现异常就关闭连接
57+
cause.printStackTrace();
58+
ctx.close();
59+
}
60+
61+
/**
62+
* 信息获取完毕后操作
63+
*
64+
* @param ctx
65+
* @throws Exception
66+
*/
67+
@Override
68+
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
69+
ctx.flush();
70+
}
71+
72+
73+
}

0 commit comments

Comments
 (0)