NIO选择器OP_READ和OP_WRITE,有关处理它们的一些问题

时间:2015-02-10 08:42:01

标签: java bit-manipulation nio

我一直关注this tutorial,这非常有帮助,大多数事情都有意义。

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

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

这里到底发生了什么,单个&符号表示两个条件都被检查,因此,在这种情况下,key.readyOps()将返回一个数字,其位代表可用的操作。 SelectionKey.OP_READ是另一个int。所以我理解这两者是如何相关的 因此,我头脑中的第一个测试(key.readyOps() & SelectionKey.OP_READ)会返回truefalse。如果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是一个i​​nt?或者除了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

  

读操作的操作设置位。假设有一个选择键   兴趣集在选择操作开始时包含OP_READ。   如果选择器检测到相应的通道已准备就绪   阅读,已经到达终点,已被远程关闭   进一步阅读,或有待处理的错误,然后它将添加OP_READ   密钥的就绪操作集并将密钥添加到其选定密钥集。

1 个答案:

答案 0 :(得分:1)

  

单个&符号表示检查两个条件

这意味着计算两个操作数的按位AND。由于其中一个操作数只有一个位集,因此只检查一个条件:OP_READ.

  

因此,在这种情况下,key.readyOps()将返回一个数字,其位代表可以使用的操作。

当然,&会修改。

  

SelectionKey.OP_READ是另一个int。所以我理解这两者是如何相关的。

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

  

所以我头脑中的第一个测试(key.readyOps()& SelectionKey.OP_READ)会返回true或false。

再次错了。它将返回零或SelectionKey.OP_READ。你需要刷新Java算法的规则。

  

如果key.readyOps()== SelectionKey.OP_READ是正确的,则为true吗?

没有

  

或者是否key.readyOps()包含为OP_READ设置的正确位。

见上文。

  

该特定if语句的开头包含相同的测试,但是使用OP_ACCEPT而不是OP_READ ...然后序列中的下一个测试== SelectionKey.OP_READ这里发生了什么?

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

  

在我脑海中,我看到像这样评估:

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

  

if(true == SelectionKey.OP_READ)

true不能等于整数。

  

     

if(false == SelectionKey.OP_READ)

同上。

  

但那可能是对的吗?因为OP_READ是一个i​​nt?

正确。所以你无法想到它。

  

或者对于0以外的任何内容,int是否为真?

没有。你需要刷新Java算法的规则。

  

接下来,一旦上述评估结果为真,我就会对处理阅读感到疑惑。

     

首先我调用SocketChannel sc =(SocketChannel)key.channel();掌握渠道。

不,从SocketChannel获取SelectionKey

  

然后我准备好我的缓冲区并使用

从套接字读取
    int bytesRead = sc.read(myBuffer);
  

现在我需要测试读取的内容,对吗?

您需要测试read()方法返回的结果。

  

所以我这样做:

    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 

没有。 OP_WRITE返回零时使用write()。没有其他时间。

}else{
    // Read bytes into the buffer

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

  

以上是可接受的事情吗?

它没有意义。您需要另外好好看看您引用的IBM教程。你在这里发布的误解不会出现在那里。