You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java NIO多端口Socket服务端抛出ClosedChannelException与空指针异常问题

异常2:NullPointerException 定位与修复

触发原因

这是Java NIO Selector的经典易错点:selector.selectedKeys()返回的就绪事件键集合,不会自动删除已处理的键,必须手动调用迭代器的remove()方法移除已处理的键。你的代码没有做该操作,同一个ACCEPT事件的键会被反复遍历,第二次处理时没有新连接接入,ServerSocketChannel.accept()会返回null,后续调用null.socket()就会抛出空指针。

修复方案

在主服务端的迭代器循环中,取出键后立刻删除已处理的键:

while (selector.isOpen()) {
    try {
        selector.select();
        Set readyKeys = selector.selectedKeys();
        Iterator iterator = readyKeys.iterator();
        System.out.println(readyKeys.size());
        while (iterator.hasNext()) {
            SelectionKey key = (SelectionKey) iterator.next();
            // 新增这行,手动移除已处理的键,避免重复遍历
            iterator.remove();
            if (key.isAcceptable()) {
                SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
                Socket socket = socketChannel.socket();
                System.out.println("Accepted From: " + socket);
                DataInputStream dis = new DataInputStream(socket.getInputStream());
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                Thread t = new ClientHandler(socket, dis, dos);
                t.start();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(0);
    }
}

额外优化建议

  • 多上报端同时写compiled.txt会有并发覆盖问题,上述修复代码中已经加了类锁保证写文件的原子性。
  • readUTF()最大仅支持64KB长度的字符串,如果你的新闻文件较大,建议改成字节流分段传输,避免抛出UTF数据长度超限异常。

内容的提问来源于stack exchange,提问作者user8331240

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:27:02