Reputation: 3204
I've been following this tutorial, it's quite helpful and most things are making sense.
If you look on page 34 you'll see this snippet of code:
} else if ((key.readyOps() & SelectionKey.OP_READ)
== SelectionKey.OP_READ) {
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
// ...
}
What exactly is going on here, the single ampersand means both conditions are checked, 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
. 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
. You can see that on page 33.
Then the next test in the sequence == SelectionKey.OP_READ
what's happening here?
In my head I see that evaluating like this:
if(true == SelectionKey.OP_READ)
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? I don't think that's right either because the second part is redundant.
The above works fine, I'm just not clear on what's actually going on with the if
test.
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.
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? So I do something like this:
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
}
So is the above an acceptable thing to do?
the javadoc says the following about 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.
Upvotes: 0
Views: 1121
Reputation: 310884
the single ampersand means both conditions are checked
It means the bitwise AND of the two operands is computed. As one of the operands has only a single bit set, only one condition is being checked: OP_READ.
so, in this case key.readyOps() will return a number whose bits represent the operations that are available to work on.
Of course, but the &
modifies that.
SelectionKey.OP_READ is another int. So I understand how these two relate.
What follows doesn't justify your confidence about that.
So the first test (key.readyOps() & SelectionKey.OP_READ) in my head this will return true or false.
Wrong again. It will return zero or SelectionKey.OP_READ
. You need to brush up the rules of Java arithmetic.
true if key.readyOps() == SelectionKey.OP_READ is that correct?
No.
or is it if key.readyOps() contains the correct bits set for OP_READ.
See above.
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?
It is testing first for OP_ACCEPT
and then for OP_READ.
In my head I see that evaluating like this:
No. See above. You are confused. What you have posted doesn't make sense.
if(true == SelectionKey.OP_READ)
true
can't be equal to an integer.
or
if(false == SelectionKey.OP_READ)
Ditto.
But that can't be right can it? since OP_READ is an int?
Correct. So you can't think it.
Or will an int be true for anything except 0?
No. You need to brush up the rules of Java arithmetic.
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.
No, to get the SocketChannel
from the SelectionKey
.
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?
You need to test the result returned by the read()
method.
So I do something like this:
if(read == -1){
// The connection has been terminated, handle that.
}else if(read == 0){
// Check data is complete
No. If the data was already complete you should already know that, and you wouldn't have called read()
again.
// if so switch to OP_WRITE
No. OP_WRITE
is used when a write()
has returned zero. No other time.
}else{
// Read bytes into the buffer
No. The bytes are already in the buffer.
So is the above an acceptable thing to do?
It doesn't begin to make sense. You need to take another good look at the IBM tutorial you cited. The misconceptions you've posted here don't appear there.
Upvotes: 1