简体   繁体   中英

Java NIO FileChannel - Empty reads from Android TUN network interface

Context: I've recently started using java.nio for my project which leverages Android's VpnService . In my implementation, I've wrapped the FileDescriptor that is returned by the establish() method of the VpnService into a java.nio.FileChannel as shown below.

private val outboundNetworkChannel = FileInputStream(fd).channel

After that, I've a kotlin coroutine which reads from the FileChannel indefinitely and processes the outbound IPv4 / IPv6 packets.

Issue: The below mentioned snippet works, but I see a lot of empty reads happening from the FileChannel which in turn spins the while loop unnecessarily.

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
    }

What I'm looking for: For a fact, I know that FileChannel is a blocking channel and in this case since the channel is backed by a.network interface, it might not have packets ready to be read. Is there a better approach with / without FileChannel which would lead to a more efficient implementation without wasting precious CPU cycles? I'm open to new ideas as well:)

I managed to figure this out after digging through the Android Docs for VpnService . By default, when a VPN connection is established using VpnService.Builder the fd is in non-blocking mode. Starting API level 21, one can setBlocking(true) .

As stated in the docs for public VpnService.Builder setBlocking (boolean blocking)

Sets the VPN interface's file descriptor to be in blocking/non-blocking mode. By default, the file descriptor returned by establish() is non-blocking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM