Java NIO SocketChannel是一个连接到TCP网络套接字的通道,它等同于Java 网络套接字。有两种方式创建SocketChannel:
- 打开SocketChannel然后连接到互联网上的服务器。
- 一个新的连接到达ServerSocketChannel时,会创建一个SocketChannel
打开SocketChannel
下面是打开SocketChannel的例子:
SocketChannel socketChannel = SocketChannel.open();
socketCannel.connect(new InetSocketAddress("http://jenkov.com", 80));
关闭SocketChannel
调用SocketChannel.close()方法后,会关闭SocketChannel,例如:
socketChannel.close();
从SocketChannel中读
调用read()方法能从SocketChannel中读,例如:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = socketChannel.read(buf);
先分配一个Buffer,然后调用SocketChannel.read(),将SocketChannel中的数据读到Buffer中。read()方法返回的int表示写入了多少数据。如果返回-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()方法。
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——表示读了多少数据。
非阻塞模式与Selector
非阻塞模式和Selector配合使用更好。通过将一个或者多个SocketChannel注册到Selector,可以询问Selector哪些通道已经读,写等就绪了。后面详细介绍如何配合SocketChannel使用Selector。