这篇来讲解java网络编程之后高性能模型。NIO,有些书成为Non-blocking IO 非阻塞IO,这个是相对于BIO来说的。还有一种说法,New IO,顾名思义新的IO,这个是相对于旧版io的定义。
这里就用前面一种,非阻塞IO。这个针对前面的版本做了哪些优化,下面先看看它的模型。
Nio Server
package com.pimee.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;
/**
* Nio Server端
*
* @author Bruce Shaw
*
*/
public class NioServer {
public static void main(String[] args) {
try {
// 创建serverSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 设置非阻塞,这个地方可以根据需要在不同的时间设置,设置之后就会使用非阻塞模式,比如在连接时使用阻塞模式,连接之后切换到非阻塞模式
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(8080));
// 创建一个selector
Selector selector = Selector.open();
// 注册连接事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
for (; selector.select() > 0;) {
// 获取selector上的事件
Iterator iterator = selector.selectedKeys().iterator();
for (; iterator.hasNext();) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()) {
// 连接上了,获取socketChannel
SocketChannel socketChannel = serverSocketChannel.accept();
// 设置非阻塞
socketChannel.configureBlocking(false);
// 注册读取事件
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
// 可读事件到来
SocketChannel channel = (SocketChannel) selectionKey.channel();
// 创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = 0;
for (; (len = channel.read(buffer)) > 0;) {
System.out.println(new String(buffer.array(), 0, len));
buffer.clear();
}
}
// 删除此事件,下次就不会进到这个事件中来
iterator.remove();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Nio Client
package com.pimee.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
/**
* Nio Client端
*
* @author Bruce Shaw
*
*/
public class NioClient {
public static void main(String[] args) {
try {
// 创建socketChannel
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(8080));
// 设置非阻塞
socketChannel.configureBlocking(false);
// 创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 往缓冲区中写入数据
buffer.put("Hello server".getBytes());
// 切换读模式
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}