NIO Selector OP_READ and OP_WRITE, 处理它们的一些问题

NIO Selector OP_READ and OP_WRITE, some questions about handling them

我一直在关注 this tutorial,它很有帮助,而且大多数事情都说得通。

如果您查看第 34 页,您会看到这段代码:

} else if ((key.readyOps() & SelectionKey.OP_READ)
== SelectionKey.OP_READ) {
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
// ...
}

这里到底发生了什么,单个&符号表示两个条件都被检查,因此,在这种情况下 key.readyOps() 将 return 一个数字,其位代表可用于处理的操作. SelectionKey.OP_READ 是另一个整数。所以我了解这两者之间的关系。
所以我脑海中的第一个测试 (key.readyOps() & SelectionKey.OP_READ) 这将是 return truefalse。 true 如果 key.readyOps() == SelectionKey.OP_READ 正确吗?或者如果 key.readyOps() 包含为 OP_READ 设置的正确位。该特定 if 语句的开头包含相同的测试,但使用 OP_ACCEPT 而不是 OP_READ。您可以在第 33 页看到这一点。

那么序列中的下一个测试 == SelectionKey.OP_READ 这里发生了什么?
在我的脑海里,我看到这样的评估:

if(true == SelectionKey.OP_READ)

if(false == SelectionKey.OP_READ)

但这不对吧?因为 OP_READ 是一个整数?或者 int 对除 0 以外的任何值都成立吗?我也不认为那是对的,因为第二部分是多余的。

以上工作正常,我只是不清楚 if 测试的实际情况。

所以接下来,我想知道一旦上面的计算结果为 true 时如何处理读取。

首先,我调用 SocketChannel sc = (SocketChannel) key.channel(); 获取频道句柄。

然后我准备好缓冲区并使用 int bytesRead = sc.read(myBuffer);

从套接字中读取

现在我需要测试读取的内容,对吗?所以我做了这样的事情:

if(read == -1){

  // The connection has been terminated, handle that. 

}else if(read == 0){

// Check data is complete, if so switch to OP_WRITE 

}else{

 // Read bytes into the buffer

}

那么以上是可以接受的事情吗?

javadoc 对 OP_READ 的描述如下:

Operation-set bit for read operations. Suppose that a selection key's interest set contains OP_READ at the start of a selection operation. If the selector detects that the corresponding channel is ready for reading, has reached end-of-stream, has been remotely shut down for further reading, or has an error pending, then it will add OP_READ to the key's ready-operation set and add the key to its selected-key set.

the single ampersand means both conditions are checked

表示计算两个操作数的按位与。由于其中一个操作数仅设置了一个位,因此仅检查一个条件:OP_READ.

so, in this case key.readyOps() will return a number whose bits represent the operations that are available to work on.

当然可以,但是 & 修改了它。

SelectionKey.OP_READ is another int. So I understand how these two relate.

以下内容并不能证明您对此有信心。

So the first test (key.readyOps() & SelectionKey.OP_READ) in my head this will return true or false.

又错了。它将 return 为零或 SelectionKey.OP_READ。 Java算术规则你要好好温习一下

true if key.readyOps() == SelectionKey.OP_READ is that correct?

没有

or is it if key.readyOps() contains the correct bits set for OP_READ.

见上文。

The start of that particular if statement contains the same test, but with OP_ACCEPT instead of OP_READ ... Then the next test in the sequence == SelectionKey.OP_READ what's happening here?

首先测试 OP_ACCEPT,然后测试 OP_READ.

In my head I see that evaluating like this:

没有。看上面。你很困惑。您发布的内容没有意义。

if(true == SelectionKey.OP_READ)

true 不能等于整数。

or

if(false == SelectionKey.OP_READ)

同上。

But that can't be right can it? since OP_READ is an int?

正确。所以你想不到。

Or will an int be true for anything except 0?

没有。 Java算术规则你要好好温习一下

So next, I'm wondering about handling reading once the above evaluates to true.

First I call SocketChannel sc = (SocketChannel) key.channel(); to get a handle on the channel.

否,要从 SelectionKey 中获取 SocketChannel

Then I ready my buffer and read from the socket with

    int bytesRead = sc.read(myBuffer);

Now I need to test what was read, correct?

您需要测试 return 由 read() 方法编辑的结果。

So I do something like this:

    if(read == -1){
        // The connection has been terminated, handle that. 
    }else if(read == 0){

    // Check data is complete

没有。如果数据已经完整,您应该已经知道了,您就不会再调用 read()

// if so switch to OP_WRITE 

没有。当 write() 的 return 为零时使用 OP_WRITE。没有其他时间了。

}else{
    // Read bytes into the buffer

没有。字节已经在缓冲区中。

So is the above an acceptable thing to do?

开始没有意义。您需要再仔细看看您引用的 IBM 教程。你在这里发布的误解不会出现在那里。