ServerSocketChannel作为服务端的SocketChannel,用来接收入站连接。

创建ServerSocketChannel

与SocketChannel类似,ServerSocketChannel也提供了静态的open方法,不过它的open方法只有一个不带参数的:

  1. public static ServerSocketChannel open() throws IOException {
  2. return SelectorProvider.provider().openServerSocketChannel();
  3. }

这样只是创建了一个ServerSocketChannel对象,并没有实现连接。我们需要绑定一个SocketAddress来完成连接。

绑定SocketAddress

ServerSocketChannel的bind方法可以将该channel连接到一个本地地址:

  1. public final ServerSocketChannel bind(SocketAddress local)
  2. throws IOException
  3. {
  4. return bind(local, 0);
  5. }

它接收的是一个SocketAddress。例如:

  1. public static void main(String[] args) throws IOException {
  2. ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
  3. SocketAddress socketAddress = new InetSocketAddress(80);
  4. serverSocketChannel.bind(socketAddress);
  5. }

这样进行了绑定之后,这个通道就能监听连接了。

通过accept方法建立连接

调用ServerSocketChannel的accept方法就能接收入站连接,这个方法会返回一个SocketChannel,我们能对这个SocketChannel进行读写:

  1. public static void main(String[] args) throws IOException {
  2. ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
  3. SocketAddress socketAddress = new InetSocketAddress(80);
  4. serverSocketChannel.bind(socketAddress);
  5. SocketChannel socketChannel = serverSocketChannel.accept();
  6. }

在默认的阻塞模式下,accept方法会阻塞直到有入站连接,这段时间线程不能进行其他操作,这种模式适合立即响应每个服务的简单服务器。

设置为非阻塞模式

我们可以调用serverSocketChannel.configureBlocking(false); 来将这个服务端Channel设置为非阻塞模式。当设置成非阻塞模式后,accept方法在没有连接入站的情况下会返回null。非阻塞模式适合并行处理多个连接并且为每个连接完成大量服务的服务器。非阻塞模式一般与Selector配合使用。