Search code examples
javasocketchannel

Using 1 SocketChannel for 2-way "real-time communictation"


I'm receiving a continuous stream of data that I'm saving to a ByteBuffer. Sometimes I need to write to the channel, however, it's important not to lose any data. Is it possible to use the selector to solve this issue?

If I'm constantly checking the selector for the channel state, it always says that the channel is currently reading and it's like there is no opportunity to perform writing. I can't use multiple connections because the server doesn't support it.

        this.socketChannel = SocketChannel.open();
        this.socketChannel.configureBlocking(false);

        this.socketChannel.connect(new InetSocketAddress(IP, this.port));


   try {
        this.selector = Selector.open();
        int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
        SelectionKey selectionKey = this.socketChannel.register(selector, interestSet);

        while (selector.select() > -1) {

            // Wait for an event one of the registered channels

            // Iterate over the set of keys for which events are available
            Iterator selectedKeys = selector.selectedKeys().iterator();
            while (selectedKeys.hasNext()) {
                SelectionKey key = (SelectionKey) selectedKeys.next();
                selectedKeys.remove();
                try {
                    if (!key.isValid()) {
                        continue;
                    } else if (key.isReadable()) {
                        System.out.println("readable");

                    } else if (key.isWritable()) {
                        System.out.println("writable");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

Edit: Sorry I didn't add more info. This is an important bit of my code. It always prints "readable" to the console and I was hoping that isWritable block also gets executed.

Thanks in advance, Honza


Solution

  • You are using else if operator so if your key is readable checking for if it is writeable will not be performed, but it doesn't mean that the channel is not writeable.

    Actually it could be readable and writeable in the same time. But in your program if it is readable you just don't check for writeable.

    replace else-if with if and see the result.