不使用selector
package com.yimin.springdemovscode.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class NioDemo {
// 保存客户端连接
static final List<SocketChannel> channels = new ArrayList<>();
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);// 连接非阻塞
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
while (true) {
SocketChannel socketChannel = serverSocketChannel.accept();// 客户端
if (socketChannel != null) {
System.out.println("客户端连接" + socketChannel.getRemoteAddress());
socketChannel.configureBlocking(false);// 读数据非阻塞
channels.add(socketChannel);// 保存客户端连接
}
Iterator<SocketChannel> it = channels.iterator();
while (it.hasNext()) {
SocketChannel channel = it.next();
ByteBuffer buf = ByteBuffer.allocate(16);
int read = channel.read(buf);
if (read == -1) { // 客户端关闭连接
it.remove();
channel.close();
} else if (read > 0) {
System.out.println("read:" + read);
System.out.println("读取到客户端消息:" + new String(buf.array()));
}
}
}
}
}
使用selector
package com.yimin.springdemovscode.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 demo
*/
public class NioDemoWithSelector {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 服务端
serverSocketChannel.configureBlocking(false);// 连接非阻塞
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
Selector selector = Selector.open();// 多路复用器
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// 注册连接事件
// 由selector进行监听,避免空轮询
while (true) {
selector.select();// 阻塞,等待事件发生
Iterator<SelectionKey> it = selector.selectedKeys().iterator();// 发生的事件集合
while (it.hasNext()) {
SelectionKey key = it.next();// 本次处理的事件
it.remove();// 移除本次处理的事件,需要手动移除,避免重复处理
switch (key.interestOps()) {
case SelectionKey.OP_ACCEPT: // 接受连接事件
ServerSocketChannel channel = (ServerSocketChannel) key.channel();// 获取发生事件的channel
SocketChannel socketChannel = channel.accept();// 接受客户端连接,不会阻塞了
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);// 客户端注册读事件
break;
case SelectionKey.OP_READ: // 读事件
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buf = ByteBuffer.allocate(16);
int read = sc.read(buf);
if (read == -1) { // 客户端关闭连接
sc.close();
key.cancel(); // 不处理本次事件
} else if (read > 0) {
System.out.println("read:" + read);
System.out.println("读取到客户端消息:" + new String(buf.array()));
}
break;
default:
break;
}
}
}
}
}