NIO(New Input/Output)是Java中的一种基于非阻塞I/O的编程模型,它允许服务器和客户端在同一时刻处理多个连接,从而提高了并发性能。以下是NIO服务器与客户端实现技术的详解:
1. NIO服务器实现技术:
NIO服务器通常使用Selector类来实现非阻塞I/O。以下是一个简单的NIO服务器实现示例:
```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;
public class NIOServer {
public static void main(String[] args) throws IOException {
int port = 8080;
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(port));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
Selector selector = Selector.open();
while (true) {
SelectionKey key = serverSocketChannel.select();
if (key == null) {
continue;
}
if (key.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead > 0) {
System.out.println("Received: " + new String(buffer.array(), 0, bytesRead));
}
}
}
}
}
```
在这个示例中,我们首先创建一个ServerSocketChannel,并将其绑定到指定的端口。然后,我们配置该Channel为非阻塞模式,并注册一个Selector。接下来,我们进入一个无限循环,每次循环时,我们调用serverSocketChannel的select方法来等待新的连接。如果接收到新的连接(即键为Acceptable),我们接受这个连接并注册一个SocketChannel到Selector。如果读取到数据(即键为Readable),我们读取数据并打印出来。
2. NIO客户端实现技术:
NIO客户端通常使用NIO的SocketChannel类来实现非阻塞I/O。以下是一个简单的NIO客户端实现示例:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
public class NIOClient {
public static void main(String[] args) throws IOException {
String host = "localhost";
int port = 8080;
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(host, port));
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead > 0) {
System.out.println("Received: " + new String(buffer.array(), 0, bytesRead));
}
}
}
```
在这个示例中,我们首先创建一个SocketChannel,并将其连接到指定的主机和端口。然后,我们配置该Channel为非阻塞模式,并注册一个Selector。接下来,我们进入一个无限循环,每次循环时,我们读取来自服务器的数据。如果读取到数据(即键为Readable),我们读取数据并打印出来。