当前位置: 首页 > news >正文

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服务

需求&#xff1a;通过手机给设备升级固件&#xff0c;设备有WIFI 方案&#xff1a;升级包放到APP可以访问的目录&#xff0c;手机开热点并启动一个HTTP服务&#xff0c;设备连接手机热点&#xff0c;另外&#xff0c;设备端开启一个 telnet 服务&#xff0c;手机通过 telnet 登…...

NLP - word2vec详解

Word2Vec是一种用于将词汇映射到高维向量空间的自然语言处理技术。由Google在2013年提出&#xff0c;它利用浅层神经网络模型来学习词汇的分布式表示。Word2Vec有两种主要模型&#xff1a;CBOW&#xff08;Continuous Bag of Words&#xff09;和Skip-gram。 1. 模型介绍 Con…...

AI办公自动化:用通义千问批量翻译长篇英语TXT文档

在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;F:\AI自媒体内容\待翻译&#xff1b; 获取里面所有TXT文档&#xff…...

一键解压,无限可能——BetterZip,您的Mac必备神器!

BetterZip for Mac 是一款高效、智能且安全的解压缩软件&#xff0c;专为Mac用户设计。它提供了直观易用的界面&#xff0c;使用户能够轻松应对各种压缩和解压缩需求。 这款软件不仅支持多种压缩格式&#xff0c;如ZIP、RAR、7Z等&#xff0c;还具备快速解压和压缩文件的能力。…...

【数学】什么是最大似然估计?如何求解最大似然估计

背景 最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一种估计统计模型参数的方法。它在众多统计学领域中被广泛使用&#xff0c;比如回归分析、时间序列分析、机器学习和经济学。其核心思想是&#xff1a;给定一个观测数据集&#xff0c;找到一组…...

跟张良均老师学大数据人工智能|企业项目试岗实训开营

我国高校毕业生数量连年快速增长&#xff0c;从2021年的909万人到2022年的1076万人&#xff0c;再到2023年的1158万人&#xff0c;预计到2024年将达到1187万人&#xff0c;2024年高校毕业生数量再创新高。 当年高校毕业生人数不等于进入劳动力市场的高校毕业生人数&#x…...

Pentest Muse:一款专为网络安全人员设计的AI助手

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

10 SpringBoot 静态资源访问

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

Unity 之通过自定义协议从浏览器启动本地应用程序

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

Python抓取天气信息

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

【超越拟合:深度学习中的过拟合与欠拟合应对策略】

如何处理过拟合 由于过拟合的主要问题是你的模型与训练数据拟合得太好&#xff0c;因此你需要使用技术来“控制它”。防止过拟合的常用技术称为正则化。我喜欢将其视为“使我们的模型更加规则”&#xff0c;例如能够拟合更多类型的数据。 让我们讨论一些防止过拟合的方法。 获…...

【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协议工具

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…...

web前端组织分析:深入剖析其结构、功能与未来趋势

web前端组织分析&#xff1a;深入剖析其结构、功能与未来趋势 在数字化浪潮的推动下&#xff0c;Web前端组织作为连接用户与数字世界的桥梁&#xff0c;其重要性日益凸显。本文将从四个方面、五个方面、六个方面和七个方面对Web前端组织进行深入分析&#xff0c;揭示其结构特点…...

GitCode热门开源项目推荐:Spider网络爬虫框架

在数字化高速发展时代&#xff0c;数据已成为企业决策和个人研究的重要资源。网络爬虫作为一种强大的数据采集工具受到了广泛的关注和应用。在GitCode这一优秀的开源平台上&#xff0c;Spider网络爬虫框架凭借其简洁、高效和易用性&#xff0c;成为了众多开发者的首选。 一、系…...

实现一个二叉树的前序遍历、中序遍历和后序遍历方法。

package test3;public class Test_A27 {// 前序遍历&#xff08;根-左-右&#xff09;public void preOrderTraversal(TreeNode root){if(rootnull){return;}System.out.println(root.val"");preOrderTraversal(root.left);preOrderTraversal(root.right);}// 中序遍…...

串扰(二)

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

零基础入门学用Arduino 第四部分(三)

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

Mp3文件结构全解析(一)

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

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...