Java NIO SocketChannel

时间:2020-01-09 10:36:16  来源:igfitidea点击:

Java NIO SocketChannel是连接到TCP网络套接字的通道。它与Java NIO等效于Java Networking的套接字。有两种方法可以创建" SocketChannel":

  • 我们打开一个" SocketChannel"并连接到互联网上某个服务器。
  • 当传入的连接到达" ServerSocketChannel"时,可以创建" SocketChannel"。

打开一个SocketChannel

这是打开" SocketChannel"的方法:

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://Hyman.com", 80));

关闭一个SocketChannel

使用完后,我们可以通过调用SocketChannel.close()方法关闭SocketChannel。这是完成的方式:

socketChannel.close();

从SocketChannel读取

要从" SocketChannel"读取数据,请调用" read()"方法之一。这是一个例子:

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = socketChannel.read(buf);

首先分配一个"缓冲区"。从" SocketChannel"读取的数据被读入" Buffer"。

其次调用SocketChannel.read()方法。该方法将数据从" SocketChannel"读取到" Buffer"中。 read()方法返回的int告诉将多少字节传送到Buffer中。如果返回-1,则到达流的末尾(连接已关闭)。

写入SocketChannel

使用" SocketChannel.write()"方法将数据写入" SocketChannel"中,该方法将" Buffer"作为参数。这是一个例子:

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);
}

注意在while循环中如何调用SocketChannel.write()方法。无法保证write()方法将多少字节写入SocketChannel中。因此,我们重复执行write()调用,直到Buffer没有更多字节可写为止。

非阻塞模式

我们可以将" SocketChannel"设置为非阻塞模式。这样做时,我们可以在异步模式下调用connect(),read()和write()。

连接()

如果" SocketChannel"处于非阻塞模式,并且我们调用" connect()",则该方法可能会在建立连接之前返回。要确定是否建立连接,可以调用finishConnect()方法,如下所示:

socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://Hyman.com", 80));

while(! socketChannel.finishConnect() ){
    //wait, or do something else...    
}

write()

在非阻塞模式下,write()方法可能会在未写入任何内容的情况下返回。因此,我们需要循环调用write()方法。但是,由于在前面的编写示例中已经完成了此操作,因此此处无需做任何其他操作。

read()

在非阻塞模式下," read()"方法可能会返回而根本不读取任何数据。因此,我们需要注意返回的" int",它告诉我们读取了多少字节。

带选择器的非阻塞模式

SocketChannel的非阻塞模式与Selector的更好。通过向一个"选择器"注册一个或者多个" SocketChannel",我们可以向"选择器"询问准备好读取,写入等的通道。解释了如何将"选择器"与" SocketChannel"一起使用在本教程的后面的文章中会更详细地介绍。