Android UDP不接收数据
Posted
技术标签:
【中文标题】Android UDP不接收数据【英文标题】:Android UDP not receiving data 【发布时间】: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 的指针都会很棒!
【问题讨论】:
【参考方案1】:您没有在设备上设置接收端口
val datagramSocketStream: DatagramSocket? = DatagramSocket(PORT)
这本身不是问题,但这意味着您依赖于接收广播消息。你可能有两个问题让你绊倒。模拟器可能正在更改您的预期 IP,或者您的手机可能不接受广播消息。 见此链接:Datagram (UDP) receiver not working - not receiving broadcast packets
【讨论】:
感谢您的延误。此后代码已更新,实际上我在服务器端遇到了问题,但当时可能一直在调整数据报套接字输入(疯狂地更改变量)。最后是:private val datagramSocketStream = DatagramSocket(Constants.STREAM_PORT)
所以会为你投票。以上是关于Android UDP不接收数据的主要内容,如果未能解决你的问题,请参考以下文章