Java Reference
In-Depth Information
When implementing a client that takes advantage of the new I/O APIs, begin by invoking
the static factory method SocketChannel.open() to create a new java.nio.chan
nels.SocketChannel object. The argument to this method is a java.net.SocketAd
dress object indicating the host and port to connect to. For example, this fragment
connects the channel to rama.poly.edu on port 19:
SocketAddress rama = new InetSocketAddress ( "rama.poly.edu" , 19 );
SocketChannel client = SocketChannel . open ( rama );
The channel is opened in blocking mode, so the next line of code won't execute until
the connection is established. If the connection can't be established, an IOException is
thrown.
If this were a traditional client, you'd now ask for the socket's input and/or output
streams. However, it's not. With a channel you write directly to the channel itself. Rather
than writing byte arrays, you write ByteBuffer objects. You've got a pretty good idea
that the lines of text are 74 ASCII characters long (72 printable characters followed by
a carriage return/linefeed pair) so you'll create a ByteBuffer that has a 74-byte capacity
using the static allocate() method:
ByteBuffer buffer = ByteBuffer . allocate ( 74 );
Pass this ByteBuffer object to the channel's read() method. The channel fills this buffer
with the data it reads from the socket. It returns the number of bytes it successfully read
and stored in the buffer:
int bytesRead = client . read ( buffer );
By default, this will read at least one byte or return -1 to indicate the end of the data,
exactly as an InputStream does. It will often read more bytes if more bytes are available
to be read. Shortly you'll see how to put this client in nonblocking mode where it will
return 0 immediately if no bytes are available, but for the moment this code blocks just
like an InputStream . As you could probably guess, this method can also throw an
IOException if anything goes wrong with the read.
Assuming there is some data in the buffer—that is, n > 0—this data can be copied to
System.out . There are ways to extract a byte array from a ByteBuffer that can then be
written on a traditional OutputStream such as System.out . However, it's more infor‐
mative to stick with a pure, channel-based solution. Such a solution requires wrapping
the OutputStream System.out in a channel using the Channels utility class, specifically,
its newChannel() method:
WritableByteChannel output = Channels . newChannel ( System . out );
You can then write the data that was read onto this output channel connected to
System.out . However, before you do that, you have to flip the buffer so that the output
channel starts from the beginning of the data that was read rather than the end:
Search WWH ::




Custom Search