Java NIO SocketChannel

Java NIO SocketChannel是连接到TCP Socket的Channel,它等效于Java Networking Socket。有两种创建SocketChannel的方法:

打开一个SocketChannel并连接到服务。 

当传入的连接到达ServerSocketChannel时,创建SocketChannel。


1.打开一个SocketChannel

这是打开SocketChannel的方法:

SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));


2.关闭一个SocketChannel

通过调用SocketChannel.close()方法关闭SocketChannel。

socketChannel.close(); 


3.从SocketChannel读

要从SocketChannel读取数据,请调用read()方法:

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = socketChannel.read(buf);


首先分配一个Buffer,从SocketChannel读取数据到Buffer。

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


4.写到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没有要写入的字节为止。


5.非阻塞模式

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


connect()

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

socketChannel.configureBlocking(false);

socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));



while(!socketChannel.finishConnect() ){

    //wait, or do something else...    

}


write()

在非阻塞模式下,write()方法可能会在未写入任何内容的情况下返回。因此,需要循环调用write()方法。与前面的示例中基本相同。


read()

在非阻塞模式下,read()方法可以不读取任何数据返回。因此,需要注意返回的int,该int告知已读取了多少个字节。


Selector的非阻塞模式

SocketChannel的非阻塞模式与Selector一起使用更好。通过向Selector注册一个或多个SocketChannel,可以向选择器询问Channel是否准备好进行读取,写入等操作。


 

展开阅读全文