NIO非阻塞IO
NIO实现客户端程序
public class NIOClient {
public static void main(String[] args) throws Exception {
//1. 得到一个网络通道
SocketChannel channel = SocketChannel.open();
//2. 设置非阻塞方式
channel.configureBlocking(false);
//3. 提供服务器端的 IP 地址和端口号
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 9999);
//4. 连接服务器端
if (!channel.connect(address)) {
while (!channel.finishConnect()) { //nio 作为非阻塞式的优势
System.out.println("Client:连接服务器端的同时,我还可以干别的一些事情");
}
}
//5. 得到一个缓冲区并存入数据
String msg = "hello,Server";
ByteBuffer writeBuf = ByteBuffer.wrap(msg.getBytes());
//6. 发送数据
channel.write(writeBuf);
System.in.read();
}
}
NIO实现服务端程序
public class NIOServer {
public static void main(String[] args) throws Exception {
//1. 得到一个 ServerSocketChannel 对象 老大
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//2. 得到一个 Selector 对象 间谍
Selector selector = Selector.open();
//3. 绑定一个端口号
serverSocketChannel.bind(new InetSocketAddress(9999));
//4. 设置非阻塞方式
serverSocketChannel.configureBlocking(false);
//5. 把 ServerSocketChannel 对象注册给 Selector 对象
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//6. 干活
while (true) {
//6.1 监控客户端
if (selector.select(2000) == 0) { //nio 非阻塞式的优势
System.out.println("Server:没有客户端搭理我,我就干点别的事");
continue;
}
//6.2 得到 SelectionKey,判断通道里的事件
Iterator<SelectionKey> keyIterator = selector.selectedKeys()
.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) { //客户端连接请求事件
System.out.println("OP_ACCEPT");
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ,
ByteBuffer.allocate(1024));
}
if (key.isReadable()) { //读取客户端数据事件
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = (ByteBuffer) key.attachment();
channel.read(buffer);
System.out.println("客户端发来数据:" + new String(buffer.array()));
}
// 6.3 手动从集合中移除当前 key,防止重复处理
keyIterator.remove();
}
}
}
}