📜  Java NIO-套接字通道(1)

📅  最后修改于: 2023-12-03 14:42:15.455000             🧑  作者: Mango

Java NIO - 套接字通道

Java NIO(New IO,非阻塞IO)是Java 1.4以后引入的一组IO新API。相比传统的Java IO,Java NIO提供了更快的IO操作和更好的可扩展性,特别是在处理大量的并发连接时。

在Java NIO中,套接字通道(SocketChannel)是一个非阻塞的、双向的通道,用于网络传输数据。SocketChannel实现了java.nio.Channel接口,并提供了以下功能:

  • 连接到服务器
  • 读取数据
  • 写入数据
  • 关闭通道
创建套接字通道

通过open()方法创建套接字通道:

SocketChannel socketChannel = SocketChannel.open();
连接到服务器

使用connect()方法连接到服务器:

socketChannel.connect(new InetSocketAddress("example.com", 80));
读取数据

使用read()方法从套接字通道读取数据:

ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
写入数据

使用write()方法向套接字通道写入数据:

ByteBuffer buffer = ByteBuffer.wrap("Hello, World".getBytes());
int bytesWritten = socketChannel.write(buffer);
关闭通道

使用close()方法关闭套接字通道:

socketChannel.close();
非阻塞模式

套接字通道默认是阻塞模式,可以通过configureBlocking()方法设置为非阻塞模式:

socketChannel.configureBlocking(false);

在非阻塞模式下,从套接字通道读取数据时可能会返回0,这意味着当前没有可用的数据。因此,在非阻塞模式下,需要不断轮询套接字通道是否有数据可供读取或者是否准备好写入。对于轮询操作,可以使用Java NIO提供的选择器(Selector)。

Selector

选择器(Selector)是Java NIO中的一个对象,用于监视多个套接字通道的IO状态。使用选择器可以轮询多个套接字通道,判断每个通道的IO状态是否有变化,根据变化的状态读取或写入数据。

使用open()方法创建选择器:

Selector selector = Selector.open();

将套接字通道注册到选择器中:

SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ);

在上面的代码中,SelectionKey.OP_READ表示监视套接字通道是否有数据可读取。可以同时监视多个事件,例如读取、写入、连接等。

接下来,可以使用select()方法轮询选择器中注册的所有通道,并检查每个通道是否有状态变化:

selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();

    if(key.isReadable()) {
        // 处理读事件
    } else if (key.isWritable()) {
        // 处理写事件
    }
    keyIterator.remove();
}
总结

套接字通道是Java NIO提供的一种高性能IO操作方式,可以实现非阻塞、双向的IO操作。将套接字通道和选择器一起使用,可以实现高并发的网络编程,有效提升应用程序的性能。