Hutool NIO 封装 - NioServer 和 NioClient
# Hutool NIO 封装 - NioServer 和 NioClient
背景介绍
Hutool 对 Java NIO 进行了简单封装,使得使用非阻塞 I/O(NIO)编写服务器和客户端更加简洁。本文将详细介绍如何使用 Hutool 提供的 NioServer
和 NioClient
类,并逐步分析其中的重要参数和 API。
# 1. 服务端 - NioServer
使用指南
# 基本使用
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.socket.nio.NioServer;
import cn.hutool.socket.nio.NioClient;
import cn.hutool.core.io.IORuntimeException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class MyNioServer {
public static void main(String[] args) {
// 创建NioServer实例,指定监听的端口号,8080是必须指定的参数
NioServer server = new NioServer(8080);
// 设置数据处理逻辑,ChannelHandler是必须设置的
server.setChannelHandler((sc) -> {
// 创建缓冲区,用于接收数据
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
try {
// 从通道中读取数据到缓冲区
int readBytes = sc.read(readBuffer);
if (readBytes > 0) {
// 翻转缓冲区,准备读取数据
readBuffer.flip();
// 读取缓冲区中的字节数据
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = StrUtil.utf8Str(bytes);
// 打印接收到的消息
Console.log("[{}]: {}", sc.getRemoteAddress(), body);
// 处理并返回响应消息
doWrite(sc, body);
} else if (readBytes < 0) {
// 当读取到-1时,表示客户端断开连接,关闭通道
IoUtil.close(sc);
}
} catch (IOException e) {
// 处理读取时的异常
throw new IORuntimeException(e);
}
});
// 启动服务器,开始监听
server.listen();
}
// 发送响应给客户端
public static void doWrite(SocketChannel channel, String response) throws IOException {
// 添加响应内容
response = "收到消息:" + response;
// 将响应数据写入通道,返回给客户端
channel.write(BufferUtil.createUtf8(response));
}
}
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
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
关键点说明
NioServer server = new NioServer(8080);
- 创建
NioServer
实例时,必须指定监听的端口号。
- 创建
server.setChannelHandler((sc) -> {...});
- 设置通道处理逻辑。处理器是必须指定的,它接收
SocketChannel
作为参数,主要负责读取客户端发送的数据。
- 设置通道处理逻辑。处理器是必须指定的,它接收
缓冲区操作:
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
:分配一个大小为 1024 字节的缓冲区用于接收数据。readBuffer.flip();
:将缓冲区切换为读模式,从头开始读取数据。readBuffer.get(bytes);
:将缓冲区的数据读取到字节数组中。
doWrite(sc, body);
- 处理并发送响应数据给客户端,调用封装的方法
doWrite
。
- 处理并发送响应数据给客户端,调用封装的方法
# 注意事项
- 端口号是启动服务器时必须指定的参数。
- ChannelHandler 是必须设置的,负责数据的读写操作。
- 对于 NIO 通信,缓冲区操作非常关键,要注意数据读取和写入时的缓冲区状态转换。
# 2. 客户端 - NioClient
使用指南
# 基本使用
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.socket.nio.NioClient;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
public class MyNioClient {
public static void main(String[] args) {
// 创建NioClient实例,指定服务端IP地址和端口号
NioClient client = new NioClient("127.0.0.1", 8080);
// 设置数据处理逻辑,ChannelHandler是必须设置的
client.setChannelHandler((sc) -> {
// 创建缓冲区,用于接收数据
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
// 从通道中读取数据到缓冲区
int readBytes = sc.read(readBuffer);
if (readBytes > 0) {
// 翻转缓冲区,准备读取数据
readBuffer.flip();
// 读取缓冲区中的字节数据
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = StrUtil.utf8Str(bytes);
// 打印接收到的消息
Console.log("[{}]: {}", sc.getRemoteAddress(), body);
} else if (readBytes < 0) {
// 当读取到-1时,表示服务端断开连接,关闭通道
sc.close();
}
});
// 启动客户端,开始监听
client.listen();
// 向服务器发送初始消息
client.write(BufferUtil.createUtf8("你好。\n"));
client.write(BufferUtil.createUtf8("你好2。"));
// 在控制台向服务器端发送数据
Console.log("请输入发送的消息:");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String request = scanner.nextLine();
if (request != null && request.trim().length() > 0) {
client.write(BufferUtil.createUtf8(request));
}
}
}
}
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
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
关键点说明
NioClient client = new NioClient("127.0.0.1", 8080);
- 创建
NioClient
实例时,必须指定服务器的 IP 地址和端口号。
- 创建
client.setChannelHandler((sc) -> {...});
- 设置通道处理逻辑。处理器是必须指定的,负责处理从服务器接收到的数据。
控制台输入与输出:
Scanner scanner = new Scanner(System.in);
:监听用户输入,并将输入内容发送至服务器。client.write(BufferUtil.createUtf8(request));
:将用户输入内容转换为 UTF-8 格式,并发送到服务器。
# 注意事项
- 服务器 IP 和端口是必须指定的参数。
- ChannelHandler 是必须设置的,负责接收服务器的响应数据并处理。
总结
Hutool 的 NioServer
和 NioClient
封装提供了简单的接口来进行 NIO 通信,极大地简化了底层的 NIO 操作。使用时要注意缓冲区的状态管理、通道的处理逻辑,以及参数的设置。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08