【问题标题】:Android UDP not receiving dataAndroid UDP不接收数据
【发布时间】:2021-02-25 13:08:08
【问题描述】:

我在 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, self.socket)
          print(sys.stderr, '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 的指针都会很棒!

【问题讨论】:

    标签: android udp android-wifi datagram


    【解决方案1】:

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

    val datagramSocketStream: DatagramSocket? = DatagramSocket(PORT)
    

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

    【讨论】:

    • 感谢您的延误。此后代码已更新,实际上我在服务器端遇到了问题,但当时可能一直在调整数据报套接字输入(疯狂地更改变量)。最后是:private val datagramSocketStream = DatagramSocket(Constants.STREAM_PORT) 所以会为你投票。
    猜你喜欢
    • 1970-01-01
    • 2013-01-20
    • 2015-07-13
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    相关资源
    最近更新 更多