Android Framework 常见解决方案(20)UDP广播无效问题
1 现象描述和原理解读
该问题同时存在于android App和Framework系统中。最终效果是在Android系统中直接使用UDP广播无效,有意思的是有的android系统可以,有的Android 系统不行。然而该部分代码自己在Linux上测试时是有效的,代码不变,只是简单的编译移植过来就变得莫名其妙的不行了,头还真是大的不行。
UDP广播接收端的关键实现程序如下所示:
#include <iostream>
#include <string>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>const int UDP_PORT = 19662;int main() {int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);if (socket_fd == -1) {std::cerr << "Failed to create socket" << std::endl;return 1;}struct sockaddr_in local_address{};local_address.sin_family = AF_INET;local_address.sin_addr.s_addr = INADDR_ANY;local_address.sin_port = htons(UDP_PORT);if (bind(socket_fd, (struct sockaddr*)&local_address, sizeof(local_address)) == -1) {std::cerr << "Failed to bind socket" << std::endl;close(socket_fd);return 1;}std::cout << "Listening for UDP broadcast on port " << UDP_PORT << std::endl;char buffer[1024];struct sockaddr_in sender_address{};socklen_t sender_address_length = sizeof(sender_address);while (true) {ssize_t bytes_received = recvfrom(socket_fd, buffer, sizeof(buffer), 0,(struct sockaddr*)&sender_address, &sender_address_length);if (bytes_received == -1) {std::cerr << "Error receiving data" << std::endl;close(socket_fd);return 1;}std::string received_message(buffer, bytes_received);std::cout << "Received message from " << inet_ntoa(sender_address.sin_addr)<< ": " << received_message << std::endl;}close(socket_fd);return 0;
}
UDP广播发送端测试程序如下:
#include <iostream>
#include <string>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>const int UDP_PORT = 19662;
const std::string UDP_BROADCAST_ADDRESS = "192.168.1.255";int main() {int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);if (socket_fd == -1) {std::cerr << "Failed to create socket" << std::endl;return 1;}int broadcast_enable = 1;if (setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) == -1) {std::cerr << "Failed to enable broadcast" << std::endl;close(socket_fd);return 1;}struct sockaddr_in target_address{};target_address.sin_family = AF_INET;target_address.sin_port = htons(UDP_PORT);if (inet_pton(AF_INET, UDP_BROADCAST_ADDRESS.c_str(), &target_address.sin_addr) <= 0) {std::cerr << "Invalid address" << std::endl;close(socket_fd);return 1;}std::string message = "Hello UDP Broadcast!";ssize_t bytes_sent = sendto(socket_fd, message.c_str(), message.size(), 0,(struct sockaddr*)&target_address, sizeof(target_address));if (bytes_sent == -1) {std::cerr << "Failed to send data" << std::endl;close(socket_fd);return 1;}std::cout << "Sent broadcast message: " << message << std::endl;close(socket_fd);return 0;
}
在移植到android的过程中实际上是使用android走JNI调用C++的方式来使用,这里就不详述了。
最后分析,发现,果然是android的问题。因为在 移动端 Android 系统中,使用 UDP 广播可能会引发一些耗电的问题,因为 UDP 广播需要 Wi-Fi 连接保持在活动状态,以便能够发送和接收数据包。为了避免在应用程序使用 UDP 广播时造成不必要的电池消耗,开发者可以考虑使用 Wi-Fi 锁来控制 Wi-Fi 连接的状态。
Wi-Fi 锁是 Android 提供的一种机制,允许应用程序在需要时保持 Wi-Fi 连接处于活动状态,而不会由于系统的网络管理策略而被关闭或断开连接。使用 Wi-Fi 锁,应用程序可以确保在需要进行网络通信时,Wi-Fi 连接一直保持活跃,从而避免了频繁的连接和断开过程,这有助于降低耗电量。
2 修改方案(Android All)
Wi-Fi锁的获取和释放源码如下所示:
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;public class WifiLockManager {private WifiLock wifiLock;private WifiManager wifiManager;public WifiLockManager(Context context) {wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "MyWifiLock");}//获取锁public void acquireWifiLock() {wifiLock.acquire();}//释放锁public void releaseWifiLock() {if (wifiLock.isHeld()) {wifiLock.release();}}
}
这样在UDP广播时就不会出现连不上的情况了。实际上Wi-Fi 锁机制从 Android 1.0 版本就存在,但是随着不同版本的 Android 系统的发布和演变,该机制可能会有一些变化和改进。
具体的行为和影响因 Android 版本和设备厂商而异。在早期的 Android 版本中,Wi-Fi 锁主要用于控制 Wi-Fi 连接的休眠策略,以防止在连接处于活动状态时进入省电模式。然而,随着 Android 版本的更新,系统对网络管理策略进行了多次改进,旨在更好地平衡性能和电池寿命,因此 Wi-Fi 锁的影响和需求可能会因 Android 版本的变化而变化。
另外,不同的硬件厂商可能会在其定制的 Android 版本中对网络管理和电池优化策略进行调整。这意味着在某些设备上,Wi-Fi 锁的行为可能会受到硬件和厂商定制的影响,因此才会出现有的设备能直接广播而有的需要wifi锁这样的情况。
相关文章:
Android Framework 常见解决方案(20)UDP广播无效问题
1 现象描述和原理解读 该问题同时存在于android App和Framework系统中。最终效果是在Android系统中直接使用UDP广播无效,有意思的是有的android系统可以,有的Android 系统不行。然而该部分代码自己在Linux上测试时是有效的,代码不变…...
VINS-Mono中的边缘化与滑窗 (4)——VINS边缘化为何是局部变量边缘化?
文章目录 0.前言1.系统构建1.1.仿真模型1.2.第一次滑窗优化1.3.第二次全局优化 2.边缘化时不同的舒尔补方式2.1.边缘化时舒尔补的意义2.2.不同的边缘化方式 3.边缘化时不同的舒尔补方式实验验证3.1.全局schur的操作方式3.2.VIO或VINS中局部边缘化的方式3.3.两种方式和全局优化方…...
真·VB.NET彻底释放Interop.Excel对象
使用 Microsoft.Office.Interop.Excel 虽然有速度慢的缺点;但是作为自带引用,兼容性最好,而且是COM对象模型也很熟悉(Excel里直接录个宏,很方便把VBA代码转成VB.NET)。所以处理几百上千条的小数据时还是很方便的。 而 Microsoft.…...
记录hutool http通过代理模式proxy访问外面的链接
效果: 代码: public class TestMain {public static void main(String[] args){HttpRequest httpRequest HttpRequest.get("https://www.youtube.com").timeout(30000);httpRequest.setProxy(new Proxy(Proxy.Type.HTTP,new InetSocketAddre…...
Selenium 自动化 | 案例实战篇
Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器(如 Chrome、Opera 和 Microsoft Edge)中的工具,用于帮助开发人员调试和研究网站。 借助 Chrome DevTools,开发人员可以更深入地访问网站…...
前端技术栈es6+promise
let入门使用、 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>let 基本使用</title><script type"text/javascript">let name "hspedu教育";//老韩解读//1. conso…...
windows vscode使用opencv
1.windows vscode使用opencv 参考:https://blog.csdn.net/zhaiax672/article/details/88971248 https://zhuanlan.zhihu.com/p/402378383 https://blog.csdn.net/weixin_39488566/article/details/121297536 g -g .\hello_opencv.cpp -stdc14 -I E:\C-software\…...
json文件读取数据报错 AttributeError: ‘str‘ object has no attribute ‘items‘
trans_width_table表如下: {frozenset({2}): {3: 250, 2.5: 100, 1.5: 25, 2: 50, 1.8: 50, 2.75: 200, 5: 350, 4: 350, 2.3: 100, 4.5: 350, 3.5: 300}, frozenset({1, 3, 4, 5}): {2.5: 75, 2.75: 100, 1.5: 25, 4: 300, 3.5: 200, 4.5: 300, 3: 100, 5: 300, 2…...
1、Spring_IOC
IOC 1.概述 IOC:Inversion of Control 控制反转,可以让容器负责对象的创建以及销毁操作,对象在容器中叫 bean 2.回顾问题 问题:写了太多与业务无关的代码 耦合度非常高,写了很多和业务无关的代码不利于项目的升级迭…...
Socks5、IP代理在爬虫开发与HTTP通信中的应用
随着互联网的不断发展,代理服务器成为网络工程师和数据爬虫开发者的关键工具。本文将深入探讨Socks5代理、IP代理以及它们在网络安全、爬虫开发和HTTP通信中的重要作用。 1. 代理服务器:保障隐私与安全的中间人 代理服务器是位于客户端与目标服务器之间…...
重新认识小米
被镁光灯聚焦的企业,总是会被贴上各种标签。 8月14日,小米科技创始人雷军以“成长”为主题的年度演讲,刷遍社交网络。提到小米,你首先想到什么?手机发烧友、极致性价比,还是最年轻的500强? 这…...
react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等
react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等 一、react-redux介绍二、React-Redux-基本使用三、获取状态useSelector四、分发动作useDispatch五、 Redux 数据流六、代码结构七、ActionType的使用八、Reducer的分离与合并九、购物挣…...
滑块验证码-接口返回base64数据
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言所需包图片示例使用方法提示前言 滑动验证码在实际爬虫开发过程中会遇到很多,不同网站返回的数据也是千奇百怪。这里分享一种接口返回base64格式的情况以及处理方式 所需包 opencv-python、…...
智能文件改名,一键与上上级目录名称同步,让文件整理更加便捷
在整理文件时,经常会遇到需要将文件名称与上上级目录名称保持一致的情况。手动逐个修改文件名不仅费时费力,还容易出错。现在,我们为你带来了一款智能文件改名工具,让你能够一键将文件名称改成跟上上级目录名称一样,让…...
RK3399平台开发系列讲解(内核调试篇)Valgrind使用案例
🚀返回专栏总目录 文章目录 一、使用未初始化的内存案例二、内存泄露三、在内存被释放后进行读/写案例四、从已分配内存块的尾部进行读/写案例五、两次释放内存案例沉淀、分享、成长,让自己和他人都能有所收获!😄 📢Valgrind 是一个开源的内存调试和性能分析工具,用于…...
07_缓存预热缓存雪崩缓存击穿缓存穿透
缓存预热&缓存雪崩&缓存击穿&缓存穿透 一、缓存预热 提前将数据从数据库同步到redis。 在程序启动的时候,直接将数据刷新到redis懒加载,用户访问的时候,第一次查询数据库,然后将数据写入redis 二、缓存雪崩 发生情…...
常见前端基础面试题(HTML,CSS,JS)(三)
JS 中如何进行数据类型的转换? 类型转换可以分为两种,隐性转换和显性转换 显性转换 主要分为三大类:数值类型、字符串类型、布尔类型 三大类的原始类型值的转换规则我就不一一列举了 数值类型(引用类型转换) Numbe…...
CSS(JavaEE初阶系列14)
目录 前言: 1.CSS是什么 1.1CSS基本语法 2.引入样式 2.1内部样式表 2.2行内样式表 2.3外部样式 3.选择器 3.1选择器的种类 3.1.1基础选择器 3.1.2复合选择器 4.常用元素属性 4.1字体属性 4.2文本属性 4.3背景属性 4.4圆角矩形 4.5元素的显示模式 4…...
学习笔记230810--get请求的两种传参方式
问题描述 今天写了一个对象方式传参的get请求接口方法,发现没有载荷,ip地址也没有带查询字符串,数据也没有响应。 代码展示 错误分析 实际上这里的query是对象方式带参跳转的参数名,而get方法对象方式传参的参数名是parmas 解…...
游戏找不到msvcr100.dll解决方法,常见的三种解决方法
在计算机领域,msvcr100.dll是一个非常重要的动态链接库文件。它是Microsoft Visual C 2010 Redistributable的一部分,用于支持Visual Studio 2010的开发环境。然而,在某些情况下,msvcr100.dll可能会出现问题,导致程序无…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
