Netty核心原理:一、基础入门-01:初入JavaIO之门BIO、NIO、AIO实战练习

news2024/12/27 2:56:17

文章目录

  • 一、前言介绍
    • 1.1 BIO:同步阻塞I/O模式
    • 1.2 NIO:同步非阻塞I/O模式
    • 1.3 AIO:异步非阻塞I/O模式
  • 二、代码实现
    • 2.1 工程结构
    • 2.2 BIO:同步阻塞I/O实现
      • 2.2.1 BIO处理器
      • 2.2.2 BIO适配器
      • 2.2.3 BIO客户端处理器
      • 2.2.4 BIO客户端
      • 2.2.5 BIO服务端处理器
      • 2.2.6 BIO服务端
      • 2.2.7 BIO单元测试
    • 2.3 NIO:同步阻非塞I/O实现
      • 2.3.1 NIO处理器
      • 2.3.2 NIO适配器
      • 2.3.3 NIO客户端处理器
      • 2.3.4 NIO客户端
      • 2.3.5 NIO服务端处理器
      • 2.3.6 NIO服务端
      • 2.3.7 NIO单元测试
    • 2.4 AIO:同步阻塞I/O实现
      • 2.4.1 AIO处理器
      • 2.4.2 AIO适配器
      • 2.4.3 AIO通道初始化
      • 2.4.4 AIO客户端处理器
      • 2.4.5 AIO客户端
      • 2.4.6 AIO服务端处理器
      • 2.4.7 AIO服务端通道初始化
      • 2.4.8 AIO服务端
      • 2.4.9 AIO单元测试

一、前言介绍

💡 Java IO:在 Java 中,提供了一些关于使用 IOAPI,可以供开发者来读写外部数据和文件。

  • Java IO 是比较难学习的知识点,并且随着 Java 的发展,为了提供更好的数据传输性能,目前有三种 IO 共存。BIONIOAIO

在这里插入图片描述

1.1 BIO:同步阻塞I/O模式

  • BIO:全称 Block-IO ,是一种同步且阻塞的通信模式。
    • 是一个比较传统的通信方式,模式简单。但并发处理能力低,通信耗时,依赖网速。

1.2 NIO:同步非阻塞I/O模式

  • NIO:全称 Non-Block-IO,是 Java SE 1.4 版本之后,针对网络传输效能优化的新功能。是一种非阻塞同步的通信模式。
  • NIO 和原来的 I/O 有同样的作用和目的,他们之间最重要的区别是数据打包和传输的方式。
  • 原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
    • 面向流的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。
    • 面向块的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

1.3 AIO:异步非阻塞I/O模式

  • AIO:全称 Asynchronous IO,是异步非阻塞的I/O。是一种非阻塞异步的通信模式。
    • NIO 的基础上引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。

二、代码实现

2.1 工程结构

netty-1.0-01
|-src
    |-main
         |-java
             |-com.lino.netty
             |    |-aio
		         |    |    |-client
		         |    |    |   |-AioClient.java
		         |    |    |   |-AioClientHandler.java
		         |    |    |-server
		         |    |    |   |-AioServer.java
		         |    |    |   |-AioServerChannelInitializer.java
		         |    |    |   |-AioServerHandler.java
		         |    |    |-ChannelAdapter.java
		         |    |    |-ChannelHandler.java
		         |    |    |-ChannelInitializer.java
             |    |-bio
		         |    |    |-client
		         |    |    |   |-BioClient.java
		         |    |    |   |-BioClientHandler.java
		         |    |    |-server
		         |    |    |   |-BioServer.java
		         |    |    |   |-BioServerHandler.java
		         |    |    |-ChannelAdapter.java
		         |    |    |-ChannelHandler.java
             |    |-nio
		         |    |    |-client
		         |    |    |   |-NioClient.java
		         |    |    |   |-NioClientHandler.java
		         |    |    |-server
		         |    |    |   |-NioServer.java
		         |    |    |   |-NioServerHandler.java
		         |    |    |-ChannelAdapter.java
		         |    |    |-ChannelHandler.java

2.2 BIO:同步阻塞I/O实现

2.2.1 BIO处理器

ChannelHandler.java

package com.lino.netty.bio;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.Charset;

/**
 * @description: bio通道处理器
 */
public class ChannelHandler {

    private Socket socket;
    private Charset charset;

    public ChannelHandler(Socket socket, Charset charset) {
        this.socket = socket;
        this.charset = charset;
    }

    public void writeAndFlush(Object msg) {
        OutputStream out = null;
        try {
            out = socket.getOutputStream();
            out.write(msg.toString().getBytes(charset));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Socket socket() {
        return socket;
    }
}

2.2.2 BIO适配器

ChannelAdapter.java

package com.lino.netty.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @description: bio消息处理器
 */
public abstract class ChannelAdapter extends Thread {

    private Socket socket;
    private ChannelHandler channelHandler;
    private Charset charset;

    public ChannelAdapter(Socket socket, Charset charset) {
        this.socket = socket;
        this.charset = charset;
        while (!socket.isConnected()) {
            break;
        }
        channelHandler = new ChannelHandler(this.socket, charset);
        channelActive(channelHandler);
    }

    @Override
    public void run() {
        try {
            BufferedReader input = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), charset));
            String str = null;
            while ((str = input.readLine()) != null) {
                channelRead(channelHandler, str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public abstract void channelActive(ChannelHandler ctx);

    public abstract void channelRead(ChannelHandler ctx, Object msg);

}

2.2.3 BIO客户端处理器

BioClientHandler.java

package com.lino.netty.bio.client;

import com.lino.netty.bio.ChannelAdapter;
import com.lino.netty.bio.ChannelHandler;
import java.net.Socket;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @description: bio消息处理器
 */
public class BioClientHandler extends ChannelAdapter {

    public BioClientHandler(Socket socket, Charset charset) {
        super(socket, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());
        ctx.writeAndFlush("hi! BioClient to msg for you \r\n");
    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
        ctx.writeAndFlush("hi 我已经收到你的消息Success! \r\n");
    }
}

2.2.4 BIO客户端

BioClient.java

package com.lino.netty.bio.client;

import java.io.IOException;
import java.net.Socket;
import java.nio.charset.Charset;

/**
 * @description: bio客户端
 */
public class BioClient {

    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 7397);
            System.out.println("lino-learn-netty bio client start done.");
            BioClientHandler bioClientHandler = new BioClientHandler(socket, Charset.forName("utf-8"));
            bioClientHandler.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.5 BIO服务端处理器

BioServerHandler.java

package com.lino.netty.bio.server;

import com.lino.netty.bio.ChannelAdapter;
import com.lino.netty.bio.ChannelHandler;
import java.net.Socket;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @description: bio服务端处理器
 */
public class BioServerHandler extends ChannelAdapter {

    public BioServerHandler(Socket socket, Charset charset) {
        super(socket, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());
        ctx.writeAndFlush("hi! BioServer to msg for you \r\n");
    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
        ctx.writeAndFlush("hi 我已经收到你的消息Success! \r\n");
    }
}

2.2.6 BIO服务端

BioServer.java

package com.lino.netty.bio.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;

/**
 * @description: 服务端
 */
public class BioServer extends Thread {

    private ServerSocket serverSocket = null;

    public static void main(String[] args) {
        BioServer bioServer = new BioServer();
        bioServer.start();
    }

    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket();
            serverSocket.bind(new InetSocketAddress(7397));
            System.out.println("lino-learn-netty bio server start done.");
            while (true) {
                Socket socket = serverSocket.accept();
                BioServerHandler handler = new BioServerHandler(socket, Charset.forName("GBK"));
                handler.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.7 BIO单元测试

启动 BioServer

lino-learn-netty bio server start done.
链接报告LocalAddress:/192.168.80.1
2023-02-16 16:49:06 接收到消息:hello world bio
2023-02-16 16:49:07 接收到消息:hello world bio
2023-02-16 16:49:09 接收到消息:hello world bio
2023-02-16 16:49:10 接收到消息:hello world bio

网络调试助手

请添加图片描述

2.3 NIO:同步阻非塞I/O实现

2.3.1 NIO处理器

ChannelHandler.java

package com.lino.netty.nio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * @description: nio处理器
 */
public class ChannelHandler {

    private SocketChannel channel;
    private Charset charset;

    public ChannelHandler(SocketChannel channel, Charset charset) {
        this.channel = channel;
        this.charset = charset;
    }

    public void writeAndFlush(Object msg) {
        try {
            byte[] bytes = msg.toString().getBytes(charset);
            ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
            writeBuffer.put(bytes);
            writeBuffer.flip();
            channel.write(writeBuffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SocketChannel channel() {
        return channel;
    }
}

2.3.2 NIO适配器

ChannelAdapter.java

package com.lino.netty.nio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

/**
 * @description: nio适配器
 */
public abstract class ChannelAdapter extends Thread {

    private Selector selector;
    private ChannelHandler channelHandler;
    private Charset charset;

    public ChannelAdapter(Selector selector, Charset charset) {
        this.selector = selector;
        this.charset = charset;
    }

    @Override
    public void run() {
        while (true) {
            try {
                selector.select(1000);
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                SelectionKey key = null;
                while (iterator.hasNext()) {
                    key = iterator.next();
                    iterator.remove();
                    handleInput(key);
                }
            } catch (Exception ignore) {
            }
        }
    }

    private void handleInput(SelectionKey key) throws IOException {
        if (!key.isValid()) {
            return;
        }

        // 客户端SocketChannel
        Class<?> superclass = key.channel().getClass().getSuperclass();
        if (superclass == SocketChannel.class) {
            SocketChannel socketChannel = (SocketChannel) key.channel();
            if (key.isConnectable()) {
                if (socketChannel.finishConnect()) {
                    channelHandler = new ChannelHandler(socketChannel, charset);
                    channelActive(channelHandler);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else {
                    System.exit(1);
                }
            }
        }

        // 服务端ServerSocketChannel
        if (superclass == ServerSocketChannel.class) {
            if (key.isAcceptable()) {
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                socketChannel.register(selector, SelectionKey.OP_READ);

                channelHandler = new ChannelHandler(socketChannel, charset);
                channelActive(channelHandler);
            }
        }

        if (key.isReadable()) {
            SocketChannel socketChannel = (SocketChannel) key.channel();
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            int readBytes = socketChannel.read(readBuffer);
            if (readBytes > 0) {
                readBuffer.flip();
                byte[] bytes = new byte[readBuffer.remaining()];
                readBuffer.get(bytes);
                channelRead(channelHandler, new String(bytes, charset));
            } else if (readBytes < 0) {
                key.cancel();
                socketChannel.close();
            }
        }
    }

    public abstract void channelActive(ChannelHandler ctx);

    public abstract void channelRead(ChannelHandler ctx, Object msg);

}

2.3.3 NIO客户端处理器

NioClientHandler.java

package com.lino.netty.nio.client;

import com.lino.netty.nio.ChannelAdapter;
import com.lino.netty.nio.ChannelHandler;
import java.io.IOException;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @description: nio消息处理器
 */
public class NioClientHandler extends ChannelAdapter {

    public NioClientHandler(Selector selector, Charset charset) {
        super(selector, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        try {
            System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());
            ctx.writeAndFlush("hi! NioClient to msg for you \r\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
        ctx.writeAndFlush("hi 我已经收到你的消息Success! \r\n");
    }
}

2.3.4 NIO客户端

NioClient.java

package com.lino.netty.nio.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * @description: nio客户端
 */
public class NioClient {

    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);

        boolean isConnect = socketChannel.connect(new InetSocketAddress("127.0.0.1", 7397));
        if (isConnect) {
            socketChannel.register(selector, SelectionKey.OP_READ);
        } else {
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
        }
        System.out.println("lino-learn-netty nio client start done.");
        new NioClientHandler(selector, Charset.forName("GBK")).start();
    }
}

2.3.5 NIO服务端处理器

NioServerHandler.java

package com.lino.netty.nio.server;

import com.lino.netty.nio.ChannelAdapter;
import com.lino.netty.nio.ChannelHandler;
import java.io.IOException;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @description: nio服务端处理器
 */
public class NioServerHandler extends ChannelAdapter {

    public NioServerHandler(Selector selector, Charset charset) {
        super(selector, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        try {
            System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());
            ctx.writeAndFlush("hi! NioServer to msg for you \r\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
        ctx.writeAndFlush("hi 我已经收到你的消息Success! \r\n");
    }
}

2.3.6 NIO服务端

NioServer.java

package com.lino.netty.nio.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.charset.Charset;

/**
 * @description: nio服务端
 */
public class NioServer {

    private Selector selector;
    private ServerSocketChannel socketChannel;

    public static void main(String[] args) {
        new NioServer().bind(7397);
    }

    public void bind(int port) {
        try {
            selector = Selector.open();
            socketChannel = ServerSocketChannel.open();
            socketChannel.configureBlocking(false);
            socketChannel.socket().bind(new InetSocketAddress(port), 1024);
            socketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("lino-learn-netty nio server start done.");
            new NioServerHandler(selector, Charset.forName("GBK")).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.3.7 NIO单元测试

启动 NioServer

lino-learn-netty nio server start done.
链接报告LocalAddress:/192.168.80.1:7397
2023-02-16 16:55:46 接收到消息:hello world nio

2023-02-16 16:55:47 接收到消息:hello world nio

2023-02-16 16:55:47 接收到消息:hello world nio

2023-02-16 16:55:53 接收到消息:hello world nio

网络调试助手

在这里插入图片描述

2.4 AIO:同步阻塞I/O实现

2.4.1 AIO处理器

ChannelHandler.java

package com.lino.netty.aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;

/**
 * @description: aio处理器
 */
public class ChannelHandler {

    private AsynchronousSocketChannel channel;
    private Charset charset;

    public ChannelHandler(AsynchronousSocketChannel channel, Charset charset) {
        this.channel = channel;
        this.charset = charset;
    }

    public void writeAndFlush(Object msg) {
        byte[] bytes = msg.toString().getBytes(charset);
        ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
        writeBuffer.put(bytes);
        writeBuffer.flip();
        channel.write(writeBuffer);
    }

    public AsynchronousSocketChannel channel() {
        return channel;
    }

    public void setChannel(AsynchronousSocketChannel channel) {
        this.channel = channel;
    }
}

2.4.2 AIO适配器

ChannelAdapter.java

package com.lino.netty.aio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @description: aio消息处理器
 */
public abstract class ChannelAdapter implements CompletionHandler<Integer, Object> {

    private AsynchronousSocketChannel channel;
    private Charset charset;

    public ChannelAdapter(AsynchronousSocketChannel channel, Charset charset) {
        this.channel = channel;
        this.charset = charset;
        if (channel.isOpen()) {
            channelActive(new ChannelHandler(channel, charset));
        }
    }

    @Override
    public void completed(Integer result, Object attachment) {
        try {
            final ByteBuffer buffer = ByteBuffer.allocate(1024);
            final long timeout = 60 * 60L;
            channel.read(buffer, timeout, TimeUnit.SECONDS, null, new CompletionHandler<Integer, Object>() {
                @Override
                public void completed(Integer result, Object attachment) {
                    if (result == -1) {
                        try {
                            channelInactive(new ChannelHandler(channel, charset));
                            channel.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    buffer.flip();
                    channelRead(new ChannelHandler(channel, charset), charset.decode(buffer));
                    buffer.clear();
                    channel.read(buffer, timeout, TimeUnit.SECONDS, null, this);
                }

                @Override
                public void failed(Throwable exc, Object attachment) {
                    exc.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void failed(Throwable exc, Object attachment) {
        exc.printStackTrace();
    }

    public abstract void channelActive(ChannelHandler ctx);

    public abstract void channelInactive(ChannelHandler ctx);

    /**
     * 读取消息抽象类
     *
     * @param ctx 通道处理器
     * @param msg 消息对象
     */
    public abstract void channelRead(ChannelHandler ctx, Object msg);
}

2.4.3 AIO通道初始化

ChannelInitializer.java

package com.lino.netty.aio;

import com.lino.netty.aio.server.AioServer;

import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

/**
 * @description: aio通道初始化
 */
public abstract class ChannelInitializer implements CompletionHandler<AsynchronousSocketChannel, AioServer> {

    @Override
    public void completed(AsynchronousSocketChannel channel, AioServer attachment) {
        try {
            initChannel(channel);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 在此接受客户端链接
            attachment.serverSocketChannel().accept(attachment, this);
        }
    }

    @Override
    public void failed(Throwable exc, AioServer attachment) {
        exc.printStackTrace();
    }

    protected abstract void initChannel(AsynchronousSocketChannel channel) throws Exception;
}

2.4.4 AIO客户端处理器

AioClientHandler.java

package com.lino.netty.aio.client;

import com.lino.netty.aio.ChannelAdapter;
import com.lino.netty.aio.ChannelHandler;
import java.io.IOException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.Date;

/**
 * @description: aio客户端处理器
 */
public class AioClientHandler extends ChannelAdapter {

    public AioClientHandler(AsynchronousSocketChannel channel, Charset charset) {
        super(channel, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        try {
            System.out.println("链接报告信息:" + ctx.channel().getRemoteAddress());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void channelInactive(ChannelHandler ctx) {

    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println("客户端收到:" + new Date() + " " + msg + "\r\n");
        ctx.writeAndFlush("客户端信息处理Success!\r\n");
    }
}

2.4.5 AIO客户端

AioClient.java

package com.lino.netty.aio.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.Future;

/**
 * @description: aio客户端
 */
public class AioClient {

    public static void main(String[] args) throws Exception {
        AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();
        Future<Void> future = socketChannel.connect(new InetSocketAddress("127.0.0.1", 7397));
        System.out.println("lino-learn-netty aio client start done.");
        future.get();
        socketChannel.read(ByteBuffer.allocate(1024), null,
                new AioClientHandler(socketChannel, Charset.forName("GBK")));
        Thread.sleep(100000);
    }
}

2.4.6 AIO服务端处理器

AioServerHandler.java

package com.lino.netty.aio.server;

import com.lino.netty.aio.ChannelAdapter;
import com.lino.netty.aio.ChannelHandler;
import java.io.IOException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.Date;

/**
 * @description: aio服务端处理器
 */
public class AioServerHandler extends ChannelAdapter {

    public AioServerHandler(AsynchronousSocketChannel channel, Charset charset) {
        super(channel, charset);
    }

    @Override
    public void channelActive(ChannelHandler ctx) {
        try {
            System.out.println("链接报告信息:" + ctx.channel().getRemoteAddress());
            // 通知客户端链接建立成功
            ctx.writeAndFlush("通知服务端链接建立成功" + " " + new Date() + " " + ctx.channel().getRemoteAddress() + "\r\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void channelInactive(ChannelHandler ctx) {

    }

    @Override
    public void channelRead(ChannelHandler ctx, Object msg) {
        System.out.println("服务端收到:" + new Date() + " " + msg + "\r\n");
        ctx.writeAndFlush("服务端信息处理Success!\r\n");
    }
}

2.4.7 AIO服务端通道初始化

AioServerChannelInitializer.java

package com.lino.netty.aio.server;

import com.lino.netty.aio.ChannelInitializer;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @description: aio服务端通道初始化
 */
public class AioServerChannelInitializer extends ChannelInitializer {
    @Override
    protected void initChannel(AsynchronousSocketChannel channel) throws Exception {
        channel.read(ByteBuffer.allocate(1024), 10, TimeUnit.SECONDS, null, new AioServerHandler(channel, Charset.forName("GBK")));
    }
}

2.4.8 AIO服务端

AioServer.java

package com.lino.netty.aio.server;

import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;

/**
 * @description: aio服务端
 */
public class AioServer extends Thread {

    private AsynchronousServerSocketChannel serverSocketChannel;

    @Override
    public void run() {
        try {
            serverSocketChannel = AsynchronousServerSocketChannel.open(AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10));
            serverSocketChannel.bind(new InetSocketAddress(7397));
            System.out.println("lino-learn-netty aio server start done.");
            // 等待
            CountDownLatch latch = new CountDownLatch(1);
            serverSocketChannel.accept(this, new AioServerChannelInitializer());
            latch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public AsynchronousServerSocketChannel serverSocketChannel() {
        return serverSocketChannel;
    }

    public static void main(String[] args) {
        new AioServer().start();
    }
}

2.4.9 AIO单元测试

启动 AioServer

lino-learn-netty aio server start done.
链接报告信息:/192.168.80.1:63121
服务端收到:Thu Feb 16 17:03:38 CST 2023 hello world aio

服务端收到:Thu Feb 16 17:03:39 CST 2023 hello world aio

服务端收到:Thu Feb 16 17:03:41 CST 2023 hello world aio

网络调试助手
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/999955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络第五章——传输层(上)

早知如此绊人心&#xff0c;何如当初莫相识 文章目录 前言 前言 虽然说是手机和手机之间的通信但是其实是手机之间的进程和进程之间的通信&#xff0c;所以这一章主要是研究进程之间通信的问题&#xff0c;在计算机网络中有一个重要的问题&#xff0c;在进行数据通信和资源共享…

【分享】golang windows 运行报错 undefined: syscall.SIGUSR1

在跟着煎鱼大佬学习 Golang-gin的时候&#xff0c;"在优雅的重启服务篇" ,为了gin服务的热更新&#xff0c;采用了 endlessfresh的方案&#xff0c;安装endless后无法在windows本地调试,然后报错。 (优雅的重启服务-地鼠文档优雅的重启服务-我不怎么喜欢左写写&#…

linux内核模块编译方法之模块编程详解

文章目录 一、模块传参二、模块依赖三、内核空间和用户空间四、执行流五、模块编程与应用编程的比较六、内核接口头文件查询总结 本期和大家主要分享的是驱动开发内核编译过程中对于模块是如何设计的&#xff0c;进行了详细的分享&#xff0c;从模块传参、模块依赖一直到内核空…

楼顶空地适合建造气膜体育馆吗?

众所周知&#xff0c;传统建筑的荷载太大&#xff0c;出于安全考虑&#xff0c;是不适合继续在楼顶加盖传统结构体育馆的&#xff0c;但是&#xff0c;气膜体育馆作为一种装配式建筑&#xff0c;它是可以在城市高空上建造一个轻盈又新颖独特的全天候气膜馆。 气膜体育馆作为一种…

小黑自己在家尝试涮牛排,肚子又开始了新一轮的胀气,喝到了酱香拿铁并烫了纹理发型体验一把的leetcode之旅:123. 买卖股票的最佳时机 III

动态规划1 class Solution:def maxProfit(self, prices: List[int]) -> int:# 数组长度n len(prices)if n < 2:return 0# 动态规划变量# 第一次买的价格first_price prices[0]# 第一次卖的收益first_cell 0# 第二次买的价格second_price prices[0]# 第二次卖second_…

STM32H750 HAL CUBEMX 时钟失败及死机无法下载问题解决

芯片采样电压设置&#xff0c;否则 无法运行 解决死机问题 设置swd 模式 短接 boot0 —vcc 3.3v即可正常下载

驱动开发,stm32mp157a开发板的led灯控制实验

1.实验目的 编写LED灯的驱动&#xff0c;在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制&#xff1b; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭&#xff1a; RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…

5. HBase必知必会之理论进阶篇

HBase必知必会之理论进阶篇 1.1 集群搭建以及规模预测1.1.1 HBase集群搭建1.1.2 HBase集群规划 1.2 HBase重要的概念1.2.1 snapshot1.2.2 region 切分1.2.3 RIT1.2.4 HBase读优化1.2.4.1 客户端优化1.2.4.2 服务端优化1.2.4.3 hdfs 优化 1.2.5 HBase写优化1.2.5.1 客户端优化1.…

Linux centos7 bash编程训练__打印各类形状

利用for循环&#xff0c;打印各种不同的三角形、矩形和菱形。 主要是fort循环嵌套使用&#xff0c;及条件判断等。 因方法简单&#xff0c;不作更多解释&#xff0c;部分注释可以帮助初学者掌握代码。 下面列出代码&#xff0c;供参考。 #! /bin/bash ## 打印输出各种*型形…

中企出海,用火山引擎DataTester开启增长第一步

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 今年 Google 宣布其提供的A/B测试工具 Optimize 将在2023年9月30号停止服务。在全球化浪潮席卷下&#xff0c;越来越多的中国企业正在加速走向全球市场&#xff0c;…

使用 Webpack 从 0 到 1 构建 Vue3 项目 + ts

使用 Webpack 从 0 到 1 构建 Vue3 项目 1.初始化项目结构2.安装 webpack&#xff0c;补充智能提示3.初步编写 webpack.config.js3.1设置入口文件及出口文件3.2 指定 html 模板位置 4.配置 运行/打包 命令&#xff0c;首次打包项目5.添加 Vue 及相关配置5.1安装并引入 vue5.2 补…

一个详细且完整的公司局域网搭建案例,跟着操作!

局域网(Local Area Network&#xff0c;简称LAN)&#xff0c;用于将有限范围内&#xff08;例如一个实验室、一层办公楼或者校园&#xff09;的各种计算机、终端与外部设备互联成网。公司局域网怎么建立&#xff1f;首先来了解下不同规模企业网络组建方式。 10人以下企业网络组…

固定资产管理表怎么填写

在现代企业管理中&#xff0c;固定资产的管理是至关重要的环节。它不仅关系到企业运营的效率&#xff0c;也直接影响到企业的财务状况。因此&#xff0c;正确、有效地填写和管理固定资产管理表显得尤为重要。并提供一些创新的方法来优化这一过程。  让我们理解什么是固定资产…

Win10 cmd默认使用管理员身份运行的修改

一、在开始菜单搜索cmd&#xff0c;打开快捷方式文件位置 二、鼠标右键快捷方式&#xff0c;打开属性 三、选择高级&#xff0c;再勾选用管理员身份运行&#xff0c;点击确定即可

文心一言插件开发全流程,ERNIE-Bot-SDK可以调用文心一言的能力

文心一言插件开发 前言插件插件是什么工作原理申请开发权限 开始第一步&#xff1a;安装python第二步&#xff1a;搭建项目manifest 描述文件&#xff1a;ai-plugin.json插件服务描述文件&#xff1a;openapi.yaml开发自己的plugin-server 第三步&#xff1a;上传插件 SDK相关链…

记录一次开机内存分析的全过程

作者&#xff1a;zzy的学习笔记 记录一次开机内存分析的全过程&#xff0c;尽量详尽的介绍常用内存分析工具和命令行的使用&#xff0c;结合具体问题探讨开机内存分析的实践经验。通过这篇文章我会介绍开机内存的常用测试分析工具的基本使用方法&#xff0c;以及如何通过抓取出…

在UMG中播放图像序列,出现卡帧怎么办?

在虚幻引擎中播放图像序列 前期步骤可以参考上面链接中官方文档的步骤1-13 如果在媒体播放器中播放的时候&#xff0c;出现卡帧现象&#xff0c;说明你的图片序列的帧率与默认的不匹配 需要在lmg Media Source类型文件中&#xff0c;覆写你的帧率 比如&#xff0c;我的图片序…

VSCode错误整理

文章目录 一、zsh: command not found: python二、Python pip安装Django异常Could not find a version that satisfies the requirement pytz (from django)三、WARNING: You are using pip version 21.2.4, however version 23.2.1 is available.四、pip install django下载报…

Sui参会必备|Token 2049活动一览

TOKEN2049是在新加坡举办的一年一度首屈一指地加密货币活动&#xff0c;吸引了顶级的Web3公司和项目的创始人和高管&#xff0c;他们将在这里分享行业观点、聚焦全球发展&#xff0c;同时以独特且广泛的视角审视这个生态系统及其广阔的机会。 自5月份主网上线以来&#xff0c;S…

lv3 嵌入式开发-11 Linux下GDB调试工具

目录 1 GDB简介 2 GDB基本命令 3 GDB调试程序 1 GDB简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说&#xff0c;GDB主要帮助你完成下面四个方面的功能&#xff1a; 1、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#…