温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java nio如何实现通信

发布时间:2026-10-13 12:09:21 来源:亿速云 阅读:91 作者:小樊 栏目:编程语言

Java NIO(New I/O,非阻塞 I/O)主要通过 Channel、Buffer、Selector 三大核心组件来实现高效通信,尤其适合高并发网络场景。

下面从 核心概念 → 通信模型 → 示例代码 → 关键点 逐步说明。


一、Java NIO 核心组件

1. Channel(通道)

  • 双向通信通道(可读可写)
  • 常见实现:
    • SocketChannel:TCP 客户端
    • ServerSocketChannel:TCP 服务端
    • DatagramChannel:UDP

2. Buffer(缓冲区)

  • 数据读写的中转容器
  • 常用:ByteBuffer
  • 重要属性:
    • capacity
    • position
    • limit
    • flip() / clear()

3. Selector(选择器)

  • 实现 多路复用
  • 一个线程可管理多个 Channel
  • 监听事件:
    • OP_ACCEPT
    • OP_CONNECT
    • OP_READ
    • OP_WRITE

二、NIO 通信模型(以 TCP 为例)

Client SocketChannel
        |
ServerSocketChannel + Selector
        |
    多个 SocketChannel

优势:

  • 一个线程处理成千上万连接
  • 非阻塞,避免线程频繁切换

三、服务端 NIO 通信示例

1. 服务端代码

public class NioServer {
    public static void main(String[] args) throws Exception {
        Selector selector = Selector.open();
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.bind(new InetSocketAddress(8080));
        serverChannel.configureBlocking(false);
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            selector.select();
            Iterator<SelectionKey> keys = selector.selectedKeys().iterator();

            while (keys.hasNext()) {
                SelectionKey key = keys.next();
                keys.remove();

                if (key.isAcceptable()) {
                    SocketChannel client = serverChannel.accept();
                    client.configureBlocking(false);
                    client.register(selector, SelectionKey.OP_READ);
                }

                if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len = client.read(buffer);
                    if (len > 0) {
                        buffer.flip();
                        System.out.println("收到:" + new String(buffer.array(), 0, len));
                        client.write(ByteBuffer.wrap("hello client".getBytes()));
                    }
                }
            }
        }
    }
}

2. 客户端 NIO 示例

public class NioClient {
    public public static void main(String[] args) throws Exception {
        SocketChannel channel = SocketChannel.open();
        channel.configureBlocking(false);
        channel.connect(new InetSocketAddress("localhost", 8080));

        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_CONNECT);

        while (true) {
            selector.select();
            for (SelectionKey key : selector.selectedKeys()) {
                if (key.isConnectable()) {
                    if (channel.finishConnect()) {
                        channel.register(selector, SelectionKey.OP_WRITE);
                    }
                }
                if (key.isWritable()) {
                    channel.write(ByteBuffer.wrap("hello server".getBytes()));
                    channel.register(selector, SelectionKey.OP_READ);
                }
                if (key.isReadable()) {
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len = channel.read(buffer);
                    if (len > 0) {
                        System.out.println("收到:" + new String(buffer.array(), 0, len));
                    }
                }
            }
        }
    }
}

四、NIO 通信关键点

1. 必须非阻塞

channel.configureBlocking(false);

2. Buffer 使用顺序

write -> flip -> read -> clear

3. 半包 / 粘包问题

  • NIO 是 流式协议
  • 需要:
    • 定长
    • 分隔符
    • 消息头+长度

4. 性能优势

  • 少量线程
  • 高并发
  • 适合 IM / 网关 / RPC

五、NIO vs BIO

对比项 BIO NIO
阻塞 是 否
线程模型 一连接一线程 单线程多连接
并发能力 低 高
编程复杂度 低 高

六、进阶建议

  • Netty(基于 NIO 封装)
  • Epoll(Linux 下更高性能)
  • Reactor 模式

如果你愿意,我可以:

  • 画 NIO 通信时序图
  • 讲 Netty 如何简化 NIO
  • 写 聊天室完整示例

你更想了解哪一部分?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手