更新时间:2023-03-22 来源:黑马程序员 浏览量:
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(); } } } }
这些代码仅作为简单的演示,实际应用中需要考虑更多的细节和异常处理。