文章目录
- 一、前言介绍
- 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 中,提供了一些关于使用 IO 的 API,可以供开发者来读写外部数据和文件。
- Java IO 是比较难学习的知识点,并且随着 Java 的发展,为了提供更好的数据传输性能,目前有三种 IO 共存。
BIO
、NIO
、AIO
。
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
网络调试助手