Java Nio
1 | Java NIO Tutorial |
2 | Java NIO Overview |
3 | Java NIO Channel |
4 | Java NIO Buffer |
5 | Java NIO Scatter / Gather |
6 | Java NIO Channel to Channel Transfers |
7 | Java NIO Selector |
8 | Java NIO FileChannel |
9 | Java NIO SocketChannel |
10 | Java NIO ServerSocketChannel |
11 | Java NIO DatagramChannel |
12 | Java NIO Pipe |
13 | Java NIO vs. IO |
A Java NIO SocketChannel is a channel that is connected to a TCP network socket. It is Java NIO's equivalent of Java Networking's Sockets. There are two ways a SocketChannel
can be created:
SocketChannel
and connect to a server somewhere on the internet.SocketChannel
can be created when an incoming connection arrives at a ServerSocketChannel
.Here is how you open a SocketChannel
:
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
You close a SocketChannel
after use by calling the SocketChannel.close()
method. Here is how that is done:
socketChannel.close();
To read data from a SocketChannel
you call one of the read()
methods. Here is an example:
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
First a Buffer
is allocated. The data read from the SocketChannel
is read into the Buffer
.
Second the SocketChannel.read()
method is called. This method reads data from the SocketChannel
into theBuffer
. The int
returned by the read()
method tells how many bytes were witten into the Buffer
. If -1 is returned, the end-of-stream is reached (the connection is closed).
Writing data to a SocketChannel
is done using the SocketChannel.write()
method, which takes a Buffer
as parameter. Here is an example:
String newData = "New String to write to file..." + System.currentTimeMillis(); ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes()); buf.flip(); while(buf.hasRemaining()) { channel.write(buf); }
Notice how the SocketChannel.write()
method is called inside a while-loop. There is no guarantee of how many bytes the write()
method writes to the SocketChannel
. Therefore we repeat the write()
call until the Buffer
has no further bytes to write.
You can set a SocketChannel
into non-blocking mode. When you do so, you can call connect()
, read()
andwrite()
in asynchronous mode.
If the SocketChannel
is in non-blocking mode, and you call connect()
, the method may return before a connection is established. To determine whether the connection is established, you can call the finishConnect()
method, like this:
socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); while(! socketChannel.finishConnect() ){ //wait, or do something else... }
In non-blocking mode the write()
method may return without having written anything. Therefore you need to call thewrite()
method in a loop. But, since this is already being done in the previous write examples, no need to do anything differently here.
In non-blocking mode the read()
method may return without having read any data at all. Therefore you need to pay attention to the returned int
, which tells how many bytes were read.
The non-blocking mode of SocketChannel
's works much better with Selector
's. By registering one or moreSocketChannel
's with a Selector
, you can ask the Selector
for channels that are ready for reading, writing etc. How to use Selector
's with SocketChannel
's is explained in more detail in a later text in this tutorial.