Android UDP 未接收数据

问题描述

我在 android 中有一个 DatagramSocket 实现,它试图从设置为服务器的 STA 设备接收数据。我有两个端口,一个是命令端口,第二个是传输数据。命令端口在 TCP 协议上运行并且工作正常,而 UDP 端口由于某种原因没有接收数据。从运行模拟器的计算机上观察,我可以向 TCP 端口发送开始传输命令,UDP 端口开始输出数据,但是数据报套接字没有接收到数据。我已经在物理设备上尝试过这个,但仍然没有运气。我也知道这是有效的,因为我有一个使用相同设备运行的 UDP 的 python 实现,运行正常。

我的实现概述:

  • TCP 和 UDP 运行在不同的线程上(使用协程)。

  • 我使用的权限包括

    uses-permission android:name = "android.permission.INTERNET"
    uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE"
    
  • 最大 UDP 数据包大小 200 字节

  • Android 代码片段(不工作)

    private val hostIP: String = "10.0.0.1"
    private val commandPort: Int = 6660
    private val streamPort: Int = 6670
    
    
    private fun sendTcpCommand(command: Int = 2) {
    
      GlobalScope.launch {
          try {
              val socketCommand = Socket(inetAddress,commandPort)
    
              if (socketCommand.isConnected) {
                  val clientCommandOutput = DataOutputStream(socketCommand.getoutputStream())
    
                  val oByteArray = byteArrayOf(command.toByte())
    
                  clientCommandOutput.write(oByteArray)
    
              } else {
                  Log.d(
                      TAG,"createIOConnections: socket is not connect?: ${socketCommand.isClosed}"
                  )
              }
              val inputStream = DataInputStream(socketCommand.getInputStream())
              val response = inputStream.readBytes()
              val responseMap = responseInterpreter(response,command)
              socketCommand.close()
    
          } catch (e: Exception) {
              e.printstacktrace()
          }
      }
    
      private fun openUdpPort() {
          GlobalScope.launch {
              try {
                  val datagramSocketStream: DatagramSocket? = DatagramSocket(null)
                  datagramSocketStream?.reuseAddress = true
                  datagramSocketStream?.broadcast = true
                  datagramSocketStream?.bind(InetSocketAddress(streamPort))
    
                  val bufferLen = 200
                  val bufferByteArray = ByteArray(bufferLen)
                  val datagramPacket = DatagramPacket(bufferByteArray,bufferByteArray.size)
    
                  datagramSocketStream?.receive(datagramPacket)
    
                  val noBytesRead = datagramPacket.length
                  interpretUdpData(datagramPacket.data)
    
              } catch (e: Exception) {
                  e.printstacktrace()
              }
          }
      }
    }
    
  • Python 代码片段(从计算机运行)

    CONTROL_SERVER_IP = "10.0.0.1"
    STREAM_SERVER_IP = "10.0.0.100"
    
    if self.socket == self.CONTROL_SOCK:
          try:
              self.sock = socket.socket(socket.AF_INET,socket.soCK_STREAM)
          except socket.error as e:
              print("Failed to create socket.")
              print(f'Error: {e}')
              sys.exit()
          print("Socket Created.")
    
    
    
          # Connect the socket to the port where the server is listening
          server_address = (self.server_ip,self.socket)
          print(sys.stderr,'connecting to %s port %s' % server_address)
          self.sock.settimeout(5)
          try:
              self.sock.connect(server_address)
              print("Port is open")
          except socket.timeout as e:
              print(
                  "Server connection Failed. Please check that the server is on and that the server and client are connected.")
              print(f'Error: {e}')
              sys.exit()
      else:
          try:
              self.sock = socket.socket(socket.AF_INET,socket.soCK_DGRAM)
          except socket.error as e:
              print("Failed to create socket.")
              print(f'Error: {e}')
              sys.exit()
          print("Socket Created.")
    
    
    
          # Connect the socket to the port where the server is listening
          server_address = (self.server_ip,'connecting to %s port %s' % server_address)
          self.sock.settimeout(5)
          try:
              self.sock.bind(server_address)
              print("Port is open")
          except socket.timeout as e:
              print(
                  "Server connection Failed. Please check that the server is on and that the server and client are connected.")
              print(f'Error: {e}')
              sys.exit()
      return self.sock
    
    
          print("Reading Meaurements.")
          self.thread_running = True
          measurements = Measurements()
          full_chunk = b''
          new_packet = True
          pointer = 0
          while self.thread_running:
              try:
                  msg,address = sock.recvfrom(200)
                  # msg = sock.recv(16)  # 16 byte buffer
              except socket.error as e:
                  print(f'Error: {e}')
                  break
                  self.disconnect()
                  self.terminate_thread()
                  sys.exit()
    
  • 尝试在 android UDP 套接字上使用地址'0.0.0.0 和 10.0.0.100。

关于为什么这不能在 Android 上运行的任何指示都会很棒!

解决方法

您没有在设备上设置接收端口

val datagramSocketStream: DatagramSocket? = DatagramSocket(PORT)

这本身不是问题,但这意味着您依赖于接收广播消息。你可能有两个问题让你失望。模拟器可能正在更改您的预期 IP,或者您的手机可能不接受广播消息。 请参阅此链接:Datagram (UDP) receiver not working - not receiving broadcast packets