gpt4 book ai didi

java - 在 JAVA nio 选择器中,我应该什么时候注册 'write operation' ?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:12:12 26 4
gpt4 key购买 nike

我正在学习 Java nio 选择器。在我的理解中,我认为使用选择器的步骤是首先注册我感兴趣的操作,然后我可以检查就绪集,最后我可以执行与我感兴趣的操作相对应的操作。我不知道为什么在这段代码中,写入过程可以发生在 if (key.isReadable()){...} 而不是 if (key.isWritable){ ...} 为什么没有注册写操作?

Iterator keys = sel.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = (SelectionKey)keys.next();

if (!key.isValid())
continue;

if (key.isAcceptable()) {
// increase the counter
connection++;

// remove accept request
keys.remove();

// ACCEPT: get the server channel
ServerSocketChannel ssc =
(ServerSocketChannel) key.channel();

// init a socket for a client
SocketChannel nsc = ssc.accept();
nsc.configureBlocking(false);

// register the socket for READ
nsc.register(sel, SelectionKey.OP_READ);
}
}


while (count < COUNT_MAX + NUM_CHILD - 1) {
sel.select();

// Get all pending events and iterate
Iterator keys = sel.selectedKeys().iterator();
while ( keys.hasNext() ) {
SelectionKey key = (SelectionKey)keys.next();
keys.remove();

if (!key.isValid())
continue;

if (key.isReadable()) {
// READ: get the channel
SocketChannel nsc = (SocketChannel) key.channel();

// clear buffer for reading
readBuffer.clear();
int nBytes = nsc.read(readBuffer);
if (nBytes == -1) {// Check if the client closed the socket
key.channel().close();
key.cancel();
continue;
}

// Read a message
DataInputStream ist = new DataInputStream (
new ByteArrayInputStream(readBuffer.array()));
String msg = ist.readUTF();
System.out.print(msg + "\n");

// Clear the write buffer
writeBuffer.clear();

// Write the counter value on the buffer
count++;
if (count < COUNT_MAX)
writeBuffer.putInt(count);
else
writeBuffer.putInt(-1);
// flip the buffer and write on the channel
writeBuffer.flip();
// Reply to a client
nsc.write(writeBuffer);
}
} // while (key)

最佳答案

您不需要注册对 OP_WRITE 的兴趣,因为通常 channel 已准备好写入。然而一个WritableChannel ,如果处于非阻塞模式,可能无法成功写入给定 ByteBuffer 的所有内容。在其 java 文档中查看此处:

Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer.

在这种情况下,您需要在选择器上注册对OP_WRITE 的兴趣,以便在 channel 再次准备好写入时收到通知,这样您就可以完成写入您的ByteBuffer.

在这里查看相关的SO question .

关于java - 在 JAVA nio 选择器中,我应该什么时候注册 'write operation' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26201320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com