程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 快速入门

  • 克隆

  • 类型转换

  • 日期时间

  • IO流相关

  • 工具类

  • 语言特性

  • JavaBean

  • 集合类

  • Map

  • Codec编码

  • 文本操作

  • 注解

  • 比较器

  • 异常

  • 数学

  • 线程和并发

  • 图片

  • 网络

  • 源码编译

  • 配置文件

  • 日志

  • 缓存

  • JSON

  • 加密解密

  • DFA查找

  • HTTP客户端

  • 定时任务

  • 扩展

  • 切面

  • 脚本

  • Office文档操作

  • 系统调用

  • 图形验证码

  • 网络Socket

    • Hutool AIO 封装 - AioServer 和 AioClient
    • Hutool NIO 封装 - NioServer 和 NioClient
      • 1. 服务端 - NioServer 使用指南
        • 基本使用
        • 注意事项
      • 2. 客户端 - NioClient 使用指南
        • 基本使用
        • 注意事项
  • JWT

  • Hutoll
  • 网络Socket
scholar
2024-08-20
目录

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

关键点说明

  1. NioServer server = new NioServer(8080);

    • 创建 NioServer 实例时,必须指定监听的端口号。
  2. server.setChannelHandler((sc) -> {...});

    • 设置通道处理逻辑。处理器是必须指定的,它接收 SocketChannel 作为参数,主要负责读取客户端发送的数据。
  3. 缓冲区操作:

    • ByteBuffer readBuffer = ByteBuffer.allocate(1024);:分配一个大小为 1024 字节的缓冲区用于接收数据。
    • readBuffer.flip();:将缓冲区切换为读模式,从头开始读取数据。
    • readBuffer.get(bytes);:将缓冲区的数据读取到字节数组中。
  4. 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

关键点说明

  1. NioClient client = new NioClient("127.0.0.1", 8080);

    • 创建 NioClient 实例时,必须指定服务器的 IP 地址和端口号。
  2. client.setChannelHandler((sc) -> {...});

    • 设置通道处理逻辑。处理器是必须指定的,负责处理从服务器接收到的数据。
  3. 控制台输入与输出:

    • 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
Hutool AIO 封装 - AioServer 和 AioClient
Hutool JWT 基础使用

← Hutool AIO 封装 - AioServer 和 AioClient Hutool JWT 基础使用→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式