用 Java Nio 实现一个和Netty一样的功能Server端和client端 并写上注释
时间: 2024-05-04 09:17:39 浏览: 12
以下是一个使用Java NIO实现的简单的Server端和Client端,类似于Netty的功能,注释已经添加在代码中:
Server端:
```java
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;
import java.util.Set;
public class NioServer {
private Selector selector;
private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
public static void main(String[] args) {
new NioServer().startServer();
}
public void startServer() {
try {
// 创建Selector
selector = Selector.open();
// 创建ServerSocketChannel并注册到Selector
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8888));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started...");
while (true) {
// 监听Channel上的事件,阻塞直到有事件发生
int selectCount = selector.select();
if (selectCount == 0) {
continue;
}
// 获取发生事件的Channel的SelectionKey集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
// 处理事件
handleEvent(selectionKey);
// 处理完事件后,从集合中移除SelectionKey
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleEvent(SelectionKey selectionKey) throws IOException {
if (selectionKey.isAcceptable()) {
// 处理连接事件
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Client connected...");
} else if (selectionKey.isReadable()) {
// 处理读事件
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
readBuffer.clear();
int readCount = socketChannel.read(readBuffer);
if (readCount > 0) {
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String message = new String(bytes);
System.out.println("Received message: " + message);
// 处理业务逻辑
String response = "Hello client";
writeBuffer.clear();
writeBuffer.put(response.getBytes());
writeBuffer.flip();
// 注册写事件
socketChannel.register(selector, SelectionKey.OP_WRITE);
} else if (readCount == -1) {
// 客户端关闭连接
socketChannel.close();
}
} else if (selectionKey.isWritable()) {
// 处理写事件
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
socketChannel.write(writeBuffer);
// 注册读事件
socketChannel.register(selector, SelectionKey.OP_READ);
}
}
}
```
Client端:
```java
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class NioClient {
private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
public static void main(String[] args) {
new NioClient().startClient();
}
public void startClient() {
try {
// 创建SocketChannel并连接到Server
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 8888));
System.out.println("Connected to server...");
// 发送数据
String message = "Hello server";
writeBuffer.clear();
writeBuffer.put(message.getBytes());
writeBuffer.flip();
socketChannel.write(writeBuffer);
System.out.println("Sent message: " + message);
while (true) {
// 接收数据
readBuffer.clear();
int readCount = socketChannel.read(readBuffer);
if (readCount > 0) {
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String response = new String(bytes);
System.out.println("Received message: " + response);
break;
}
}
// 关闭连接
socketChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```