【发布时间】:2020-09-02 03:40:02
【问题描述】:
上下文:我最近开始在我的项目中使用java.nio,该项目利用了Android 的VpnService。在我的实现中,我将VpnService 的establish() 方法返回的FileDescriptor 包装成java.nio.FileChannel,如下所示。
private val outboundNetworkChannel = FileInputStream(fd).channel
之后,我有一个 kotlin 协程,它无限期地从 FileChannel 读取并处理出站 IPv4 / IPv6 数据包。
问题:下面提到的 sn-p 有效,但我看到FileChannel 发生了很多空读取,这反过来又不必要地旋转了while 循环。
fun reader() = scope.launch(handler) {
while (isActive) {
val pkt = read()
if(pkt !== DUMMY){
// Send the read IPv4/IPv6 packet for processing
}
}
}
private suspend fun read(): IPDatagram =
withContext(Dispatchers.IO) {
val bytes = ByteBufferPool.acquire()
outboundChannel.read(bytes) // Returns a lot of empty reads with return value as 0
return@withContext marshal(bytes) // Read IPv4/IPv6 headers and wrap the packet
}
我在寻找什么:事实上,我知道FileChannel 是一个阻塞通道,在这种情况下,由于该通道由网络接口支持,它可能没有数据包准备好阅读。有没有更好的方法有/没有FileChannel,这将导致更有效的实施而不浪费宝贵的CPU周期?我也乐于接受新想法:)
【问题讨论】:
-
fd是如何进入非阻塞模式的? -
@user207421 好像是在非阻塞模式下默认从Android VpnService检索到的fd。
标签: java android kotlin nio android-vpn-service