我正在尝试运行最简单的仅接受连接的NIO服务器。
public static void main(String[] args) throws IOException{
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress("localhost", 1456));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
try {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
if (key.isAcceptable())
accept(key, selector);
}
} catch (IOException e) {
System.err.println("I/O exception occurred");
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void accept(SelectionKey key, Selector selector) throws IOException{
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false); //<------- NPE Here
channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
channel.register(selector, SelectionKey.OP_READ);
}
和最简单的I / O客户端:
public static void main(String[] ars) throws IOException{
Socket s = new Socket("localhost", 1456);
OutputStream ous = s.getOutputStream();
InputStream is = s.getInputStream();
while (true) {
ous.write(new byte[]{1, 2, 3, 3, 4, 5, 7, 1, 2, 4, 5, 6, 7, 8});
is.read();
}
}
当我运行这两个过程时,会得到一堆
NullPointterExceeption
。客户端第一次连接时,可以。我们检索密钥,获取频道并接受传入的连接。
但是由于我不清楚这个问题,原因是我一直在检索可接受的密钥并尝试接受更多的密钥。
SocketChannel channel = serverChannel.accept();
为空,我得到NPE
。但是,为什么总是向我通知接受的密钥?我做错什么了?
最佳答案
处理后,需要从所选集中删除每个SelectionKey
。否则,即使尚未真正准备就绪,您仍将再次得到同一事件:因此,例如accept()
将返回null。
您需要查看一个教程。只是弥补没有好处。请参阅Oracle NIO教程。