java - 为什么我应该在写入数据之前检查 channel isWritable()

标签 java nio

我在服务器端使用ServerSocket channel (NIO)。我的问题是,如果在向客户端写入数据之前不检查套接字 channel 是否可写,会发生什么情况?我使用服务器程序进行了测试,该程序运行良好,无需检查 channel 是否准备就绪。

public class SelectorExample {  
    public static void main (String [] args)
            throws IOException {
    // Get selector
    Selector selector = Selector.open();

    System.out.println("Selector open: " + selector.isOpen());

    // Get server socket channel and register with selector
    ServerSocketChannel serverSocket = ServerSocketChannel.open();
    //serverSocket.setOption(StandardSocketOptions.SO_REUSEADDR, true);
    InetSocketAddress hostAddress = new InetSocketAddress("localhost", 5454);
    serverSocket.socket().bind(hostAddress,0);
    serverSocket.configureBlocking(false);
    int ops = serverSocket.validOps();
    SelectionKey selectKy = serverSocket.register(selector, ops, null);

    for (;;) {

       System.out.println("Waiting for select...");

        int noOfKeys = selector.select();         

        Set selectedKeys = selector.selectedKeys();
        Iterator iter = selectedKeys.iterator();

        while (iter.hasNext()) {

            SelectionKey ky = (SelectionKey)iter.next();

                ++count;
            if (ky.isAcceptable()) {
                // Accept the new client connection
                SocketChannel client = serverSocket.accept();
                client.configureBlocking(false);

                // Add the new connection to the selector
              client.register(selector, SelectionKey.OP_READ);

               System.out.println("["+new java.sql.Timestamp(System.currentTimeMillis())+"]"+"Accepted new connection from client: " + client);

            }
            else if (ky.isReadable()) {                 
                // Read the data from client

                SocketChannel client = (SocketChannel) ky.channel();
                ByteBuffer buffer = ByteBuffer.allocate(2048);
                int i =client.read(buffer);
                String output = new String(buffer.array());                 
                    System.out.println("Message read from client: " + output);
                output =output.trim();
                output=output+"\r\n";                

                //*********write message here******
                byte[] a=output.getBytes();
                ByteBuffer bb=ByteBuffer.wrap(a);
                 client.write(bb);                   

                  buffer.clear();
                 System.out.println("   Sent    Message ");
                if (i == -1) {                  
                    client.close();
                   System.out.println("Client messages are complete; close.");
                }

            } // end if (ky...)
            //countkey++;
            iter.remove();                  
        } // end while loop

    } // end for loop
}

}

最佳答案

Why should I check channel isWritable() before write?

没有任何内容表明您应该这样做。

what would happen if I don't check if the socketchannel is writable or not before writing data to client?

您可能会得到零长度写入。您可能会收到一篇简短的文章。

一般来说,只要有东西要写,就应该只写,并且只有在写入为零或短的情况下才使用 OP_WRITE 。任何认为 isWritable() 之前无法写入的想法都是错误的。

关于java - 为什么我应该在写入数据之前检查 channel isWritable(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43861477/

相关文章:

java - 启动时的 Tomcats 警告消息

java - 如何让JVM默认使用给定的源IP?

java - Canvas : Double Buffering

Java NIO : How to know when SocketChannel read() is complete with non-blocking I/O

java - JDK中 `sun`开头的包源在哪里获取?

java - C++ 客户端连接到非阻塞 Java NIO 服务器

java - ErrorHandler 用于在一个地方解决多个异常?

java - 如何在 JavaFX 中设置 -fx-graphic 大小?

java - 原始数据吞吐量上的非阻塞 io 与阻塞 io

java - 我应该从 SelectedSet 中删除 SelectionKey 吗?