我一直在关注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)
将返回true
或false
。如果key.readyOps() == SelectionKey.OP_READ
是正确的,则为true?还是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?还是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
说了以下内容:读操作的操作设置位。假设选择键的
兴趣集在选择操作开始时包含OP_READ。
如果选择器检测到相应的频道已准备就绪
阅读,已到达流的末尾,已被远程关闭
进一步阅读,或者有待处理的错误,那么它将OP_READ添加到
键的就绪操作集,并将该键添加到其选择键集中。
最佳答案
单个“&”号表示同时检查了两个条件
这意味着将计算两个操作数的按位与。由于其中一个操作数只设置了一个位,因此仅检查一种情况: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.
在我的脑海中,我看到这样评估:
否。请参见上文。你很困惑。您发布的内容没有任何意义。
如果(true == SelectionKey.OP_READ)true
不能等于整数。
要么
if(false == SelectionKey.OP_READ)
同上。
但这不对吗?因为OP_READ是一个int?
正确。所以你想不到。
还是int对于除0以外的其他任何东西都是正确的?
不。您需要重新整理Java算术规则。
因此,接下来,我想知道一旦上述评估结果为true,就应该处理阅读。
首先我调用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教程进行另一个很好的了解。您在此处发布的误解不会在此处出现。