非阻塞套接字在读取时不会挂起

时间:2014-07-29 16:29:12

标签: java sockets nio nonblocking

我有以下代码。你可以在下面看到它的输出。我认为javadoc socket.read应该永远不会挂起或者其他什么,这是一个意想不到的行为。

    Context con = new Context();
    con.buf = ByteBuffer.allocate(1024);
    log.trace("reading.. {}, {}, {}, {}, {}", socket.isConnected(), !socket.isBlocking(), socket.isOpen(), socket.keyFor(selector).isReadable(), socket.keyFor(selector).isValid());

    FutureTask<Integer> readTask = new FutureTask<Integer>(

            new Callable<Integer>() {

                Context con;

                Callable<Integer> setContext(Context con) {
                    this.con = con;
                    return this;
                }

                public Integer call() throws Exception{
                    int rd = socket.read(con.buf);
                    return Integer.valueOf(rd);
                }

            }.setContext(con)
    );

    ExecutorService exec = Executors.newSingleThreadExecutor();
    exec.submit(readTask);

    int read = 0;
    try {
        read = readTask.get(5, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        log.error("hello java");
        System.exit(0);
    }

(我根本不需要那里的未来任务,但这只是为了检查我对socket.read方法的坚持的假设。

此处是日志输出(请注意!socket.isBlocking()已反转,因此它显示处于非阻止模式):

reading.. true, true, true, true, true
hello java 

这意味着5秒后我们什么都没有,套接字仍然打开,没有任何错误。

请帮我解决这个问题。它可能是socket&#34; keepalive&#34;或OS或java或防火墙(我仍然只在localhost上读写)?

这就是我得到这个套接字的方式:

SocketChannel socket = ((ServerSocketChannel) key.channel()).accept();
log.trace("accepted:{}", socket.getRemoteAddress());
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);

0 个答案:

没有答案