无法在 Android 上使用 Ktor 原始套接字接收 UDP 数据报

问题描述 投票:0回答:1

我正在尝试使用 Ktor 和协程接收 UDP 数据报。我创建了一个简单的 android kotlin 应用程序,并设法使用阻塞 java.nio.DatagramChannel 接收数据报,但不使用 Ktor 的套接字。类似的暂停方法也适用于桌面 Kotlin 应用程序。该应用程序在 Android Studio 模拟器(API 30 设备)和 Android 11 手机上进行了测试。

安卓应用程序

添加到AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

添加到 build.gradle 中的依赖项:

    implementation 'io.ktor:ktor-network:2.2.4'

MainViewModel.kt:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.ktor.network.selector.*
import io.ktor.network.sockets.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.nio.ByteBuffer
import java.nio.channels.DatagramChannel
import java.util.concurrent.Executors

class MainViewModel: ViewModel() {
    private val receiverService = Executors.newSingleThreadExecutor()
    private var messageChannel = DatagramChannel.open()
    private val selector = SelectorManager(Dispatchers.IO)
    private val portBlocking = 15100
    private val portSuspend = 15101

    init {
        addCloseable(selector)
        addCloseable(messageChannel)

        receiveBlocking()
        receiveSuspend()
    }

    private fun receiveBlocking() {
        val bindAddress = java.net.InetSocketAddress(portBlocking)
        messageChannel.bind(bindAddress)
        println("--- Blocking receive at ${messageChannel.localAddress} UDP ---")
        receiverService.submit {
            val buf = ByteBuffer.allocate(1000)
            messageChannel.receive(buf)
            println("--- Received blocking $buf ---")
        }
    }

    private fun receiveSuspend() = viewModelScope.launch {
        val localAddress = InetSocketAddress("127.0.0.1", portSuspend)
        val inSocket = aSocket(selector).udp().bind(localAddress) { reuseAddress = true }
        println("--- Suspend receive at ${inSocket.localAddress} UDP ---")
        val datagram = inSocket.receive()
        println("--- Received suspend ${datagram.packet.readText()} ---")
    }
}

工作桌面应用程序

import io.ktor.network.selector.*
import io.ktor.network.sockets.*
import kotlinx.coroutines.*

const val port = 9000

fun main(args: Array<String>) = runBlocking {
    val selectorManager = SelectorManager(Dispatchers.IO)

    receiveSuspend(selectorManager)
}

private suspend fun receiveSuspend(selector: SelectorManager) {
    val localAddress = InetSocketAddress("127.0.0.1", port)
    val inSocket = aSocket(selector).udp().bind(localAddress) { reuseAddress = true }
    println("--- Suspend receive at ${inSocket.localAddress} UDP ---")
    val datagram = inSocket.receive()
    println("--- Received ${datagram.packet.readText()} ---")
}
android kotlin udp ktor
1个回答
0
投票

我遇到了同样的问题。您实际上需要指定发送者的IP地址。如果您不知道,您可以简单地使用“0.0.0.0”(广播接收)。

val inSocket = aSocket(selector).udp().bind(InetSocketAddress("0.0.0.0", port))

参见如何绑定正确的地址和端口进行UDP通信?.

© www.soinside.com 2019 - 2024. All rights reserved.