📜  Java NIO 包中的 ServerSocketChannel

📅  最后修改于: 2022-05-13 01:55:03.480000             🧑  作者: Mango

Java NIO 包中的 ServerSocketChannel

Java NIO ServerSocketChannel是一个可以侦听传入 TCP 连接的通道,就像标准Java网络中的 ServerSocket。 ServerSocketChannel 类位于Java.nio.channels 包中。

java.lang.Object
    java.nio.channels.spi.AbstractInterruptibleChannel
        java.nio.channels.SelectableChannel
            java.nio.channels.spi.AbstractSelectableChannel
                java.nio.channels.ServerSocketChannel

所有实现的接口:

Closeable, AutoCloseable, Channel, InterruptibleChannel, NetworkChannel
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
implements NetworkChannel

构造函数

  • protected ServerSocketChannel(SelectorProvider provider):初始化此类的新实例。

Socket通道的重要方法

  • bind(SocketAddress local) -此方法用于将套接字通道绑定到作为此方法的参数提供的本地地址。
  • accept() -此方法用于接受与此通道的套接字建立的连接。
  • connect(SocketAddress remote) -此方法用于将套接字连接到远程地址。
  • finishConnect() -此方法用于完成连接套接字通道的过程。
  • getRemoteAddress() -此方法返回通道套接字连接到的远程位置的地址。
  • isConnected() -如前所述,此方法返回套接字通道的连接状态,即它是否已连接。
  • open() - Open 方法用于打开没有指定地址的套接字通道。这种便捷方法的工作方式类似于调用 open() 方法,在生成的服务器套接字通道上调用 connect 方法,远程传递它,然后返回该通道。
  • read(ByteBuffer dst) -此方法用于通过套接字通道从给定缓冲区读取数据。
  • setOption(SocketOption name, T value) -此方法设置套接字选项的值。
  • socket() -此方法检索与此通道关联的服务器套接字。
  • validOps() -此方法返回标识此通道支持的操作的操作集。服务器套接字通道仅支持接受新连接,因此此方法返回 SelectionKey.OP_ACCEPT。

面向流的侦听套接字的可选通道。

服务器套接字通道是通过调用此类的 open 方法创建的。不可能为任意的、预先存在的 ServerSocket 创建通道。新创建的服务器套接字通道已打开但尚未绑定。尝试调用未绑定的服务器套接字通道的 accept 方法将导致抛出 NotYetBoundException。可以通过调用此类定义的绑定方法之一来绑定服务器套接字通道。



套接字选项是使用 setOption 方法配置的。服务器套接字通道支持以下选项:

Option Name         Description
SO_RCVBUF             The size of the socket receive buffer
SO_REUSEADDR        Re-use address

还可以支持其他(特定于实现的)选项。

服务器套接字通道可供多个并发线程安全使用。

下面是一个例子:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));

while(true) {
   SocketChannel socketChannel = serverSocketChannel.accept();

   // Body
   // Do something with socketChannel...
}

A.打开一个 ServerSocketChannel

您可以通过调用 ServerSocketChannel.open() 方法打开 ServerSocketChannel。

句法:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

B.关闭一个 ServerSocketChannel

关闭 ServerSocketChannel 是通过调用 ServerSocketChannel.close() 方法完成的。



句法:

serverSocketChannel.close();

C.监听传入连接

侦听传入连接是通过调用 ServerSocketChannel.accept() 方法完成的。当 accept() 方法返回时,它返回一个带有传入连接的 SocketChannel。因此,accept() 方法会阻塞,直到传入连接到达。

由于您通常对仅侦听单个连接不感兴趣,因此您可以在 while 循环中调用 accept()。这是它的外观:

句法:

while(true) {
   SocketChannel socketChannel = serverSocketChannel.accept();
   // Do something with socketChannel...
}

当然,您会在 while 循环中使用除 true 之外的其他停止标准。

D.非阻塞模式

ServerSocketChannel 可以设置为非阻塞模式。在非阻塞模式下,accept() 方法立即返回,因此如果没有传入连接到达,则可能返回 null。因此,您必须检查返回的 SocketChannel 是否为空。

插图:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);

while(true) 
{
   SocketChannel socketChannel = serverSocketChannel.accept();

   if(socketChannel != null)
   {
       // Do something with socketChannel...
   }
}