0

I have a implementation of DatagramSocket in android which are attempting to receive data from an STA device set up as a Server. I have two ports one which is a command port and the second which streams data in. The command port runs on TCP Protocol and works fine, whereas the UDP port does not receive the data in for some reason. I can send the TCP port a start transmission command and the UDP port starts outputting data, observed from a computer running an emulator, but the Datagram Socket does not receive the data. I have tried this on a physical device also still no luck. I also know this is working as I have a python implementation of UDP running with the same device that works fine.

My implementation overview:

  • TCP and UDP are running on different different threads (using coroutines).

  • Permissions I am using include:

    uses-permission android:name = "android.permission.INTERNET"
    uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE"
    
  • max UDP packet size 200bytes

  • Android Code Snippets (Not working)

    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 Code Snippets (Working run from a computer)

    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()
    
  • Tried using address' 0.0.0.0 and 10.0.0.100 on the android UDP socket.

Any pointers as to why this is not working on Android would be great!

958
  • 178
  • 1
  • 9

1 Answers1

1

You are not setting the receive port on your device

val datagramSocketStream: DatagramSocket? = DatagramSocket(PORT)

This in itself is not a problem but it means that you are relying on receiving broadcast messages. You might have two issues tripping you up. The emulator might be changing your expected IP or your phone might not be accepting broadcast messages. See this link : Datagram (UDP) receiver not working - not receiving broadcast packets

Assay
  • 96
  • 7
  • Thanks for this apologies for the delay. Code has since been updated, I actually had an issue server side but had probably been tweaking the datagram socket input at the time (frantically changing variables). Ended up with: `private val datagramSocketStream = DatagramSocket(Constants.STREAM_PORT)` So will upvote you for this one. – 958 Aug 13 '21 at 07:56