Java Reference
In-Depth Information
The processing of data from an existing connection involves making use of the
ByteBuffer object created earlier. Buffer method clear (the purpose of which is
self-evident) should be called before each fresh reading of data into the buffer
from its associated channel. A reference to the channel is obtained by calling
method channel on the current SelectionKey and again typecasting the Object
reference that is returned. The reading itself is carried out by method read of the
SocketChannel class. This method takes the buffer as its single argument and
returns an integer that indicates the number of bytes read. The lines to obtain the
SocketChannel reference, clear the ByteBuffer and read data from the channel into
the buffer are as follows:
socketChannel = (SocketChannel)key.channel();
buffer.clear();
int numBytes = socketChannel.read(buffer);
In order to write the data from the buffer to the channel, it is necessary to call
Buffer method fl i p to reset the buffer pointer to the start of the buffer and then call
method write on the channel object, supplying the buffer as the single argument. In
the example at the end of this section (which will contain all the code accumulated
within the section), the data received will simply be echoed back to the client. Since
it may not be possible to send the entire contents of the buffer in one operation, a
while loop will be used, with Buffer method remaining being called to determine
whether there are any bytes still to be sent. Since an IOException may be generated,
this code will need to be contained within a try block, but the basic code (without
the try ) is shown below.
buffer.fl ip();
while (buffer.remaining()>0)
socketChannel.write(buffer);
Note that whereas, with the multithreading approach, we had separate streams
for input and output, the SocketChannel is a two-way conduit and provides all the
I/O requirements between server and client. Note also that reading and writing is
specifi ed with respect to the channel . It can be very easy at fi rst viewing to interpret
socketChannel.read(buffer) as being 'read from buffer' and sock-
etChannel.write(buffer) as being 'write to buffer', whereas this is pre-
cisely the opposite of what is actually happening.
The link between client and server can break down, of course, possibly because
the connection has been closed at the client end or possibly because of some error
situation. Whatever the reason, this must be taken into account when attempting to
read from the SocketChannel . If a breakdown occurs, then the call to method read
will return −1. When this happens, the registration of the current SelectionKey with
the Selector object must be rescinded. This is done by calling method cancel on the
SelectionKey object. The socket associated with the client should also be closed.
Before this can be done, it is necessary to get a reference to the Socket object by
calling method socket on the SocketChannel object. The (attempted) closure of the
socket may fail and needs to be executed within a try block, but the example
Search WWH ::




Custom Search