https://www.itheima.com/news/20230322/092941.html
BIO、NIO、AIO 都是 Java 中用于实现网络编程的三种不同的方式,它们有以下区别:
1.BIO (Blocking I/O):传统的阻塞式 I/O,每个连接都需要一个线程来处理,当连接数较多时,会导致系统资源消耗严重,性能较差。
2.NIO (Non-blocking I/O):非阻塞式 I/O,通过使用单线程轮询多个连接的方式来实现高效的处理方式,可以支持较大数量的并发连接,但编程模型较为复杂。
3.AIO (Asynchronous I/O):异步 I/O,通过回调方式实现高效的 I/O 操作,可以大大降低系统资源的消耗,适用于高并发、高吞吐量的场景,但在实际使用中可能会受到操作系统和硬件的限制。
下面是 Java 中分别使用 BIO、NIO、AIO 实现简单的网络通信的示例代码:
BIO 示例代码:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
try {
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
NIO 示例代码:
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 NioServer {
private Selector selector;
public static void main(String[] args) throws IOException {
new NioServer().startServer();
}
public void startServer() throws IOException {
selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress("localhost", 8000));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started on port 8000...");
while (true) {
selector.select();
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
acceptConnection(key);
} else if (key.isReadable()) {
readFromClient(key);
}
keyIterator.remove();
}
}
}
private void acceptConnection(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Connection accepted from client: " + socketChannel.getRemoteAddress());
}
private void readFromClient(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
System.out.println("Connection closed by client: " + socketChannel.getRemoteAddress());
} else {
byte[] data = new byte[bytesRead];
buffer.flip();
buffer.get(data, 0, bytesRead);
System.out.println("Received message from client: " + new String(data));
socketChannel.write(ByteBuffer.wrap("Hello from server".getBytes()));
}
}
}
AIO 示例代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AioServer {
public static void main(String[] args) throws IOException {
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
serverSocketChannel.accept(null, this);
ByteBuffer buffer = ByteBuffer.allocate(1024);
result.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer buffer) {
if (result > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);
System.out.println(new String(bytes));
buffer.clear();
result.write(ByteBuffer.wrap("Hello, client!".getBytes()));
} else if (result == -1) {
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这些代码仅作为简单的演示,实际应用中需要考虑更多的细节和异常处理。