Java套接字选择器不会切换到写入状态

时间:2015-04-02 21:02:12

标签: java sockets tcp selector nio

我们已经基于选择器实现了解决方案

    @Override
public void run() {
    super.run();
    while (session.isConnectionAlive()) {
        try {
            // Wait for an event
            selector.select();
        } catch (IOException e) {
            log.error("Selector error: {}", e.toString());
            log.debug("Stacktrace: ", e);
            session.closeConnection();
            break;
        }
        handleSelectorkeys(selector.selectedKeys());
    }
    executorService.shutdown();
    log.debug("Ucp worker stopped");
}

private void handleSelectorkeys(Set<SelectionKey> selectedKeys) {
    Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
    while (keys.hasNext()) {
        SelectionKey selKey = keys.next();
        selector.selectedKeys().remove(selKey);
        try {
            processSelectionKey(selKey);
        } catch (IOException e) {
            // Handle error with channel and unregister
            selKey.cancel();
            log.error("Selector error: {}", e.toString());
            log.debug("Stacktrace: ", e);
        }
    }
}

public void processSelectionKey(SelectionKey selKey) throws IOException {

    // Since the ready operations are cumulative,
    // need to check readiness for each operation
    if (selKey.isValid() && selKey.isConnectable()) {
        log.debug("connectable");
        // Get channel with connection request
        SocketChannel sChannel = (SocketChannel) selKey.channel();

        boolean success = sChannel.finishConnect();
        if (!success) {
            // An error occurred; handle it
            log.error("Error on finish");
            // Unregister the channel with this selector
            selKey.cancel();
        }
    }

    if (selKey.isValid() && selKey.isReadable()) {
        readMessage(selKey);
    }

    if (selKey.isValid() && selKey.isWritable()) {
        writeMessage(selKey);
    }

    if (selKey.isValid() && selKey.isAcceptable()) {
    }

}

它工作正常,直到我们开始每秒发送大约100条消息并接收大约100条响应和100条收入消息并发送100条我们的响应(每种方式每条消息大约400条消息)由于未知而不时有这样的负载另一方面,我们的合作伙伴切断连接。我们重新建立连接但由于某种原因,选择器不会切换到只读取的写入状态。我们收到很多关于阅读的消息但不能发送任何内容 有任何想法吗?是否存在操作系统问题与我们的连接问题。选择器如何工作?通过某种逻辑或自发地从读到写切换?

1 个答案:

答案 0 :(得分:1)

  1. 没有'切换[从读取]到写入状态'。套接字可以同时读写,Selector不能“切换”:它只报告套接字上存在哪些状态。

  2. 如果写入事件永远不会触发,那是因为套接字发送缓冲区已满,这表明对等方没有从连接中读取。