Android开启HTTP服务
需求:通过手机给设备升级固件,设备有WIFI
方案:升级包放到APP可以访问的目录,手机开热点并启动一个HTTP服务,设备连接手机热点,另外,设备端开启一个 telnet 服务,手机通过 telnet 登录到设备系统(Android系统热点的默认IP地址是192.168.43.1,APP可以遍历192.168.43这个IP段的IP以及固定的端口),通过指令下载固件,完成升级。
1. 用到的第三方库
implementation 'commons-net:commons-net:3.9.0' // telnet
implementation 'org.nanohttpd:nanohttpd:2.3.1' // NanoHttpd
implementation 'org.apache.commons:commons-compress:1.23.0'//解压缩文件
implementation 'com.github.junrar:junrar:7.5.4'//解压rar
implementation 'org.tukaani:xz:1.9'//解压.7z文件需要
implementation 'com.sparkjava:spark-core:2.9.4'// sparkjava
2. 添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!-- If your app targets Android 13 (API level 33)or higher, you must declare the NEARBY_WIFI_DEVICES permission. --><!-- If your app derives location information fromWi-Fi APIs, don't include the "usesPermissionFlags"attribute. --><uses-permissionandroid:name="android.permission.NEARBY_WIFI_DEVICES"android:usesPermissionFlags="neverForLocation"tools:targetApi="s" /><!-- If any feature in your app relies onprecise location information, don't include the"maxSdkVersion" attribute. --><!-- Android12获取SSID需要 ACCESS_FINE_LOCATION 权限 --><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"android:maxSdkVersion="32" /><uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32" />
3. 开启热点
APUtil.kt
import android.Manifest
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.wifi.SoftApConfiguration
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import java.lang.reflect.Field
import java.lang.reflect.Methodclass APUtil(private val context: Context) {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerprivate fun securityTypeString(securityType: Int): String {return when (securityType) {SoftApConfiguration.SECURITY_TYPE_OPEN -> "OPEN"SoftApConfiguration.SECURITY_TYPE_WPA2_PSK -> "WPA2_PSK"SoftApConfiguration.SECURITY_TYPE_WPA3_OWE -> "WPA3_OWE"SoftApConfiguration.SECURITY_TYPE_WPA3_SAE -> "WPA3_SAE"SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION -> "WPA3_OWE_TRANSITION"SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION -> "WPA3_SAE_TRANSITION"else -> "Unknown security type: $securityType"}}@RequiresApi(Build.VERSION_CODES.O)private val localOnlyHotspotCallback = object : WifiManager.LocalOnlyHotspotCallback() {override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {super.onStarted(reservation)if (Build.VERSION.SDK_INT >= 30) {reservation?.softApConfiguration?.let { config ->Log.i(TAG, "-------------------------- softApConfiguration --------------------------")if (Build.VERSION.SDK_INT >= 33) {Log.i(TAG, "热点名称: ${config.wifiSsid}")} else {Log.i(TAG, "热点名称: ${config.ssid}")}Log.i(TAG, "热点密码: ${config.passphrase}")Log.i(TAG, "securityType=${securityTypeString(config.securityType)}")Log.i(TAG, "mac=${config.bssid}")}} else {reservation?.wifiConfiguration?.let { config ->Log.i(TAG, "-------------------------- wifiConfiguration --------------------------")Log.i(TAG, "热点名称: ${config.SSID}")Log.i(TAG, "热点密码: ${config.preSharedKey}")Log.i(TAG, "mac=${config.BSSID}")Log.i(TAG, "status=${config.status}")config.httpProxy?.let { httpProxy ->Log.i(TAG, "http://${httpProxy.host}:${httpProxy.port}")}}}}override fun onStopped() {super.onStopped()Log.e(TAG, "onStopped()")}override fun onFailed(reason: Int) {super.onFailed(reason)Log.e(TAG, "onFailed() - reason=$reason")}}fun startHotspot() {if (Build.VERSION.SDK_INT >= 26) {if (ActivityCompat.checkSelfPermission(context,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context,Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) {return}// 官方文档// https://developer.android.google.cn/reference/android/net/wifi/WifiManager#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)wifiManager.startLocalOnlyHotspot(localOnlyHotspotCallback, null)}}fun printHotSpotState() {Log.i(TAG, "热点是否已经打开:方式1 ${isHotSpotApOpen(context)} 方式2 ${isHotSpotApOpen2(context)}")Log.i(TAG, "手机型号:${Build.MANUFACTURER} ${Build.MODEL}")}companion object {private const val TAG = "APUtil"//获取热点是否打开方式1fun isHotSpotApOpen(context: Context): Boolean {var isAPEnable = falsetry {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerval method: Method = wifiManager.javaClass.getDeclaredMethod("getWifiApState")val state = method.invoke(wifiManager) as Intval field: Field = wifiManager.javaClass.getDeclaredField("WIFI_AP_STATE_ENABLED")val value = field.get(wifiManager) as IntisAPEnable = state == valueLog.i(TAG, "state=$state, value=$value")} catch (e: Exception) {e.printStackTrace()}return isAPEnable}//获取热点是否打开方式2fun isHotSpotApOpen2(context: Context): Boolean {var isAPEnable = falsetry {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerval method: Method = wifiManager.javaClass.getDeclaredMethod("isWifiApEnabled")method.isAccessible = trueisAPEnable = method.invoke(wifiManager) as Boolean} catch (e: Exception) {e.printStackTrace()}return isAPEnable}/*** 打开设置热点的页面*/fun openSettings(context: Context) {val intent = Intent()intent.addCategory(Intent.CATEGORY_DEFAULT)intent.action = "android.intent.action.MAIN"val cn = ComponentName("com.android.settings","com.android.settings.Settings\$WirelessSettingsActivity")intent.component = cntry {context.startActivity(intent)} catch (ex: ActivityNotFoundException) {intent.component = ComponentName("com.android.settings","com.android.settings.Settings\$TetherSettingsActivity")context.startActivity(intent)}}}
}
4. 开启HTTP服务
使用 nanohttpd 实现
HttpFileServer.kt
import android.content.Context
import android.util.Log
import fi.iki.elonen.NanoHTTPD
import org.json.JSONObject
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.util.stream.Collectors/*** 手机开热点时使用的IP*/
const val SERVER_IP = "192.168.43.1"
const val SERVER_PORT = 8080private const val TAG = "HttpFileServer"// HFS
class HttpFileServer(context: Context, ipAddress: String) : NanoHTTPD(ipAddress, SERVER_PORT) {init {rootDir = context.getExternalFilesDir("OTA")!!.absolutePathLog.i(TAG, "rootDir=$rootDir")}override fun serve(session: IHTTPSession): Response? {val params = session.parametersLog.e(TAG, String.format("uri=%s", session.uri))for (entry in params.entries) {Log.e(TAG, String.format("%s=%s", entry.key, entry.value.stream().collect(Collectors.joining(", "))))}return responseFile(session)}private fun responseFile(session: IHTTPSession): Response? {//目前使用的是 http://192.168.43.1:8080/filenameval uri = session.urival filename = uri.substring(uri.lastIndexOf('/') + 1)return try {//文件输入流val fis = FileInputStream("$rootDir/${filename}")newFixedLengthResponse(Response.Status.OK, "application/octet-stream", fis, fis.available().toLong())} catch (e: FileNotFoundException) {Log.e(TAG, "$filename 文件不存在!", e)val jsonObj = JSONObject()jsonObj.put("message", "$filename 文件不存在!")Log.e(TAG, jsonObj.toString(2))newFixedLengthResponse(Response.Status.NOT_FOUND, "application/json", jsonObj.toString(2))} catch (e: IOException) {e.printStackTrace()newFixedLengthResponse(session.uri + " 异常 " + e)}}companion object {var rootDir: String = ""}
}
使用 sparkjava 实现
注意:使用的是sparkjava,而不是大数据分析的那个Spark!
// http://192.168.43.1:8080/download?filename=dog.jpg
Spark.port(8080)
Spark.get("download") { req, res ->val filename = req.queryParams("filename")println("thread ${Thread.currentThread().id} - $filename")res.status(200)res.header("Content-Type", "application/octet-stream")res.header("Content-disposition", "attachment; filename=$filename")context.assets.open(filename).use { istream ->istream.copyTo(res.raw().outputStream)}res
}
5. 使用 telnet
WifiUtil.kt
telnet 主要用到了 WifiUtil 的一个属性:network
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.net.wifi.WifiNetworkSpecifier
import android.os.Build
import android.os.PatternMatcher
import android.util.Log
import androidx.annotation.RequiresApi
import site.feiyuliuxing.wifitest.toIPAddressclass WifiUtil(context: Context) {private val mNetworkCallback: ConnectivityManager.NetworkCallbackprivate val mConnectivityManager: ConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerprivate val wifiManager: WifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerprivate var mNetwork: Network? = null//Android系统热点的默认IP地址是192.168.43.1var hostIP = "192.168.43.1"private setval network: Network?get() = mNetworkval targetIP: Stringget() {val arr = hostIP.split(".").toMutableList()arr[arr.lastIndex] = "1"return arr.joinToString(".")}init {if (Build.VERSION.SDK_INT < 29) {//Android10以下系统mNetworkCallback = object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}}} else if (Build.VERSION.SDK_INT < 31) {//Android10 Android11mNetworkCallback = object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}@RequiresApi(Build.VERSION_CODES.Q)override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {// Android10才支持该回调方法callbackCapabilitiesChanged(network, networkCapabilities)}}} else {//Android12获取 SSID 需要 FLAG_INCLUDE_LOCATION_INFO 并获得 ACCESS_FINE_LOCATION 权限mNetworkCallback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}@RequiresApi(Build.VERSION_CODES.Q)override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {// Android10才支持该回调方法callbackCapabilitiesChanged(network, networkCapabilities)}}}}private fun callbackAvailable(network: Network) {mNetwork = networkhostIP = getIP(network)}private fun callbackLost(network: Network) {mNetwork = null}@RequiresApi(Build.VERSION_CODES.Q)private fun callbackCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {val wifiInfo = networkCapabilities.transportInfo as WifiInfo?if (wifiInfo != null) {println("onCapabilitiesChanged() - SSID=${wifiInfo.ssid}, IP=${wifiInfo.ipAddress.toIP()}")}}private val networkRequest: NetworkRequestget() = NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).apply {if (Build.VERSION.SDK_INT >= 29) {val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
// .setBand(ScanResult.WIFI_BAND_24_GHZ)//Android12 但是设置这个参数后无法连接.setSsidPattern(PatternMatcher("ZS[0-9a-fA-F]{8}", PatternMatcher.PATTERN_ADVANCED_GLOB))
// .setSsid("ZS3755a0e2").setWpa2Passphrase("12345678").build()setNetworkSpecifier(wifiNetworkSpecifier)}}.build()fun requestConnectWIFI() {mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback)}fun close() {mConnectivityManager.unregisterNetworkCallback(mNetworkCallback)}//无需运行时申请权限fun getGatewayIP(): String {if (Build.VERSION.SDK_INT < 32) {/*This method was deprecated in API level 31.Use the methods on LinkProperties which can be obtained either viaNetworkCallback#onLinkPropertiesChanged(Network, LinkProperties) orConnectivityManager#getLinkProperties(Network).*/val dhcpInfo = wifiManager.dhcpInfo// 网关IP地址是一个整数,需要转换为可读的IP地址格式val gatewayIpAddress: String = dhcpInfo.gateway.toIPAddress()println("Gateway IP: $gatewayIpAddress")return gatewayIpAddress} else {var addr = ""mConnectivityManager.activeNetwork?.let { network ->mConnectivityManager.getLinkProperties(network)?.let { linkProperties ->linkProperties.dhcpServerAddress?.let { inet4Address ->addr = inet4Address.hostAddress ?: ""}}}println("网关IP: $addr")return addr}}private fun getIP(network: Network): String {mConnectivityManager.getLinkProperties(network)?.linkAddresses?.let { linkAddresses ->linkAddresses.forEach { linkAddress ->// hostAddress: the IP address string in textual presentation.linkAddress.address.hostAddress?.let { hostAddress ->if (hostAddress.isValidIP) {println("手机IP:${hostAddress}")return hostAddress}}}}return ""}private val ipRegex = """\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}""".toRegex()private val String.isValidIP: Booleanget() = ipRegex.matches(this)private fun Int.toIP(): String {return "${this.and(0xff)}" +".${this.shr(8).and(0xff)}" +".${this.shr(16).and(0xff)}" +".${this.shr(24).and(0xff)}"}
}
TelnetUtil.kt
import android.net.Network
import org.apache.commons.net.telnet.EchoOptionHandler
import org.apache.commons.net.telnet.SuppressGAOptionHandler
import org.apache.commons.net.telnet.TelnetClient
import org.apache.commons.net.telnet.TerminalTypeOptionHandlerclass TelnetUtil {private val telnetClient = TelnetClient()private fun connectServer(ip: String, network: Network?): Boolean {try {if (network != null) {telnetClient.setSocketFactory(network.socketFactory)}/*val ttopt = TerminalTypeOptionHandler("VT220", false, false, true, false)val echoopt = EchoOptionHandler(true, false, true, false)val gaopt = SuppressGAOptionHandler(true, true, true, true)telnetClient.addOptionHandler(ttopt)telnetClient.addOptionHandler(echoopt)telnetClient.addOptionHandler(gaopt)*/telnetClient.connect(ip, 23)if (telnetClient.isConnected) {println("端口可用 $ip")return true}} catch (ex: Exception) {ex.printStackTrace()}return false}fun readUntil(match: String, timeout: Long = 10_000): Boolean {val sb = StringBuilder()val startTime = System.currentTimeMillis()while (true) {if ((System.currentTimeMillis() - startTime) >= timeout) {//超时break}var len = telnetClient.inputStream.available()while (len > 0) {val ch = telnetClient.inputStream.read()if (ch != -1) {sb.append(ch.toChar())print(ch.toChar())if (ch == 0x0D || ch == 0x0A) {System.out.flush()}if (sb.contains(match)) {println(sb.toString())return true}}len--}}println(sb.toString())return false}fun send(msg: String) {telnetClient.outputStream.apply {write(msg.toByteArray(Charsets.UTF_8))flush()}}
}
6. 解压缩文件
参考这篇文章:Android解压 zip rar 7z 文件
相关文章:
Android开启HTTP服务
需求:通过手机给设备升级固件,设备有WIFI 方案:升级包放到APP可以访问的目录,手机开热点并启动一个HTTP服务,设备连接手机热点,另外,设备端开启一个 telnet 服务,手机通过 telnet 登…...
NLP - word2vec详解
Word2Vec是一种用于将词汇映射到高维向量空间的自然语言处理技术。由Google在2013年提出,它利用浅层神经网络模型来学习词汇的分布式表示。Word2Vec有两种主要模型:CBOW(Continuous Bag of Words)和Skip-gram。 1. 模型介绍 Con…...

AI办公自动化:用通义千问批量翻译长篇英语TXT文档
在deepseek中输入提示词: 你是一个Python编程专家,现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本,具体步骤如下: 打开文件夹:F:\AI自媒体内容\待翻译; 获取里面所有TXT文档ÿ…...

一键解压,无限可能——BetterZip,您的Mac必备神器!
BetterZip for Mac 是一款高效、智能且安全的解压缩软件,专为Mac用户设计。它提供了直观易用的界面,使用户能够轻松应对各种压缩和解压缩需求。 这款软件不仅支持多种压缩格式,如ZIP、RAR、7Z等,还具备快速解压和压缩文件的能力。…...
【数学】什么是最大似然估计?如何求解最大似然估计
背景 最大似然估计(Maximum Likelihood Estimation, MLE)是一种估计统计模型参数的方法。它在众多统计学领域中被广泛使用,比如回归分析、时间序列分析、机器学习和经济学。其核心思想是:给定一个观测数据集,找到一组…...

跟张良均老师学大数据人工智能|企业项目试岗实训开营
我国高校毕业生数量连年快速增长,从2021年的909万人到2022年的1076万人,再到2023年的1158万人,预计到2024年将达到1187万人,2024年高校毕业生数量再创新高。 当年高校毕业生人数不等于进入劳动力市场的高校毕业生人数&#x…...

Pentest Muse:一款专为网络安全人员设计的AI助手
关于Pentest Muse Pentest Muse是一款专为网络安全研究人员和渗透测试人员设计和开发的人工智能AI助手,该工具可以帮助渗透测试人员进行头脑风暴、编写Payload、分析代码或执行网络侦查任务。除此之外,Pentest Muse甚至还能够执行命令行代码并以迭代方式…...

10 SpringBoot 静态资源访问
我们在开发Web项目的时候,往往会有很多静态资源,如html、图片、css等。那如何向前端返回静态资源呢? 以前做过web开发的同学应该知道,我们以前创建的web工程下面会有一个webapp的目录,我们只要把静态资源放在该目录下…...

Unity 之通过自定义协议从浏览器启动本地应用程序
内容将会持续更新,有错误的地方欢迎指正,谢谢! Unity 之通过自定义协议从浏览器启动本地应用程序 TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进…...

Python抓取天气信息
Python的详细学习还是需要些时间的。如果有其他语言经验的,可以暂时跟着我来写一个简单的例子。 2024年最新python教程全套,学完即可进大厂!(附全套视频 下载) (qq.com) 我们计划抓取的数据:杭州的天气信息…...

【超越拟合:深度学习中的过拟合与欠拟合应对策略】
如何处理过拟合 由于过拟合的主要问题是你的模型与训练数据拟合得太好,因此你需要使用技术来“控制它”。防止过拟合的常用技术称为正则化。我喜欢将其视为“使我们的模型更加规则”,例如能够拟合更多类型的数据。 让我们讨论一些防止过拟合的方法。 获…...

【Orange Pi 5与Linux内核编程】-理解Linux内核中的container_of宏
理解Linux内核中的container_of宏 文章目录 理解Linux内核中的container_of宏1、了解C语言中的struct内存表示2、Linux内核的container_of宏实现理解3、Linux内核的container_of使用 Linux 内核包含一个名为 container_of 的非常有用的宏。本文介绍了解 Linux 内核中的 contain…...

003.Linux SSH协议工具
我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…...
web前端组织分析:深入剖析其结构、功能与未来趋势
web前端组织分析:深入剖析其结构、功能与未来趋势 在数字化浪潮的推动下,Web前端组织作为连接用户与数字世界的桥梁,其重要性日益凸显。本文将从四个方面、五个方面、六个方面和七个方面对Web前端组织进行深入分析,揭示其结构特点…...

GitCode热门开源项目推荐:Spider网络爬虫框架
在数字化高速发展时代,数据已成为企业决策和个人研究的重要资源。网络爬虫作为一种强大的数据采集工具受到了广泛的关注和应用。在GitCode这一优秀的开源平台上,Spider网络爬虫框架凭借其简洁、高效和易用性,成为了众多开发者的首选。 一、系…...
实现一个二叉树的前序遍历、中序遍历和后序遍历方法。
package test3;public class Test_A27 {// 前序遍历(根-左-右)public void preOrderTraversal(TreeNode root){if(rootnull){return;}System.out.println(root.val"");preOrderTraversal(root.left);preOrderTraversal(root.right);}// 中序遍…...

串扰(二)
三、感性串扰 首先看下串扰模型及电流方向: 由于电感是阻碍电流变化,受害线的电流方向和攻击线的电流方向相反。同时由于受害线阻抗均匀,故有Vb-Vf(感应电流属于电池内部电流)。 分析感性串扰大小仍然是按微分的方法…...

零基础入门学用Arduino 第四部分(三)
重要的内容写在前面: 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路…...

Mp3文件结构全解析(一)
Mp3文件结构全解析(一) MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3的全称应为MPEG1 Layer-3 音频 文件,MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG 音频文件…...

ES 8.14 Java 代码调用,增加knnSearch 和 混合检索 mixSearch
1、pom依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>8.14.0</version></dependency><dependency><groupId>co.elastic.clients<…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》
近日,嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》,海云安高敏捷信创白盒(SCAP)成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天,网络安全已成为企业生存与发展的核心基石,为了解…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

CTF show 数学不及格
拿到题目先查一下壳,看一下信息 发现是一个ELF文件,64位的 用IDA Pro 64 打开这个文件 然后点击F5进行伪代码转换 可以看到有五个if判断,第一个argc ! 5这个判断并没有起太大作用,主要是下面四个if判断 根据题目…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...