feat(新增): 🚀 nio编程

This commit is contained in:
bunny 2024-05-23 10:08:25 +08:00
parent 698453a522
commit f708469f43
23 changed files with 186 additions and 3 deletions

View File

@ -2,6 +2,7 @@
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />

View File

@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,java.nio.channels.ServerSocketChannel,open" />
</inspection_tool>
</profile>
</component>

View File

@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -9,8 +9,28 @@
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target>
<lombok.version>1.18.32</lombok.version>
</properties>
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- hu tool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.13</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package cn.bunny.file_dir;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
@Slf4j
public class ClientDemo {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 8080));
// socketChannel.write(Charset.defaultCharset().encode("hello"))
System.out.println("等待。。。");
}
}

View File

@ -0,0 +1,61 @@
package cn.bunny.file_dir;
import java.io.IOException;
import java.net.InetSocketAddress;
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.util.Iterator;
public class Server2Demo {
public static void main(String[] args) throws IOException {
// 创建Selector
Selector selector = Selector.open();
// 创建服务器
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
SelectionKey selectionKey = serverSocketChannel.register(selector, 0, null);
// 只关注channel
selectionKey.interestOps(SelectionKey.OP_ACCEPT);
System.out.println(STR."注册时的key\{selectionKey}");
// 模拟监听端口
serverSocketChannel.bind(new InetSocketAddress(8080));
while (true) {
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
// 需要移出key在事件集合中需要移出
iterator.remove();
if (key.isAcceptable()) {
ServerSocketChannel cancel = (ServerSocketChannel) key.channel();
SocketChannel accept = cancel.accept();
accept.configureBlocking(false);
SelectionKey scKey = accept.register(selector, 0, null);
scKey.interestOps(SelectionKey.OP_READ);
System.out.println(STR."accept的key\{accept}");
System.out.println(STR."scKey\{scKey}");
} else if (key.isReadable()) {
try {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(16);
// 如果客户端断开这里会报错
channel.read(buffer);
buffer.flip();
} catch (IOException exception) {
exception.printStackTrace();
// 断开后会进行删除
key.cancel();
}
}
}
}
}
}

View File

@ -0,0 +1,76 @@
package cn.bunny.file_dir;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.InetSocketAddress;
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.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
@Slf4j
public class ServerDemo {
// 阻塞模式下只能接受一个连接
public static void main(String[] args) throws IOException {
// 创建Selector
Selector selector = Selector.open();
// 创建服务器
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
SelectionKey selectionKey = serverSocketChannel.register(selector, 0, null);
// 只关注channel时间
selectionKey.interestOps(SelectionKey.OP_ACCEPT);
System.out.println(STR."注册时的key:\{selectionKey}");
// 模拟监听端口
serverSocketChannel.bind(new InetSocketAddress(8080));
while (true) {
selector.select();
// 处理事件
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
System.out.println(STR."key的值为\{key}");
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
SocketChannel accept = channel.accept();
System.out.println(STR."接受到的值\{accept}");
}
}
}
private static void m1() throws IOException {
// 使用 ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(16);
// 创建服务器
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
// 模拟监听端口
serverSocketChannel.bind(new InetSocketAddress(8080));
// 连接集合
ArrayList<SocketChannel> channels = new ArrayList<>();
while (true) {
SocketChannel accept = serverSocketChannel.accept();
if (accept != null) {
accept.configureBlocking(false);
channels.add(accept);
}
for (SocketChannel channel : channels) {
int read = channel.read(buffer);
// 当read大于0时才去读
if (read > 0) {
buffer.flip();
System.out.println((STR."读取到的内容:\{StandardCharsets.UTF_8.decode(buffer)}"));
buffer.clear();
}
}
}
}
}