Android NIO 系列教程(六) -- SocketChannel

本文深入探讨Android NIO中的SocketChannel,一种用于TCP网络连接的非阻塞通道。介绍了SocketChannel的创建、读写操作及非阻塞模式的设置,展示了如何与ServerSocketChannel配合工作,以及如何使用Selector进行高效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android NIO 系列教程(一) NIO概述
Android NIO 系列教程(二) – Channel
Android NIO 系列教程(三) – Buffer
Android NIO 系列教程(四) – Selector
Android NIO 系列教程(五) – FileChannel
Android NIO 系列教程(六) – SocketChannel
Android NIO 系列教程(七) – ServerSocketChannel
Android NIO 系列教程(八) --NIO简易聊天室

这一章,我们来学习 SocketChannel。

SocketChannel 用于 Tcp 网络连接的通道,类似于非阻塞的 Socket,它可以通过以下两种方式创建:

  1. 通过 SocketChannel 的open()方法,并 connect 网络上的服务器
  2. 当 ServerSocketChannel 连接到一个请求,也会创建 SocketChannel。

创建 SocketChannel

通过 open() 方法创建:

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,然后通过 read() 方法,把数据从 SocketChannel 读到buffer;它的返回值表示能读取到多少个字节数,如果返回 -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);
}

注意写数据这里,用到了 while循环,因为我们不确定有多少字节会被写入。

非阻塞模式

我们可以把 SocketChannel 设置为非阻塞模式,这样当我们在调用 connect(), read() and write() 方法时,都是异步的。
如果我们设置了非阻塞模式,当我们调用 connect 方法,它可能在连接建立前就会返回,所以,我们可以使用 finishConnect() 方法判断是否完成:

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

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

write() 方法

当你设置为非阻塞模式,write() 方法调用并返回时,不一定表示你的数据已经成功写入,因此我们需要把 write() 放到 循环方法内:

while(buf.hasRemaining()) {
    channel.write(buf);
}

read() 方法

当你设置为非阻塞模式,read() 方法调用并返回时,不一定数据已经读取到数据了,所以需要判断返回值的大小,它会告诉你实际读取了多少数据。

非阻塞模式和 Selector

SocketChannel 的非组设模式可以很好配合 selector ,当向 selector 注册一个或多个 SocketChannel 时,你可以通过 selector 判断哪些 channel 是可读可写的。关于这些,我们后面介绍。

下一章,我们学习 ServerSocketChannel。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值