Android 设备接收 UDP 广播时丢包

2023-11-22

为了从服务器接收 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 设备)错过了一些。它不会丢失,因为您无法足够快地读取它,有时只是通过空中干扰/拥塞或繁忙的套接字。

接收者只会知道:

  1. 由于缺少数据,因此在处理数据时出现错误
  2. 或者您的 UDP 数据包在其标头中按顺序编号,并且您检测到丢失的数字(例如 1,2,4 - 丢失 3)

一旦数据包丢失,它就丢失了。你有两个选择:

  1. 实现重发请求:在检测到丢失的数据包后,接收方需要通知发送方重新发送该丢失的数据包,直到收到它为止,并且您的数据包处理可能会停止,直到收到为止
  2. 或者能够忽略它,“嘿,我们可以在没有他的情况下做到这一点”,并填充空白数据(例如,位图会有一些空白像素,就像损坏的图像)
  3. 降低发送速度,这样数据包就不会堵塞和丢失
  4. 您的包裹越小,它们存活的可能性就越大

(选项 1:所有这些重发请求只是伪 TCP,因此您可能会考虑放弃 UDP 并转而使用 TCP)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 设备接收 UDP 广播时丢包 的相关文章

随机推荐

  • Jetpack Compose Navigation - 将本地文件位置作为字符串传递

    我正在尝试传递音频文件位置 storage emulated 0 Android media 作为第一个屏幕中的字符串home screen到第二个屏幕detail screen 当我正常传递上面的字符串作为参数时 我收到此错误 java
  • Python 进程使用的总内存?

    Python 程序有没有办法确定它当前使用了多少内存 我看过关于单个对象的内存使用情况的讨论 但我需要的是该进程的总内存使用情况 以便我可以确定何时需要开始丢弃缓存数据 Here是一个有用的解决方案 适用于各种操作系统 包括 Linux W
  • fetch response.text() 返回待处理的承诺

    我使用 jsonplaceholder URL 测试 fetch API 但我的函数返回 Promise State Pending 我不明白为什么 function getUsers url return fetch url const
  • CSS:删除选择元素内的填充

    我试图从选择元素中删除填充 以便其中的文本与其正下方的输入元素中的文本对齐 除其他外 我还尝试过以下操作 select padding left 0 有任何想法吗 JS小提琴在这里http jsfiddle net pLSkH 2 去除te
  • 当应用程序在后台运行时,如何让我的 AVPlayer 播放?

    我已经完成了我的作业 一直在阅读这里的文档 谷歌搜索 stackoverflowing 但是当用户让应用程序进入后台时仍然无法让我的声音保持不变 到目前为止我所做的 将 UIBackgroundModes 音频添加到 plist 文件中 首
  • 如何搜索redis哈希中的关键模式?

    我有一个哈希表 其键的模式为 USER TEL 如下所示 bob 123456 Some address mary 567894 other address john 123456 third address 现在 我想获取密钥中具有相同电
  • 使用 atos 通过 dSYM 确定崩溃的方法名称

    我有一个来自用户的控制台堆栈 不是崩溃报告 我试图确定我的应用程序中的哪个方法调用是最后一个站着的人 我知道他们使用的是哪个版本的应用程序 并且我有该发布 调试版本的副本 以及存档副本的 dSYM 文件 但是 当我尝试使用atos吐出内存地
  • React Native 响应式字体大小

    我想问一下如何反应原生处理或做响应式字体 例如 在 iphone 4s 中 我的 fontSize 14 而在 iphone 6 中 我的 fontSize 18 您可以使用像素比 例如 var React require react na
  • SELECT * INTO 在 SQL Server 2008 中保留 ORDER BY,但在 2012 中不保留

    在2008年和2012年执行以下SQL 在2008年执行时 返回的结果是正确的排序顺序 2012 年 排序顺序不再保留 这是已知的变化吗 2012 年是否有保留排序顺序的解决方法 CREATE TABLE MyTable Name VARC
  • 连接在不活动一段时间后挂起

    在我的应用程序中 Spring 管理用于数据库访问的连接池 Hibernate 使用这些连接进行查询 乍一看 我对池没有任何问题 它可以在并发客户端和只有一个连接的池中正常工作 我可以执行很多查询 所以我认为我 或Spring 不会留下开放
  • 使用layout_gravity =“bottom”放置在LinearLayout的底部

    我想在 LinearLayout 的底部放置一个布局 但我似乎无法让它工作 我知道我可以使用RelativeLayout来做到这一点 但我应该能够使用LinearLayout 不是吗 EDIT 事实上这比我想象的更令人困惑 下面的布局已简化
  • 使用折叠工具栏和选项卡滚动

    我正在尝试制作一个布局CollapsingToolbarLayout其中有scroll exitUntilCollapsed标志 和一个TabLayout其中有scroll enterAlways滚动标志属性 基本上我希望我的工具栏被固定并
  • Keras 中每个时期的训练准确性是如何确定的?

    我正在 Keras 中训练一个模型 如下所示 model fit Xtrn ytrn batch size 16 epochs 50 verbose 1 shuffle True callbacks model checkpoint val
  • 是否可以关闭/管理 IIS 上的 SSL 连接/会话?

    我试图找出 IIS 中是否有某种 API 或控件允许我以某种方式控制 SSL 会话 例如关闭会话或要求重新身份验证 底线我问是否有人知道管理从 C 到 IIS 7 的 SSL 连接的方法 类似于 Tomcat 7 的方法 Invalidat
  • 无法选择 UIAlertController 中的按钮顺序

    我的印象是 如果正常操作是破坏性操作 而另一个是 UIAlertController 中的取消操作 则破坏性操作应该位于左侧 取消操作应该位于右侧 如果正常操作不是破坏性的 那么正常操作应该在右侧 取消应该在左侧 也就是说 我有以下内容 v
  • 使用 Sass 的媒体查询无法编译

    我在使用媒体查询混合编译 Sass 文件时遇到错误 我遵循了几个教程 但它无法编译 我在用着Sass 3 3 0 alpha 67 Bleeding Edge 这是我的代码 Included at the end mixin mobile
  • 在类内部使用比较函数进行 sort() 时出现问题

    如果你看一下我在类中的函数 CardCompare 它不起作用 但是 如果我改用 Hand cpp 中注释掉的函数 它就可以正常工作 为什么是这样 另外 我想知道将 CardCompare 函数保留在我的 hand 类中是否比将其保留在 C
  • 如何使用 Firefox 操作系统在后台播放音频?

    在我的清单文件中 我在权限中添加了音频通道内容 permissions audio channel content description Use the audio channel for the music player 在我的 ind
  • 无法捕获 fn 项目中的动态环境

    在此代码中 一切正常 除了task id 我希望这个脚本能够计算请求数task id use std thread use std thread sleep ms use std sync mpsc macro use extern cra
  • Android 设备接收 UDP 广播时丢包

    为了从服务器接收 UDP 广播数据包到 Android 设备 我使用了一个服务类并在线程中侦听数据包 成功接收数据包 问题是 如果服务器同时发送多个数据包 则会导致数据包丢失 我什至尝试使用队列并在单独的线程中处理接收到的数据包 然后我也没