Java SocketChannel tutorial with examples
A selectable channel for stream-oriented connecting sockets.
Introduction
A selectable channel for stream-oriented connecting sockets.
A socket channel is created by invoking one of the (#open open) methods of this class.
It is not possible to create a channel for an arbitrary, pre-existing socket.
A newly-created socket channel is open but not yet connected.
An attempt to invoke an I/O operation upon an unconnected channel will cause a NotYetConnectedException to be thrown.
A socket channel can be connected by invoking its (#connect connect) method; once connected, a socket channel remains connected until it is closed.
Whether or not a socket channel is connected may be determined by invoking its (#isConnected isConnected) method.
Socket channels support non-blocking connection: A socket channel may be created and the process of establishing the link to the remote socket may be initiated via the (#connect connect) method for later completion by the (#finishConnect finishConnect) method.
Whether or not a connection operation is in progress may be determined by invoking the (#isConnectionPending isConnectionPending) method.
Socket channels support asynchronous shutdown, which is similar to the asynchronous close operation specified in the Channel class.
If the input side of a socket is shut down by one thread while another thread is blocked in a read operation on the socket’s channel, then the read operation in the blocked thread will complete without reading any bytes and will return -1.
If the output side of a socket is shut down by one thread while another thread is blocked in a write operation on the socket’s channel, then the blocked thread will receive an AsynchronousCloseException.
Socket options are configured using the *#setOption(SocketOption,Object) setOption* method.
Socket channels support the following options:
Option Name | Description |
---|---|
(java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF) | The size of the socket send buffer |
(java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF) | The size of the socket receive buffer |
(java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE) | Keep connection alive |
(java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR) | Re-use address |
(java.net.StandardSocketOptions#SO_LINGER SO_LINGER) | Linger on close if data is present (when configured in blocking mode only) |
(java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY) | Disable the Nagle algorithm |
Additional (implementation specific) options may also be supported.
Socket channels are safe for use by multiple concurrent threads.
They support concurrent reading and writing, though at most one thread may be reading and at most one thread may be writing at any given time.
The (#connect connect) and (#finishConnect finishConnect) methods are mutually synchronized against each other, and an attempt to initiate a read or write operation while an invocation of one of these methods is in progress will block until that invocation is complete.
Example
The following code shows how to use SocketChannel from java.nio.channels.
import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class Main < public static void main(String[] argv) throws Exception < SocketChannel sChannel = SocketChannel.open(); sChannel.configureBlocking(false); sChannel.connect(new InetSocketAddress("hostName", 12345)); ByteBuffer buf = ByteBuffer.allocateDirect(1024); buf.put((byte) 0xFF); buf.flip(); int numBytesWritten = sChannel.write(buf); > >
import java.nio.CharBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; public class Main < public static void main(String[] args) throws Exception < CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder(); ServerSocketChannel server = ServerSocketChannel.open(); server.socket().bind(new java.net.InetSocketAddress(8000)); for (;;) < // This server runs forever SocketChannel client = server.accept(); String response = new java.util.Date().toString() + "\r\n"; client.write(encoder.encode(CharBuffer.wrap(response))); client.close();// w w w . d e m o 2 s . co m > > >
import java.nio.CharBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; public class Main < public static void main(String[] args) throws Exception < CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder(); ServerSocketChannel server = ServerSocketChannel.open(); server.socket().bind(new java.net.InetSocketAddress(8000)); for (;;) < // This server runs forever SocketChannel client = server.accept(); String response = new java.util.Date().toString() + "\r\n"; client.write(encoder.encode(CharBuffer.wrap(response))); client.close();// w ww . d e mo 2 s . c o m > > >
Related
- Java SocketChannel interrupt a socket channel
- Java Channel getRemoteHost(Channel channel)
- Java Channel Returns the IP address of the remote host for a socket channel.
- Java SocketChannel tutorial with examples
- Java SocketChannel write(ByteBuffer src)
- Java SocketChannel write(ByteBuffer[] srcs)
- Java SocketChannel close()
demo2s.com | Email: | Demo Source and Support. All rights reserved.
Java NIO SocketChannel
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:
- You open a SocketChannel and connect to a server somewhere on the internet.
- A SocketChannel can be created when an incoming connection arrives at a ServerSocketChannel .
Opening a SocketChannel
Here is how you open a SocketChannel :
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
Closing a SocketChannel
You close a SocketChannel after use by calling the SocketChannel.close() method. Here is how that is done:
Reading from a SocketChannel
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 the Buffer . 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 to a SocketChannel
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.
Non-blocking Mode
You can set a SocketChannel into non-blocking mode. When you do so, you can call connect() , read() and write() in asynchronous mode.
connect()
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. >
write()
In non-blocking mode the write() method may return without having written anything. Therefore you need to call the write() method in a loop. But, since this is already being done in the previous write examples, no need to do anything differently here.
read()
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.
Non-blocking Mode with Selectors
The non-blocking mode of SocketChannel ‘s works much better with Selector ‘s. By registering one or more SocketChannel ‘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.