簡體   English   中英

Java套接字選擇器不會切換到寫入狀態

[英]Java Socket selector doesnt switch to write state

我們已經實現了基於選擇器的解決方案

喜歡

    @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. 沒有“從讀取狀態切換到寫入狀態”這樣的事情。 一個套接字可以同時可讀可寫,並且Selector不會“切換”:它僅報告套接字上存在哪些狀態。

  2. 如果寫事件從未觸發,那是因為套接字發送緩沖區已滿,這表明對等方未從連接中讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM