博客
关于我
Netty基础—2.网络编程基础四
阅读量:792 次
发布时间:2023-02-14

本文共 4319 字,大约阅读时间需要 14 分钟。

NIO网络编程实战与Reactor模式

Buffer网络编程

Buffer的作用

Buffer(缓冲区)是NIO中用于高效读写数据的核心组件。它通过将数据从通道读入缓冲区,再从缓冲区写入通道,简化了数据传输过程。应用程序在发送数据时,会先将数据写入缓冲区,然后通过通道发送;在接收数据时,先从通道读取到缓冲区,再逐个读取缓冲区数据。

Buffer的重要属性

  • Capacity(容量)

    Buffer的容量决定了可以存储的最大数据量。只能往Buffer中写入capacity个字节、长整型或字符。一旦Buffer满了,需要通过clear()或compact()方法清空。

  • Position(位置)

    表示当前在缓冲区中可以写入或读取的位置。初始值为0,写入或读取数据后,position会移动到下一个可写入或可读的位置。

  • Limit(限制)

    在写模式下,limit表示缓冲区中可以写入的最大数据量,等于capacity。切换到读模式后,limit表示可以读取的最大数据量。

  • Buffer分配与操作

  • 分配

    使用allocate()方法分配内存,例如:

    ByteBuffer buf = ByteBuffer.allocate(1024);
  • 读写操作

    • 写数据:从通道读取到Buffer,或者直接调用put()方法。
    • 读数据:从Buffer读取到通道,或者调用get()方法。
    • 常用步骤:
    • 写入数据。
    • 调用flip()切换到读模式。
    • 读取数据。
    • 调用clear()或compact()清空缓冲区。
  • 其他操作

    • rewind():将position设回0。
    • clear():清空缓冲区,position设为0,limit设为capacity。
    • compact():将未读数据移动到缓冲区起始位置,position设为最后一个未读数据后面。
  • Selector与Channel

    Selector的作用

    Selector(选择器)用于管理和监听多个通道(Channel)的读写事件。它通过注册事件类型(如OP_READ、OP_WRITE)来判断何时需要处理哪个通道。

    Channel的作用

    Channel是NIO中用于高效读写数据的核心类。常见的Channel实现包括SocketChannel和ServerSocketChannel,它们都继承自SelectableChannel。所有通道都需要通过Buffer进行数据传输。

    SelectionKey

    SelectionKey用于表示对特定通道的操作事件感兴趣。定义了四种事件类型:OP_ACCEPT、OP_READ、OP_WRITE、OP_CONNECT。这些事件类型对应不同的网络操作。

    NIO开发流程

  • 服务端启动

    使用ServerSocketChannel创建服务器,并注册OP_ACCEPT事件处理器。

  • 客户端连接

    客户端通过SocketChannel连接到服务器,并注册OP_CONNECT事件处理器。

  • 数据交互

    • 服务端接收连接后,创建SocketChannel并注册OP_READ事件。
    • 客户端在连接建立后,注册OP_READ事件以便读取数据。
  • IO循环处理

    使用Selector管理多个通道,等待事件就绪。每次循环中,调用select()方法阻塞等待事件,然后处理对应的事件。

  • NIO开发示例

    服务端代码

    public class NioServer {    private static Selector selector;    private static ServerSocketChannel serverChannel;    public static void main(String[] args) {        try {            selector = Selector.open();            serverChannel = ServerSocketChannel.open();            serverChannel.configureBlocking(false);            serverChannel.socket().bind(new InetSocketAddress(8080));            serverChannel.register(selector, SelectionKey.OP_ACCEPT);            startServer();        } catch (IOException e) {            e.printStackTrace();        }    }    private static void startServer() {        while (!Thread.currentThread().isInterrupted()) {            try {                selector.select();                Set
    keys = selector.selectedKeys(); Iterator
    it = keys.iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); if (key.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); } } } catch (IOException e) { e.printStackTrace(); } } }}

    客户端代码

    public class NioClient {    private static Selector selector;    private static SocketChannel socketChannel;    public static void start() {        try {            selector = Selector.open();            socketChannel = SocketChannel.open();            socketChannel.configureBlocking(false);            socketChannel.register(selector, SelectionKey.OP_CONNECT);        } catch (IOException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        start();        Scanner scanner = new Scanner(System.in);        while (true) {            System.out.println("请输入消息:");            String msg = scanner.nextLine();            if (!sendMsg(msg)) {                break;            }        }    }    private static boolean sendMsg(String msg) {        try {            socketChannel.register(selector, SelectionKey.OP_READ);            ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());            buffer.flip();            int bytesWritten = socketChannel.write(buffer);            return bytesWritten > 0;        } catch (IOException e) {            e.printStackTrace();            return false;        }    }}

    Reactor模式简介

    Reactor模式通过多个Reactor线程管理IO操作,提升了吞吐量和系统性能。其核心思想是将IO事件分散到多个线程,从而避免单线程处理大量IO请求带来的性能瓶颈。

    单线程Reactor模式

  • 流程

    • Reactor线程启动事件循环。
    • 注册Acceptor事件处理器。
    • 处理连接请求和读写事件。
  • 优化

    • 使用线程池处理非IO业务逻辑,提高IO响应速度。
  • 局限性

    • 单线程无法处理高并发场景,性能受限。
  • 多线程Reactor模式

  • 流程

    • MainReactor处理连接请求。
    • SubReactor线程池处理读写事件。
  • 优势

    • 主Reactor负责接收连接,SubReactor负责数据通信。
    • 适用于高并发场景,提升吞吐量。
  • 应用

    • Netty框架常用多线程Reactor模式。
  • 通过以上优化,NIO网络编程实现了高效的数据传输和事件处理,适用于各种网络应用场景。

    转载地址:http://cjcfk.baihongyu.com/

    你可能感兴趣的文章
    nacos config
    查看>>
    Nacos Config--服务配置
    查看>>
    Nacos Derby 远程命令执行漏洞(QVD-2024-26473)
    查看>>
    Nacos 与 Eureka、Zookeeper 和 Consul 等其他注册中心的区别
    查看>>
    Nacos 单机集群搭建及常用生产环境配置 | Spring Cloud 3
    查看>>
    Nacos 启动报错[db-load-error]load jdbc.properties error
    查看>>
    Nacos 注册服务源码分析
    查看>>
    Nacos 融合 Spring Cloud,成为注册配置中心
    查看>>
    Nacos-注册中心
    查看>>
    Nacos2.X 源码分析:为订阅方推送、服务健康检查、集群数据同步、grpc客户端服务端初始化
    查看>>
    Nacos2.X 配置中心源码分析:客户端如何拉取配置、服务端配置发布客户端监听机制
    查看>>
    Nacos2.X源码分析:服务注册、服务发现流程
    查看>>
    NacosClient客户端搭建,微服务注册进nacos
    查看>>
    Nacos中使用ribbon
    查看>>
    Nacos使用OpenFeign
    查看>>
    Nacos使用Ribbon
    查看>>
    Nacos做注册中心使用
    查看>>
    Nacos做配置中心使用
    查看>>
    Nacos入门过程的坑--获取不到配置的值
    查看>>
    Nacos原理
    查看>>