简体   繁体   English

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

[英]Java Socket selector doesnt switch to write state

We have implemented solution based on selector 我们已经实现了基于选择器的解决方案

like 喜欢

    @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()) {
    }

}

It works fine till we start sending around 100 messages per sec and receive also around 100 response and 100 income messages and send 100 our responses (around 400 messages per sec in both ways) With such load from time to time due to unknown issue on other side our partner cut connection. 直到我们开始每秒发送大约100条消息并接收大约100条响应和100条收入消息并发送100条我们的响应(两种方式大约每秒400条消息)为止,它的工作情况一直很好,由于其他问题未知与我们的合作伙伴断开连接。 We reestablish connection but for some reason selector doesn't switch to write state only read. 我们重新建立连接,但由于某种原因选择器不会切换为仅读取状态。 We receive a lot messages on read but cannot send anything. 我们收到大量阅读后的消息,但无法发送任何内容。
Any ideas? 有任何想法吗? Is it OS issue issue on our side with connection. 是我们这方面的操作系统问题吗? How does selector works? 选择器如何工作? Switch from read to write by some logic or spontaneously? 是通过某种逻辑还是自发地从读取切换为写入?

  1. There is no such thing as 'switch [from read] to write state'. 没有“从读取状态切换到写入状态”这样的事情。 A socket can be readable and writable at the same time, and a Selector doesn't 'switch': it merely reports which states exist on the socket. 一个套接字可以同时可读可写,并且Selector不会“切换”:它仅报告套接字上存在哪些状态。

  2. If the write event never triggers, it is because the socket send buffer is full, which indicates that the peer isn't reading from the connection. 如果写事件从未触发,那是因为套接字发送缓冲区已满,这表明对等方未从连接中读取。

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

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