为了从服务器接收 UDP 广播数据包到 Android 设备,我使用了一个服务类并在线程中侦听数据包。成功接收数据包。问题是,如果服务器同时发送多个数据包,则会导致数据包丢失。
我什至尝试使用队列并在单独的线程中处理接收到的数据包,然后我也没有收到数据包。我对网络编程完全陌生,任何帮助将不胜感激
void startListenForUdpBroadcast() {
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
InetAddress broadcastIP = InetAddress.getByName(UdpConstants.IP_ADDRESS);
Integer port = UdpConstants.RECEIVER_PORT;
while (shouldRestartSocketListen) {
listenAndWaitAndThrowIntent(broadcastIP, port);
}
} catch (Exception e) {
Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
}
}
});
UDPBroadcastThread.setPriority(Thread.MAX_PRIORITY); //Setting The Listener thread to MAX PRIORITY to minimize packet loss.
UDPBroadcastThread.start();
}
此代码侦听新数据包并将其推送到队列
private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
byte[] recvBuf = new byte[64000];
if (socket == null || socket.isClosed()) {
socket = new DatagramSocket(port, broadcastIP);
socket.setBroadcast(true);
}
//socket.setSoTimeout(1000);
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
messQueue.add(packet);
}
这会检查队列中是否有新消息并对其进行处理
/**
* @purpose Checking queue and If anything is added to the queue then broadcast it to UI
*/
private void checkQueue() {
queueThread = new Thread(new Runnable() {
public void run() {
try {
while (shouldRestartSocketListen) {
if (!messQueue.isEmpty()) {
broadcastIntent(messQueue.poll());
}
}
} catch (Exception e) {
}
}
});
queueThread.start();
}
UDP 的问题是你的发送者(你的服务器)不知道你(你的 Android 设备)错过了一些。它不会丢失,因为您无法足够快地读取它,有时只是通过空中干扰/拥塞或繁忙的套接字。
接收者只会知道:
- 由于缺少数据,因此在处理数据时出现错误
- 或者您的 UDP 数据包在其标头中按顺序编号,并且您检测到丢失的数字(例如 1,2,4 - 丢失 3)
一旦数据包丢失,它就丢失了。你有两个选择:
- 实现重发请求:在检测到丢失的数据包后,接收方需要通知发送方重新发送该丢失的数据包,直到收到它为止,并且您的数据包处理可能会停止,直到收到为止
- 或者能够忽略它,“嘿,我们可以在没有他的情况下做到这一点”,并填充空白数据(例如,位图会有一些空白像素,就像损坏的图像)
- 降低发送速度,这样数据包就不会堵塞和丢失
- 您的包裹越小,它们存活的可能性就越大
(选项 1:所有这些重发请求只是伪 TCP,因此您可能会考虑放弃 UDP 并转而使用 TCP)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)