0

コンテキスト:最近java.nio、Android のVpnService. 私の実装では、以下に示すように、 のメソッドFileDescriptorによって返される を にラップしました。establish()VpnServicejava.nio.FileChannel

private val outboundNetworkChannel = FileInputStream(fd).channel

FileChannelその後、無期限に読み取り、送信 IPv4 / IPv6 パケットを処理する kotlin コルーチンを作成しました。

問題:以下のスニペットは機能しますが、 から多くの空の読み取りが発生し、ループが不必要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 サイクルを無駄にすることなく、より効率的な実装につながるより良いアプローチがありますか? 私も新しいアイデアを受け入れています:)

4

1 に答える 1

0

Android Docs for を掘り下げた後、なんとかこれを理解することができましたVpnService。デフォルトでは、 を使用して VPN 接続が確立されるVpnService.Builderfd、ノンブロッキング モードになります。API レベル 21 から、次のことができsetBlocking(true)ます。

ドキュメントに記載されているようにpublic VpnService.Builder setBlocking (boolean blocking)

VPN インターフェースのファイル記述子をブロッキング/非ブロッキング モードに設定します。デフォルトでは、 Establish() によって返されるファイル記述子はノンブロッキングです。

于 2020-05-22T13:13:59.133 に答える