Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8164471
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T19:19:25+00:00 2026-06-06T19:19:25+00:00

I’d like to use the NIO to send/receive data to/from a distant machine. I

  • 0

I’d like to use the NIO to send/receive data to/from a distant machine. I can send or receive data at any time, when i need to send data i just send it without any queries from the distant machine, and the distant machine send me data at regular interval. I don’t understand the NIO mechanism. What generates and read or write event on the Selector SelectionKey ? Is it possible to use only one ServerSocketChannel on my side, to read data from the distant machine et to write data to it ? That is what i understand but i don’t see how the writing event can be triggered… Thank you for your explanation.

I already did some coding and i can read data coming in from the distant machine, but cannot write. I use Selector and i don’t know how can i write data. The logged message “handle write” is never written, but in wireshark i can see my packet.

    public class ServerSelector {

    private static final Logger logger = Logger.getLogger(ServerSelector.class.getName());
    private static final int TIMEOUT = 3000; // Wait timeout (milliseconds)
    private static final int MAXTRIES = 3;
    private final Selector selector;

    public ServerSelector(Controller controller, int... servPorts) throws IOException {
        if (servPorts.length <= 0) {
            throw new IllegalArgumentException("Parameter(s) : <Port>...");
        }
        Handler consolehHandler = new ConsoleHandler();
        consolehHandler.setLevel(Level.INFO);
        logger.addHandler(consolehHandler);

        // Create a selector to multiplex listening sockets and connections
        selector = Selector.open();

        // Create listening socket channel for each port and register selector
        for (int servPort : servPorts) {
            ServerSocketChannel listnChannel = ServerSocketChannel.open();
            listnChannel.socket().bind(new InetSocketAddress(servPort));

            listnChannel.configureBlocking(false); // must be nonblocking to register
            // Register selector with channel.  The returned key is ignored
            listnChannel.register(selector, SelectionKey.OP_ACCEPT);
        }

        // Create a handler that will implement the protocol
        IOProtocol protocol = new IOProtocol();

        int tries = 0;
        // Run forever, processing available I/O operations
        while (tries < MAXTRIES) {
            // Wait for some channel to be ready (or timeout)
            if (selector.select(TIMEOUT) == 0) { // returns # of ready chans
                System.out.println(".");
                tries += 1;
                continue;
            }

            // Get iterator on set of keys with I/O to process
            Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
            while (keyIter.hasNext()) {
                SelectionKey key = keyIter.next(); // Key is a bit mask
                // Server socket channel has pending connection requests?
                if (key.isAcceptable()) {
                    logger.log(Level.INFO, "handle accept");
                    protocol.handleAccept(key, controller);
                }

                // Client socket channel has pending data?
                if (key.isReadable()) {
                    logger.log(Level.INFO, "handle read");
                    protocol.handleRead(key);
                }

                // Client socket channel is available for writing and
                // key is valid (i.e., channel not closed) ?
                if (key.isValid() && key.isWritable()) {
                    logger.log(Level.INFO, "handle write");
                    protocol.handleWrite(key);
                }
                keyIter.remove(); // remove from set of selected keys
                tries = 0;
            }
        }
    }
}

The protocol

    public class IOProtocol implements Protocol {

    private static final Logger logger = Logger.getLogger(IOProtocol.class.getName());

    IOProtocol() {
        Handler consolehHandler = new ConsoleHandler();
        consolehHandler.setLevel(Level.INFO);
        logger.addHandler(consolehHandler);
    }

    /**
     *
     * @param key
     * @throws IOException
     */
    @Override
    public void handleAccept(SelectionKey key, Controller controller) throws IOException {
        SocketChannel clntChan = ((ServerSocketChannel) key.channel()).accept();
        clntChan.configureBlocking(false); // Must be nonblocking to register
        controller.setCommChannel(clntChan);
        // Register the selector with new channel for read and attach byte buffer
        SelectionKey socketKey = clntChan.register(key.selector(), SelectionKey.OP_READ | SelectionKey.OP_WRITE, controller);
    }

    /**
     * Client socket channel has pending data
     *
     * @param key
     * @throws IOException
     */
    @Override
    public void handleRead(SelectionKey key) throws IOException {
        Controller ctrller = (Controller)key.attachment();
        try {
            ctrller.readData();
        } catch (CommandUnknownException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
        key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    }

    /**
     * Channel is available for writing, and key is valid (i.e., client channel
     * not closed).
     *
     * @param key
     * @throws IOException
     */
    @Override
    public void handleWrite(SelectionKey key) throws IOException {

        Controller ctrl = (Controller)key.attachment();
        ctrl.writePendingData();
        if (!buf.hasRemaining()) { // Buffer completely written ?
            // Nothing left, so no longer interested in writes
            key.interestOps(SelectionKey.OP_READ);
        }
    buf.compact();
    }
}

The controller

    /**
     * Fill buffer with data.
     * @param msg The data to be sent
     * @throws IOException 
     */
    private void writeData(AbstractMsg msg) throws IOException {
//        
        writeBuffer = ByteBuffer.allocate(msg.getSize() + 4);
        writeBuffer.putInt(msg.getSize());
        msg.writeHeader(writeBuffer);
        msg.writeData(writeBuffer);
        logger.log(Level.INFO, "Write data - message size : {0}", new Object[]{msg.getSize()});
        logger.log(Level.INFO, "Write data - message : {0}", new Object[]{msg});
    }

    /**
     * Write to the SocketChannel
     * @throws IOException 
     */
    public void writePendingData() throws IOException {
        commChannel.write(writeBuffer);
    }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T19:19:26+00:00Added an answer on June 6, 2026 at 7:19 pm

    ServerSocketChannel is used to make a connection, but not send data. You need one ServerSocketChannel and one SocketChannel per each connection.

    Examples of reading and writing using SocketChannel:

    ByteBuffer buf = ByteBuffer.allocate(48);
    int bytesRead = socketChannel.read(buf);
    

    Your program will sleep at second line until data will come. You need to put this code in infinite loop and run it in background Thread. When data came you can process it from this thread, then wait for another data to come.

    ByteBuffer buf = ByteBuffer.allocate(48);
    buf.clear();
    buf.put("Hello!".getBytes());
    
    buf.flip();
    
    while(buf.hasRemaining()) {
        channel.write(buf);
    }
    

    There is no blocking methods, so if you sending small byte buffer you can call this from your main Thread.

    Source

    ADD:
    Don’t set OP_WRITE key on new connection. Only OP_READ. When you want to write some data you need to notify selector that you want to send something and send it in events loop. Good solution is to make a Queue of outcoming messages. Then follow this steps:

    • adding data to Queue
    • setting OP_WRITE to channel’s key
    • in while (keyIter.hasNext()) loop you’ll have writable key, write all data from queue and remove OP_WRITE key.

    It’s hard for me to understand your code, but I think you’ll find out what’s the problem. Also if you want to have only one connection there is no need to use Selector. And this is weird that you binding few ServerSocketChannels.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
Does anyone know how can I replace this 2 symbol below from the string
I have some data like this: 1 2 3 4 5 9 2 6
I would like to count the length of a string with PHP. The string
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I am trying to understand how to use SyndicationItem to display feed which is
I have a jquery bug and I've been looking for hours now, I can't
I've got a string that has curly quotes in it. I'd like to replace

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.