Java NIO的SocketChannel是一个用来连接TCP网络的channel。有两种方式创建:
- open一个SocketChannel并连接到internet上的某个服务器。
- 当有一个ServerSocketChannel连接来了,就创建一个SocketChannel。
open一个SocketChannel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
关闭一个SocketChannel
调用close方法就可以关闭:
socketChannel.close();
从SocketChannel中读数据
通过调用read方法:
ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = socketChannel.read(buf);
首先分配一个buffer空间,然后把buffer当作参数传入socketChannel的read方法。返回的int值表明读取了多少长度的字节。如果是-1则表示已经读完或者连接已经关闭。
向SocketChannel中写数据
调用write方法即可,需要一个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);
}
注意SocketChannel的write方法是在while循环中调用的,write()方法不能保证向SocketChannel写入多少字节。因此,我们重复write()调用,直到缓冲区没有需要写入的字节为止。
非阻塞模式
这种类型的channel可以设置成非阻塞模式。设置之后,就可以在异步的模式下调用connect、read、write等函数了。
connect()
在非阻塞模式下调用connect方法,可能会在建立连接之前就返回了。判断是否建立连接的依据就是调用finishConnect()方法,类似这样:
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));while(! socketChannel.finishConnect() ){//wait, or do something else...
}
write()
在非阻塞模式下调用write方法,可能在还没写任何数据的时候就返回了。因此你需要在一个while循环中调用write()。这和上面的写数据的例子类似。
read()
在非阻塞模式下调用read方法,可能在还没任何数据的情况下就返回了。因此你需要注意返回的int型的值,它表明了这次返回了多少长度的数据。
非阻塞模式下使用Selector
非阻塞模式下SocketChannel的Selector工作的更好。把一个Selector注册到多个SocketChannel中,你可以调用Selector来查看哪些channel已经准备好了。后面会介绍如果在SocketChannel中使用Selector。
下一篇:【译】Java NIO ServerSocketChannel