繁体   English   中英

了解Java NIO套接字通道中NullPointerException的原因

[英]Understanding Cause of NullPointerException in Java NIO Socket Channel

我使用java nio整理了一个简单的回显类型服务器应用程序。 尽管它能够写入数据,但始终会引发以下异常。 谁能解释为什么会这样? 我的代码如下。 在创建包含run方法的线程之前,请确保key.isAcceptable()为true。

线程“ pool-1-thread-2”中的异常java.lang.NullPointerException

ExecutorService pool = Executors.newFixedPool(5);
...
try {
    pool.execute(                                           
        new Thread() {
            @Override public void run() {
                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                SocketChannel sc = null;
                try {
                    sc = ssc.accept();
                    String response = "Server thread (" + Thread.currentThread().getId() + ") Current time: " + new Date();
                    ByteBuffer bytes = encoder.encode(CharBuffer.wrap(response));
                    sc.write(bytes);
                } catch (java.io.IOException e) {
                    System.out.println("Exception: " + e.getMessage());                                                                              
                } finally {
                    try {
                        if (sc.isOpen()) sc.close(); // This is the line causing the exception to be thrown. If the check is changed to (sc != null) no exceptions are thrown.
                    } catch (java.io.IOException e) {
                        System.out.println("Exception: " + e.getMessage());
                    }
                }
            }
        }
    );
} catch (java.lang.Exception e) {
    System.out.println("Interrupted!");
}               

线程“ pool-1-thread-2”中的异常60java.lang.NullPointerException

  at EchoServer$1.run(EchoServer.java:61) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec 

utor.java:886),位于java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor .java:908),位于java.lang.Thread.run(Thread.java:619)

我猜想ssc.accept返回的SocketChannel为null,这反过来意味着ServerSocketChannel处于非阻塞模式,并且没有挂起的连接。

ServerSocketChannel的Javadoc说:

If this channel is in non-blocking mode then this method will immediately 
return null if there are no pending connections. Otherwise it will block 
indefinitely until a new connection is available or an I/O error occurs.

您确定ssc.accept()并非仅出于该原因返回null吗?

正如@IainM和@QuantumMechanic所建议的那样,您无需检查'sc'是否为null。 如果NPE出现在sc.close()中,则“ sc”为null,我想说您有一个NPE调用sc.write(),而在finally {}块中又有一个NPE调用sc.close()。

您也没有检查write()的结果,因此您可能正在编写部分消息,或者根本什么也没写。 您还对sc.isOpen()进行了完全没有意义的测试。 在此代码中为null或打开,没有其他可能性。

而且我不知道当它不读取任何输入时如何将其称为回显服务器。

这不是使用NIO的方法。 整个想法是,您不需要额外的线程。 您的整个设计存在严重问题。

您还可以通过打印“ Interrupted!”来对自己说谎。 任何异常,并通过不打印其消息或堆栈跟踪来隐藏实际异常。 这也不是使用异常的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM