当前位置: 代码迷 >> 综合 >> 【译】Java NIO SocketChannel
  详细解决方案

【译】Java NIO SocketChannel

热度:88   发布时间:2024-01-24 19:47:42.0

Java NIO的SocketChannel是一个用来连接TCP网络的channel。有两种方式创建:

  1. open一个SocketChannel并连接到internet上的某个服务器。
  2. 当有一个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

  相关解决方案