學習 Android(十四)NDK基礎

學習 Android(十四)NDK基礎

Android NDK 是一個工具集,可讓我們使用 C 和 C++ 等語言以原生代碼實現應用的各個部分。對于特定類型的應用,這可以幫助我們重復使用以這些語言編寫的代碼庫。

接下來,我們將按照以下步驟進行講解

  • NDK 是什么,作用和原理
  • Android Studio 中配置 NDK 與 CMake
  • 創建簡單 Native 庫(C/C++),Java 調用 Native 方法
  • 了解 JNI 基本概念,基本數據類型映射,Java 和 C++ 函數簽名
  • 學習如何傳遞 Java 字符串、數組到 Native ,反之亦然

1. NDK 是什么?作用和原理

1.1 NDK 是什么?

原生開發套件 (NDK) 是一套工具,能夠讓我們在 Android 應用中使用 C 和 C++ 代碼,并提供眾多平臺庫,我們可使用這些平臺庫管理原生 activity 和訪問實體設備組件,例如傳感器和觸控輸入。NDK 可能不適合大多數 Android 編程初學者(例如作者我),初學者只需使用 Java 代碼和框架 API 開發應用。然而,我們需要實現以下一個或多個目標,那么 NDK 就能派上用場:

  • 進一步提升設備性能,以降低延遲或運行游戲或物理模擬等計算密集型應用。

  • 重復使用您自己或其他開發者的 C 或 C++ 庫。

我們可以在 Android Studio 2.2 或更高版本中使用 NDK 將 C 和 C++ 代碼編譯到原生庫中,然后使用 Android Studio 的集成構建系統 Gradle 將原生庫打包到 APK 中。Java 代碼隨后可以通過 Java 原生接口 (JNI) 框架調用原生庫中的函數。

Android Studio 編譯原生庫的默認構建工具是 CMake。由于很多現有項目都使用 ndk-build 構建工具包,因此 Android Studio 也支持 ndk-build。不過,如果要創建新的原生庫,則應使用 CMake。

1.2 NDK 的工作原理

NDK 的本質是通過 JNI(Java Native Interface)橋接 Java/Kotlin 和 C/C++ 本地代碼,從而實現跨語言通信與調用,并在 Android 系統中生成 .so 動態鏈接庫供運行時加載。

  • 整體架構流程圖如下所示
Java/Kotlin 層|| 調用 native 方法v
JNI (Java Native Interface)|| 負責參數類型轉換、方法注冊v
C/C++ 層代碼(通過 NDK 編譯)|| 編譯為 .so 動態庫v
libnative-lib.so 被 Android 加載并運行
  • Java 層聲明 native 方法

    我們首先要在 Java 或 Kotlin 中用 native 關鍵字聲明一個方法:

    public class NativeLib {static {System.loadLibrary("native-lib"); // 加載 C/C++ 編譯生成的 .so 文件}public native int add(int a, int b); // native 方法,C/C++ 實現
    }
    
  • C/C++ 層實現(通用JNI)

    我們需要在 C/C++ 中用 JNI 方式實現這個方法,簽名必須完全匹配

    extern "C" JNIEXPORT jint JNICALL
    Java_com_example_NativeLib_add(JNIEnv *env, jobject thisz, jnit a, jint b) {return a + b;
    }
    
    • JNIEnv* 是 JNI 環境指針(用于訪問 Java)

    • jobject 是 Java 傳進來的對象引用(即 this)

  • 構建和變異位動態庫(.so 文件)

    使用 CMakeLists.txtAndroid.mk 構建規則,把你的 C++ 文件編譯成 .so

    • 輸出目錄:app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so

    • 會被打包進 APK,在運行時由 System.loadLibrary 加載

  • 運行時調用流程

    • 用戶點擊或代碼調用 NativeLib.add()

    • JVM 會通過 JNI 找到 .so 文件中注冊的 Java_com_example_NativeLib_add() 方法

    • 調用 C++ 實現,返回結果給 Java

2. Android Studio 中配置 NDK 與 CMake

2.1 在 Android Studio 中操作:

  1. 打開 Preferences(設置)

    • macOS: Android Studio > Preferences

    • Windows/Linux: File > Settings

  2. 導航到:
    Appearance & Behavior > System Settings > Android SDK > SDK Tools

  3. 勾選并安裝:

    • NDK (Side by side)

    • CMake

    • LLDB(可選,調試 C++ 用)

2.2 配置 build.gradle 文件

以下以 App 模塊的 build.gradle(Groovy 版) 為例說明配置方式:

  1. defaultConfig 中添加:

    defaultConfig {...externalNativeBuild {cmake {cppFlags ""}}ndk {abiFilters 'armeabi-v7a', 'arm64-v8a' // 你可以根據需求精簡架構}
    }
    
  2. 配置 externalNativeBuild

    android {...externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt" // 指向你的 CMake 配置文件version "3.22.1" // 根據你安裝的版本寫}}
    }
    

2.3 創建 C/C++ 文件和 CMake 配置

app/└── src/└── main/├── cpp/│    ├── native-lib.cpp│    └── CMakeLists.txt└── java/

native-lib.cpp

#include <jni.h>extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkdemo_NativeLib_add(JNIEnv *env, jobject obj, jint a, jint b) {return a + b;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10.2)project("ndkdemo")add_library( # 構建庫名native-libSHAREDnative-lib.cpp
)find_library( # 找到 log 庫log-liblog
)target_link_libraries( # 鏈接 log 庫native-lib${log-lib}
)

2.4 Java 層調用 native 方法

public class NativeLib {static {System.loadLibrary("native-lib"); // 加載 .so}public native int add(int a, int b); // 聲明 native 方法
}

2.5 構建與運行

  1. 點擊 Build → Rebuild Project

  2. .so 文件將生成在:
    app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so

  3. 如果你運行到 ARM64 模擬器或真機,程序會自動加載對應 .so 并調用你的 native 方法。

3. 創建簡單 Native 庫(C/C++),Java 調用 Native 方法

3.1 步驟一:項目結構準備

在 Android Studio 中新建一個空項目(Empty Activity),選擇 Java語言,API 21,然后按如下結構添加文件:

app/└── src/└── main/├── cpp/│    ├── native-lib.cpp      C++ 實現文件│    └── CMakeLists.txt      CMake 構建文件└── java/com/example/ndkdemo/└── NativeLib.java      Java 調用封裝類

3.2 步驟二:配置 build.gradle (app 模塊)

android {defaultConfig {...// 指定使用的 ABI 架構ndk {abiFilters 'armeabi-v7a', 'arm64-v8a'}// 配置 CMake 構建externalNativeBuild {cmake {cppFlags ""}}}// 指定 CMake 構建文件路徑externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt"}}
}

3.3 步驟三:創建 CMake 構建文件(CMakeLists.txt)

app/src/main/cpp/CMakeLists.txt 中實現

cmake_minimum_required(VERSION 3.10.2)
project("ndkdemo") // 記得這是填對應的名稱add_library( # native 庫名native-libSHAREDnative-lib.cpp
)find_library( # 引用 Android 日志庫(可選)log-liblog
)target_link_libraries(native-lib${log-lib}
)

3.4 步驟四:實現 C++ 代碼(native-lib.cpp)

app/src/main/cpp/native-lib.cpp 中實現

#include <jni.h>// 使用 extern "C" 避免 C++ 方法名被改寫(mangling)
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkdemo_NativeLib_add(JNIEnv *env, jobject thiz, jint a, jint b) {return a + b;
}

3.5 步驟五:Java 封裝 Native 調用

com/example/ndkdemo/NativeLib.java 中實現

package com.example.ndkdemo;public class NativeLib {static {System.loadLibrary("native-lib"); // 加載 native-lib.so 動態庫}// native 方法聲明,由 C++ 實現public native int add(int a, int b);
}

3.6 步驟六:在 Activity 中調用驗證

com/example/ndkdemo/MainActivity.java 中實現

public class MainActivity extends AppCompatActivity {private final NativeLib nativeLib = new NativeLib();private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = findViewById(R.id.tv_result);int result = nativeLib.add(3, 4); // 調用 native 方法textView.setText("3 + 4 = " + result);}
}

3.7 步驟七:構建運行

編譯運行結果如下所示
在這里插入圖片描述

4. 了解 JNI 基本概念,基本數據類型映射,Java 和 C++ 函數簽名

接下來我們將針對 JNI 進行相關的學習和了解

4.1 基本數據類型

Java 類型JNI 類型描述
booleanjboolean無符號 8 位(通常為 unsigned char),
值為 JNI_TRUE (1)JNI_FALSE (0)
bytejbyte有符號 8 位
charjchar無符號 16 位
shortjshort有符號 16 位
intjint有符號 32 位
longjlong有符號 64 位
floatjfloat32 位 IEEE 浮點數
doublejdouble64 位 IEEE 浮點數
voidvoid對應 void 類型

4.2 引用類型

Java 類型JNI 類型說明
java.lang.Objectjobject所有對象的基類
任意 Java 類jclassJava 類的引用
java.lang.StringjstringJava 字符串
T[](Java 數組)jarray所有數組的基類
原始類型數組jintArrayjbyteArray特定類型的數組
Java 對象數組jobjectArray包含對象引用的數組
異常jthrowable可被 throw 的對象

4.3 特殊輔助類型

JNI 類型定義用途
jsizetypedef jint jsize;表示數組、字符串長度或大小等
jfieldID不透明指針類型標識一個類的字段
jmethodID不透明指針類型標識一個類的方法

4.4 本地方法接口類型

JNI 提供的所有函數都通過這兩個結構體訪問:

類型名說明
JNIEnv *每個線程獨有,包含 JNI 所有函數指針
JavaVM *JVM 實例指針,用于跨線程附加線程等操作

4.5 布爾常量

為兼容 C 語言布爾類型,定義了:

#define JNI_TRUE  1
#define JNI_FALSE 0

4.6 原始類型數組

Java 類型JNI 類型
boolean[]jbooleanArray
byte[]jbyteArray
char[]jcharArray
short[]jshortArray
int[]jintArray
long[]jlongArray
float[]jfloatArray
double[]jdoubleArray

4.7 對象數組

Java 類型JNI 類型說明
String[]jobjectArray指向一組 jstring 對象的數組
Object[]jobjectArray可存放任意引用類型對象
SomeClass[]jobjectArray存放 SomeClass 對象的數組

5 Java 和 C++ 函數簽名

Java 和 C++ 函數簽名是函數唯一身份的定義方式,但兩者的表現形式和規則存在差異。

5.1 Java 的函數簽名

Java 中函數簽名包括:函數名 + 參數類型列表(不包括返回值)

public int add(int a, int b) { ... }

Java 中,下面兩個方法簽名相同,會報錯

public void test(int x) { }
public int tes(int x) { } // 編譯報錯:簽名沖突(返回值不算簽名)

Java 方法簽名示例(包括參數類型):

方法聲明簽名(方法名 + 參數類型)
void foo(int x)foo(I)
void foo(String s)foo(Ljava/lang/String;)
void foo(int[] arr)foo([I)
void foo(int x, String s)foo(ILjava/lang/String;)

5.2 C++ 的函數簽名

C++ 中函數簽名包括:函數名 + 參數類型列表(返回值不計入簽名)

int add(int a, int b);
double add(int a, int b); // 編譯錯誤:重定義函數(簽名沖突)

但和 Java 不同的是,C++ 支持函數重載:C++ 的重載機制在編譯和鏈接層處理得很好,不需要額外區分。但 Java 的重載雖然語法上支持,但在調用 native 方法時,需要開發者顯式編碼函數簽名,這讓處理重載略顯麻煩。并不是說 Java 不支持重載,而是說 Java 的重載不天然適用于 native binding,需要額外工作。

void print(int x);
void print(double x);

函數簽名還包括是否為指針、引用、常量等修飾:

void func(int &x); // 引用
void func(const int x); // const 修飾不同參數,簽名不同

5.3 Java 和 C++ 在 JNI 中的函數簽名映射

JNI 中為了讓 Java 調用 C/C++ 函數,會將 Java 方法 簽名映射為 JNI 名字。

public class MyClass {public native void hello(String msg);
}

對應的 C 函數簽名為:

JNIEXPORT void JNICALL Java_MyClass_hello(JNIENV *env, jobject obj, jstring msg);

規則如下:

  • 包名和類名中的 . 替換為 _

  • 方法名拼接在類名后

  • 參數類型在 JNI 中通過 jintjstringjbooleanArray 等類型傳遞

5.4 常見 JNI 簽名編碼表

Java 類型JNI 類型編碼
intI
booleanZ
byteB
charC
shortS
longJ
floatF
doubleD
voidV
ObjectL類名;
int[][I
StringLjava/lang/String;

6. 學習如何傳遞 Java 字符串、數組到 Native ,反之亦然

6.1 Java 與 Native(C/C++)之間的數據傳遞總覽

類型Java -> NativeNative -> Java
Stringjstringconst char*(使用 GetStringUTFChars創建 jstring(用 NewStringUTF
基本類型數組jintArray, jbyteArray 等 → jint*(使用 GetXxxArrayElementsGetXxxArrayRegion創建數組并填充(用 NewXxxArray + SetXxxArrayRegion
對象數組jobjectArray → 單個元素用 GetObjectArrayElement 訪問創建 jobjectArray 并填充每一項
自定義對象傳入 jobject,通過 JNI API 訪問其字段或方法構造 Java 對象并返回

6.2 Java 字符串與 Native 的相互轉換:

  • Java -> Native :獲取 C 字符串:

    extern "C" JNIEXPORT void JNICALL
    Java_com_example_hello_NativeLib_print(JNIEnv* env, jobject thiz, jstring jStr) {const char* cStr = (*env).GetStringUTFChars(jStr, 0);printf("收到字符串: %s\n", cStr);(*env).ReleaseStringUTFChars(jStr, cStr); // 一定要釋放
    }
    
  • Native -> Java :創建 Java 字符串:

    extern "C" JNIEXPORT jstring JNICALL
    Java_com_example_hello_NativeLib_stringFromJNI(JNIEnv* env,jobject thiz /* this */) {jstring result = (*env).NewStringUTF("你好 MainActivity");return result;
    }
    

6.3 Java 數組與 Native 的相互轉換:

  • Java int[] -> Native

    extern "C" JNIEXPORT void JNICALL
    Java_com_example_demo_NativeLib_sum(JNIEnv* env, jobject thiz, jintArray arr) {jsize len = (*env).GetArrayLength(arr);jint* elems = (*env).GetIntArrayElements(arr, NULL);int sum = 0;for (int i = 0; i < len; i++) {sum += elems[i];}printf("總和: %d\n", sum);(*env).ReleaseIntArrayElements(arr, elems, 0); // 0 表示更新 Java 數組
    }
  • Native int[] -> Java int[]

    extern "C" JNIEXPORT jintArray JNICALL
    Java_com_example_demo_NativeLib_getNumbers(JNIEnv *env, jobject) {jint nums[] = {1, 2, 3, 4, 5};jintArray arr = (*env).NewIntArray(5);(*env).SetIntArrayRegion(arr, 0, 5, nums);return arr;
    }
    

在 Native (C/C++) 中使用 printf() 打印日志時,它的輸出位置取決于哪個平臺運行,在 Android 中 printf() 輸出不會自動出現在 Logcat,我們通常看不到它的輸出。

為此我們需要使用 __android_log_print

native-lib.cpp 中添加

#include <android/log.h>#define LOG_TAG "NativeLog"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

將在 Native 中使用 print() 的方法替換成 LOGI() 或者 LOGE() 方法,我們就可以在 Logcat 查看日志了
jintArray arr = (*env).NewIntArray(5);
(*env).SetIntArrayRegion(arr, 0, 5, nums);
return arr;
}

在 Native (C/C++) 中使用 `printf()` 打印日志時,它的輸出位置取決于哪個平臺運行,**在 Android 中 `printf()` 輸出不會自動出現在 Logcat**,我們通常看不到它的輸出。為此我們需要使用 `__android_log_print`在 `native-lib.cpp` 中添加```cpp
#include <android/log.h>#define LOG_TAG "NativeLog"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

將在 Native 中使用 print() 的方法替換成 LOGI() 或者 LOGE() 方法,我們就可以在 Logcat 查看日志了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92199.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

寶塔(免費版9.2.0)的docker拉取倉庫失敗的加速方法

寶塔docker拉取倉庫失敗 完美加速方法_寶塔docker加速-CSDN博客 版本&#xff1a;免費版 9.2.0 https://docker.1ms.run 其他的試了很多 都不行 最后不要用寶塔的控制面板(很卡)&#xff0c;直接在linux中用命令行&#xff0c;效果就很好了。

文獻解讀-生境分析亞區域選擇+2D_DL+3D_DL-局部晚期食管鱗狀細胞癌新輔助化療免疫治療反應預測

研究標題&#xff1a;結合亞區域放射組學與多通道二維或三維深度學習模型預測局部晚期食管鱗狀細胞癌&#xff08;LA-ESCC&#xff09;患者對新輔助化療免疫治療&#xff08;NACI&#xff09;的反應借鑒點&#xff1a;建模思路&#xff08;看流程圖理解就夠了&#xff09;引言食…

機器學習第四課之決策樹

目錄 簡介 一.決策樹算法簡介 二. 決策樹分類原理 1.ID3算法 1.1 熵值 1.2 信息增益 1.3 案例分析 ?編輯 2.C4.5 2.1 信息增益率 2.2.案例分析 3.CART決策樹 3.1基尼值和基尼指數 3.2案例分析 三、決策樹剪枝 四、決策樹API 五、電信客戶流失 六、回歸樹 七. 回歸…

Java面試題和答案大全

一、Java基礎知識 1. Java語言特點 題目: 請說明Java語言的主要特點? 答案: 面向對象:Java是純面向對象的語言,支持封裝、繼承、多態 平臺無關性:一次編譯,到處運行(Write Once, Run Anywhere) 簡單性:語法簡潔,去掉了C++中的指針、多重繼承等復雜特性 安全性:提…

用NAS如何遠程訪問:詳細教程與實用技巧

在信息時代&#xff0c;家用NAS&#xff08;網絡附加存儲&#xff09;成為家庭數據存儲和管理的熱門設備。它不僅可以作為家庭照片、視頻、工作文件的集中存儲中心&#xff0c;還支持遠程訪問&#xff0c;方便用戶隨時隨地獲取數據。那么&#xff0c;如何配置和實現家用NAS的遠…

Qt-桌面寵物

目錄 一&#xff0c;演示&#xff08;部分功能&#xff09; 二&#xff0c;開發環境準備 三&#xff0c;部分代碼實現 1.創建基礎窗口 2.實現寵物動畫 3.添加交互功能 4.系統托盤集成 5.行為模式實現 6.狀態管理系統 7.資源打包部署 四&#xff0c;接受定制 一&…

C++編程學習(第19天)

局部變量和全局變量每一個變量都有其有效作用范圍&#xff0c;這就是變量的作用域&#xff0c;在作用域以外是不能訪問這些變量的。局部變量在一個函數內部定義的變量是局部變量&#xff0c;它只在本函數范圍內有效&#xff0c;也就是說只有在本函數內才能使用他們&#xff0c;…

客流特征識別準確率提升 29%:陌訊多模態融合算法在零售場景的實戰解析

原創聲明本文為原創技術解析文章&#xff0c;涉及的技術參數與架構設計引用自《陌訊技術白皮書》&#xff0c;禁止任何形式的抄襲與轉載。一、行業痛點&#xff1a;零售客流識別的技術瓶頸在零售數字化轉型過程中&#xff0c;客流特征識別&#xff08;包括性別、年齡分層、停留…

YOLOv8/YOLOv11 C++ OpenCV DNN推理

首先需要將yolov8/yolov11的pt文件轉為onnx文件 from ultralytics import YOLO model YOLO("best.pt") model.export(format"onnx",opset11,dynamicFalse) 本次C工具使用vs2017&#xff0c;需要下載OpenCV包&#xff1a;https://opencv.org/releases/&a…

【Mysql】日志--錯誤日志、二進制日志、查詢日志、慢查詢日志

錯誤日志:數據庫出現錯誤時&#xff0c;進行故障排除默認位置&#xff1a;/var/log/mysqld.log查看日志位置show variables like %log_error%查看日志tail -50 /var/log/mysqld.log二進制日志&#xff1a;記錄了所有的DDL語句和DML語句&#xff0c;不包含查詢&#xff08;selec…

后端常用框架環境與軟件詳解

一、基礎運行環境 1. JDK&#xff08;Java Development Kit&#xff09; 定義&#xff1a;Java 開發工具包&#xff0c;包含編譯器、運行時環境&#xff08;JRE&#xff09;及核心類庫 作用&#xff1a;提供 Java 程序開發和運行的基礎環境&#xff0c;是所有 Java 應用的必備依…

本地服務器端部署基于大模型的通用OCR項目——dots.ocr

本地服務器端部署基于大模型的通用OCR項目——dots.ocrdots.ocr相關介紹本地服務器端部署第一步&#xff1a;安裝cuda12.8與CUDNN8.9.7第二步&#xff1a;創建項目所需的依賴環境第三步&#xff1a;啟動項目第四步&#xff1a;測試第五步&#xff1a;文本解析相關性測試第六步&…

Text2SQL 智能問答系統開發-spider驗證集(三)

概述 已完成 基礎 Text2SQL 功能實現 實現用戶輸入自然語言問題后&#xff0c;系統能夠自動生成 SQL 并執行返回結果。用戶交互優化 支持用戶通過補充信息對查詢進行調整&#xff0c;提升易用性。模糊時間處理機制 對“最近”“近期”等模糊時間關鍵詞進行補全或引導&#xf…

ElementUI常用的組件展示

文章目錄1、要使用ElementUI先導入組件庫2、自定義表頭&#xff0c;可以改為添加和批量刪除的按鈕3、Dialog模態框&#xff0c;主要用于添加和修改時展示信息4、抽屜5、消息提示&#xff1a;用于提示是否操作成功6、詢問&#xff1a;常用于詢問是否確定刪除7、批量選擇復選框8、…

在電腦上可以存儲文件并合理備份文件的工具用哪個?

每天被群消息、報表、PPT 輪番轟炸的上班族&#xff0c;最怕的不是加班&#xff0c;而是——文件突然失蹤&#xff01;別再把“CtrlS”當護身符&#xff0c;今天一口氣測完 4 款熱門“文件保險箱”&#xff0c;看看誰才真正配得上你的 Deadline。 敬業簽 首先登場的是敬業簽&am…

JavaWeb(04)

MyBatis 時一款優秀的持久層框架&#xff0c;用于簡化JDBC的開發 The MyBatis Blog 目錄 MyBatis入門Mybatis基礎CRUDMybatis動態SQL Mybatis入門 快速入門 JDBC介紹 數據庫連接池 lombok 準備工作(創建springboot工程&#xff0c;數據庫表user&#xff0c;實體類User) …

統計學1:伯努利模型的參數估計與等價性分析

伯努利模型的參數估計方法 1. 統計學習方法三要素對比方法模型策略算法極大似然估計概率模型經驗風險最小化數值解貝葉斯估計概率模型結構風險最小化解析解2. 極大似然估計 2.1 模型設定 設P(x1)θP(x1)\thetaP(x1)θ&#xff0c;則P(x0)1?θP(x0)1-\thetaP(x0)1?θ 2.2 似然…

游戲行業DDoS攻防實戰指南

一、游戲DDoS攻擊特征分析游戲行業DDoS攻擊呈現高度復合化特征&#xff0c;攻擊手段日益專業化。2023年Akamai監測數據顯示&#xff0c;63%的游戲服務器攻擊采用UDP反射放大&#xff08;如NTP、Memcached協議&#xff09;與HTTP慢速攻擊&#xff08;如Slowloris&#xff09;相結…

[自動化Adapt] 錄制引擎 | iframe 穿透 | NTP | AIOSQLite | 數據分片

鏈接&#xff1a;https://github.com/OpenAdaptAI/OpenAdapt/wiki/OpenAdapt-Architecture-(draft) docs&#xff1a;OpenAdapt OpenAdapt 是一個開源項目&#xff0c;旨在 記錄 和 回放 用戶在計算機上的交互行為。 它如同智能助手般 觀察 我們的操作&#xff08;鼠標點擊、…

ipv6學習

ipv6的歷史背景和及展望ipv6普及不夠&#xff0c;ipv4快要用完。ipv6技術部分ivp6包頭結構ipv6不允許分片&#xff0c;減輕中間設備壓力。IPv6 包頭結構可按字段分層解析&#xff0c;核心特點是 固定頭部長度&#xff08;40 字節&#xff09; &#xff0c;將可選功能移至擴展頭…