每一秒钟的时间都值得铭记

0%

Netty4入门教程,搭建简单的Netty服务端和客户端

什么是 Netty?

Netty 是 jboss 提供的一个 Java 开源框架,Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可用性的网络服务器和客户端程序。也就是说 Netty 是一个基于 NIO 的编程框架,使用 Netty 可以快速的开发出一个网络应用。
由于 Java 自带的 NIO API 使用起来非常复杂,并且还可能出现 Epoll Bug,这使得我们使用原生的 NIO 来进行网络编程存在很大的难度且非常耗时。但是 Netty 良好的设计可以使开发人员快速高效的进行网络应用开发。

Netty 入门

搭建项目

首先需要搭建一个普通的 Maven 项目,JDK 版本为 JDK8。

引入 Netty 依赖

由于 Netty5 已经被废弃,目前最新的 Netty 版本是 Netty4。

1
2
3
4
5
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.67.Final</version>
</dependency>

搭建 Netty 服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class NettyServer {

public static void main(String[] args) throws Exception {
NettyServer nettyServer = new NettyServer();
nettyServer.start(12345);
}

public void start(int port) throws Exception {
// 1.定义执行线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
// 2.定义服务类
ServerBootstrap serverBootstrap = new ServerBootstrap();
// 3.设置线程池
serverBootstrap.group(group);
// 4.设置通道
serverBootstrap.channel(NioServerSocketChannel.class);
// 5.绑定端口
serverBootstrap.localAddress(new InetSocketAddress(port));
// 6.添加Handler
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel channel) {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("StringDecoder", new StringDecoder());
pipeline.addLast("StringEncoder", new StringEncoder());
pipeline.addLast("ServerHandler", new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Channel channel = ctx.channel();
System.out.println("server receive UserToken[" + channel.id().asLongText() + "] msg ==> " + msg);
}

@Override
public void channelActive(ChannelHandlerContext ctx) {
Channel channel = ctx.channel();
System.out.println("UserToken[" + channel.id().asLongText() + "] 创建链接");
final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("The server created a link!", StandardCharsets.UTF_8));
ctx.writeAndFlush(buf.duplicate());
}

@Override
public void channelInactive(ChannelHandlerContext ctx) {
Channel channel = ctx.channel();
System.out.println("UserToken[" + channel.id().asLongText() + "] 断开链接");
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Channel channel = ctx.channel();
System.out.println("UserToken[" + channel.id().asLongText() + "] 发生异常");
}
});
}
});
ChannelFuture channelFuture = serverBootstrap.bind().sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();
}
}
}

搭建 Netty 客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class NettyClient {

public static void main(String[] args) {
NettyClient nettyClient = new NettyClient();
nettyClient.start("127.0.0.1", 12345);
}

public void start(String host, int port) {
// 1.定义执行线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
// 2.定义客户端类
Bootstrap clientBootstrap = new Bootstrap();
// 3.设置线程池
clientBootstrap.group(group);
// 4.设置通道
clientBootstrap.channel(NioSocketChannel.class);
// 5.添加Handler
clientBootstrap.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("StringDecoder", new StringDecoder());
pipeline.addLast("StringEncoder", new StringEncoder());
pipeline.addLast("ClientHandler", new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
System.out.println("client receive msg ==> " + msg.toString());
}
});
}
});

// 6.建立连接
ChannelFuture channelFuture = clientBootstrap.connect(host, port);
// 7.测试输入
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Please enter:");
String msg = bufferedReader.readLine();
channelFuture.channel().writeAndFlush(msg);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 8.关闭连接
group.shutdownGracefully();
}
}
}

启动项目

分别启动 NettyServer 和 NettyClient 的 main 方法,服务器和客户端即可进行简单的通讯。

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------