问题描述
我在 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