Java Reference
In-Depth Information
ready for writing. Both of these are I/O operations, and both can throw
IOException
s
for a variety of reasons, so you'll want to wrap this all in a
try
block:
try
{
if
(
key
.
isAcceptable
())
{
ServerSocketChannel
server
=
(
ServerSocketChannel
)
key
.
channel
();
SocketChannel
connection
=
server
.
accept
();
connection
.
configureBlocking
(
false
);
connection
.
register
(
selector
,
SelectionKey
.
OP_WRITE
);
// set up the buffer for the client...
}
else
if
(
key
.
isWritable
())
{
SocketChannel
client
=
(
SocketChannel
)
key
.
channel
();
// write data to client...
}
}
Writing the data onto the channel is easy. Retrieve the key's attachment, cast it to
Byte
Buffer
, and call
hasRemaining()
to check whether there's any unwritten data left in the
buffer. If there is, write it. Otherwise, refill the buffer with the next line of data from the
rotation
array and write that.
ByteBuffer
buffer
=
(
ByteBuffer
)
key
.
attachment
();
if
(!
buffer
.
hasRemaining
())
{
// Refill the buffer with the next line
// Figure out where the last line started
buffer
.
rewind
();
int
first
=
buffer
.
get
();
// Increment to the next character
buffer
.
rewind
();
int
position
=
first
-
' '
+
1
;
buffer
.
put
(
rotation
,
position
,
72
);
buffer
.
put
((
byte
)
'\r'
);
buffer
.
put
((
byte
)
'\n'
);
buffer
.
flip
();
}
client
.
write
(
buffer
);
The algorithm that figures out where to grab the next line of data relies on the characters
being stored in the
rotation
array in ASCII order.
buffer.get()
reads the first byte of
data from the buffer. From this number you subtract the space character (32) because
that's the first character in the
rotation
array. This tells you which index in the array
the buffer currently starts at. You add 1 to find the start of the next line and refill the
buffer.
In the chargen protocol, the server never closes the connection. It waits for the client
to break the socket. When this happens, an exception will be thrown. Cancel the key
and close the corresponding channel:
catch
(
IOException
ex
)
{
key
.
cancel
();
try
{