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可能会出现问题,导致程序无…...
MASA模组汉化包终极指南:3分钟告别Minecraft英文界面困扰
MASA模组汉化包终极指南:3分钟告别Minecraft英文界面困扰 【免费下载链接】masa-mods-chinese 一个masa mods的汉化资源包 项目地址: https://gitcode.com/gh_mirrors/ma/masa-mods-chinese 你是否曾在Minecraft中使用Litematica、Minihud等MASA模组时&#…...
别再只会显示字符了!用51单片机和OLED做个简易电子时钟(IIC协议详解)
从零构建51单片机OLED电子时钟:IIC协议深度解析与项目实战 在嵌入式开发领域,51单片机因其稳定性和易用性始终占据一席之地。当基础的点亮OLED屏幕、显示静态文字已经无法满足你的求知欲时,一个融合硬件协议、实时时钟和UI设计的电子时钟项目…...
EFM8 I2C Slave外设深度解析:从SMBus思维转换到实战应用
1. 项目概述:从SMBus到I2C Slave的思维转换如果你之前主要接触的是SMBus(系统管理总线)设备,现在要上手Silicon Labs的EFM8LB1或EFM8BB3这类8位MCU的I2C Slave(从机)功能,可能会觉得有点“水土不…...
Java Agent全链路追踪:无侵入分布式系统监控实战
1. 项目概述:一个面向分布式系统的全链路数据采集探针最近在跟几个做微服务架构的朋友聊天,大家都在头疼同一个问题:线上系统出点性能瓶颈或者偶发性错误,排查起来简直像大海捞针。服务A调用服务B,B又调用了C和D&#…...
打造极致氛围感编码环境:从视觉、听觉到工作流的全栈实践指南
1. 项目概述:当“氛围感”遇上“编码”,一个宝藏仓库的诞生如果你和我一样,是个对开发环境、工具流和“仪式感”有执念的程序员,那你肯定不止一次地折腾过自己的IDE主题、终端配色、字体,甚至桌面的壁纸和音乐。我们内…...
树莓派AI智能体进化框架:轻量化部署与持续学习实践
1. 项目概述:一个面向树莓派的AI智能体进化框架 最近在折腾树莓派上的AI应用时,发现了一个挺有意思的项目: kingkillery/pk-pi-hermes-evolve 。光看这个名字,就能拆解出不少信息点:“pk-pi”显然指的是树莓派平台&…...
Android Recovery 模式工作原理与定制实战
Recovery 是 Android 的"救命系统",负责 OTA 升级、恢复出厂、用户数据加密管理。本文剖析 Recovery 的架构、启动流程、与主系统的通信机制,并演示如何修改并构建一个自定义 Recovery。一、Recovery 到底是什么? 很多人以为 Recovery 是 Android 系统的一个"模…...
TV Bro电视浏览器革命性突破:让Android电视变身智能上网终端
TV Bro电视浏览器革命性突破:让Android电视变身智能上网终端 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro 您是否曾在大屏幕电视前感到手足无措࿱…...
告别GBIF官网卡顿!用R语言raster/dismo包5分钟搞定物种分布数据下载与清洗
告别GBIF官网卡顿!用R语言raster/dismo包5分钟搞定物种分布数据下载与清洗 当你在深夜赶论文,急需下载某个物种的全球分布数据时,GBIF官网却不断弹出"503 Service Unavailable";当你终于打开页面,却发现每页…...
Linux重定向与管道:从文件描述符到高效命令行工作流
1. 项目概述:为什么重定向是命令行的效率倍增器?如果你在Linux命令行里混过一段时间,肯定遇到过这样的场景:想看看一个命令的输出,结果屏幕刷地一下滚过去几百行,关键信息一闪而过;或者想把一个…...
