Java中网络IO的实现方式主要有BIO、NIO、AIO三种。下面分别进行介绍。
BIO
BIO即Blocking IO,阻塞式IO,是一种传输方式。BIO的特点是同步阻塞,也就是说,客户端请求到来后,服务器必须处理完该请求才能执行下一步操作,高并发下无法满足需求。使用BIO方式,可以使用Socket
和ServerSocket
类进行通信。
下面是一个BIO的示例,该示例利用BIO模拟了一个简单的服务器。
public class SocketHandler extends Thread {
private InputStream inputStream;
private OutputStream outputStream;
public SocketHandler(Socket socket) throws IOException {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
}
@Override
public void run() {
try {
byte[] buffer = new byte[1024];
int len = 0;
if ((len = inputStream.read(buffer)) != -1) {
String request = new String(buffer, 0, len);
String response = "response to " + request;
outputStream.write(response.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Server {
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(8899);
while (true) {
Socket socket = serverSocket.accept();
SocketHandler socketHandler = new SocketHandler(socket);
socketHandler.start();
}
}
public static void main(String[] args) throws IOException {
Server server = new Server();
server.start();
}
}
NIO
NIO即New IO,新IO,是JDK的1.4版本中引入的新特性。相对于BIO的同步阻塞,NIO采用事件驱动机制,利用轮询的方式进行事件的处理,因此可以更好地支持高并发。使用NIO方式,可以使用Channel
和Selector
类进行通信。
下面是一个NIO的示例,该示例利用NIO模拟了一个简单的服务器。
public class SocketHandler implements Runnable {
private SocketChannel socketChannel;
private Selector selector;
private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
public SocketHandler(SocketChannel socketChannel, Selector selector) throws IOException {
this.socketChannel = socketChannel;
this.selector = selector;
}
@Override
public void run() {
try {
while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) continue;
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isReadable()) {
byteBuffer.clear();
socketChannel.read(byteBuffer);
byteBuffer.flip();
String request = new String(byteBuffer.array(), 0, byteBuffer.limit());
String response = "response to " + request;
socketChannel.write(ByteBuffer.wrap(response.getBytes()));
}
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Server {
public void start() throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(8899));
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) continue;
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
new Thread(new SocketHandler(socketChannel, selector)).start();
}
iterator.remove();
}
}
}
public static void main(String[] args) throws IOException {
Server server = new Server();
server.start();
}
}
AIO
AIO即Asynchronous IO,异步IO,在JDK的1.7版本中引入。相对于NIO的轮询方式,AIO采用异步回调的方式进行事件的处理,更加符合面向对象的思想。使用AIO方式,可以使用AsynchronousServerSocketChannel
和CompletionHandler
类进行通信。
下面是一个AIO的示例,该示例利用AIO模拟了一个简单的服务器。
public class SocketHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {
private AsynchronousServerSocketChannel serverSocketChannel;
public SocketHandler(AsynchronousServerSocketChannel serverSocketChannel) {
this.serverSocketChannel = serverSocketChannel;
}
@Override
public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
try {
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer, attachment, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
try {
buffer.flip();
String request = new String(buffer.array(), 0, buffer.limit());
String response = "response to " + request;
socketChannel.write(ByteBuffer.wrap(response.getBytes()));
buffer.clear();
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
} finally {
serverSocketChannel.accept(attachment, this);
}
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
}
public class Server {
public void start() throws Exception {
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8899));
serverSocketChannel.accept(null, new SocketHandler(serverSocketChannel));
System.in.read();
}
public static void main(String[] args) throws Exception {
Server server = new Server();
server.start();
}
}
以上就是Java中网络IO的实现方式,包括BIO、NIO、AIO三种,分别适用于不同的场景。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中网络IO的实现方式(BIO、NIO、AIO)介绍 - Python技术站