主頁 >  其他 > 淺談IPC|Binder

淺談IPC|Binder

2020-09-13 11:08:06 其他

前言

  • IPC是什么?
  • 為什么要學IPC
  • 怎么進行IPC

下面是我這篇博文的學習腦圖,方便讀者更快的找到自己想要了解的知識點,

一、IPC簡介

1.1什么是IPC

IPC是Inter-Process Communication的縮寫,含義為行程間通信或者跨行程通信,是指兩個行程之間進行資料交換的程序

看到這里,需要先了解一下行程、執行緒以及它們的關系,

  • 行程:一般指一個執行單元,在PC和移動設備上指一個程式應用

  • 執行緒:CPU調度的最小單元,執行緒是一種有限的系統資源,

    二者之間的關系:

    一個行程可包含多個執行緒,即一個應用程式上可以同時執行多個任務,

    注意:不可在主執行緒做大量耗時操作,會導致ANR(應用無回應),

IPC不是Android中所獨有的,任何一個作業系統都需要有相應的IPC機制,Binder是Android中最有特色的行程間通信方式,

1.2為什么要進行IPC

行程間通信的必要性

? 所有運行在不同行程的四大組件,只要它們之間需要通過記憶體在共享資料,都會共享失敗,這是由于Android為每個應用分配了獨立的虛擬機,不同的虛擬機在記憶體分配上有不同的地址空間,這會導致在不同的虛擬機中訪問同一個類的物件會產生多份副本,

1.3怎么進行IPC

使用Bundle、檔案共享、MessengerAIDLContentProvider、Socket,

二、Android 中的多行程模式

2.1開啟行程

  • (常規)在AndroidMenifest中給四大組件指定屬性android:process
  • (不常規)通過JNI在native層fork一個新的行程,

行程名的默認規則:

默認行程:

  • 沒有指定該屬性則運行在默認行程,其行程名就是包名

以“:”開頭的行程:

  • 省略包名,如android:process=":remote",表示行程名為com.example.myapplication:remote
  • 屬于當前應用的私有行程,其他行程的組件不能和他跑在同一行程中,

完整命名的行程:

  • android:process="com.example.myapplication.remote"
  • 屬于全域行程,其他應用可以通過**ShareUID**方式和他跑在用一個行程中,

UID: Android系統會為每個應用分配一個唯一的UID,具有相同的UID才能共享資料,

兩個應用通過ShareUID跑在同一個行程中的條件:具有相同的ShareUID和簽名,

  • 滿足上述條件的兩個應用,無論是否跑在同一行程,它們可共享data目錄,組件資訊,
  • 若跑在同一行程,它們除了可共享data目錄、組件資訊,還可共享記憶體資料,它們就像是一個應用的兩個部分,

2.2多行程的運行機制

Android為每一個行程分配了一個獨立的虛擬機,不同虛擬機在記憶體分配上有不同的地址空間,這也導致了不同虛擬機中訪問同一個物件會產生多份副本

一般來說使用多行程會帶來以下四個方面的問題:

  • 靜態變數和單例模式失效 原因:不同虛擬機中訪問同一個物件會產生多份副本

  • 執行緒同步機制失效 原因:記憶體不同,執行緒無法同步,

  • SharedPreference的可靠性下降 原因:底層是通過讀寫XML檔案實作的,發生并發問題,

  • Application多次創建- 原因:Android系統會為新的行程分配獨立虛擬機,相當于應用重新啟動了一次,

為了解決這些問題,可以采用跨行程通信方法,通過Intent,共享檔案和SharedPreferencesMessengerAIDLSocket等,

三、IPC基礎概念

在了解以下三種介面使用前,需要先了解一下什么是序列化和反序列化,

1.什么是序列化?

含義:序列化表示將一個物件轉換成可存盤或可傳輸的狀態,序列化后的物件可以在網路上進行傳輸,也可以存盤到本地,

場景:需要通過IntentBinder等傳輸類物件就必須完成物件的序列化程序,

兩種方式:實作Serializable/Parcelable介面,

2.什么是反序列化?

把位元組序列恢復為物件的程序稱為物件的反序列化,與序列化相反,

3.1 Serializable介面

Serializable是Java所提供的一個序列化介面,是一個空介面,為物件提供標準的序列化和反序列化操作,

  • 用法:物體類實作Serializable介面,宣告serialVesionUID

  • 注意:serialVesionUID非必需,但是不宣告會對反序列化有影響,

? serialVesionUID與當前類的serialVesionUID相同才能被正常反序列化,

? serialVesionUID可以系統配置/手動修改,

代碼示例:

//User物體類實作Serializable介面;
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    public int UserId;
    public String userName;
    public boolean isMale;

    public User(int userId, String userName, boolean isMale) {
        UserId = userId;
        this.userName = userName;
        this.isMale = isMale;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public int getUserId() {
        return UserId;
    }

    public void setUserId(int userId) {
        UserId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public boolean isMale() {
        return isMale;
    }

    public void setMale(boolean male) {
        isMale = male;
    }
}
 //序列化程序
    User user = new User(1,"Yuki",true);
    ObjectOutputStream outputStream;

    {
        try {
            outputStream = new ObjectOutputStream(new FileOutputStream("cache.txt"));
    //反序列化程序
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));

            User newUser = (User)in.readObject();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

3.2 Parcelable介面

用法:

  • 物體類實作Parcelable介面

  • 內容描述

  • 序列化

  • 反序列化

代碼示例:

//User物體類實作Parcelable;
public class User implements Parcelable {
    public int UserId;
    public String userName;
    public boolean isMale;
//    public Book book;

    public User(int userId, String userName, boolean isMale) {
        UserId = userId;
        this.userName = userName;
        this.isMale = isMale;
    }

    protected User(Parcel in) {
        UserId = in.readInt();
        userName = in.readString();
        isMale = in.readByte() != 0;
//        book = in.readParcelable(Thread.currentThread().getContextClassLoader());
    }
    

    //反序列化
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };




    public int getUserId() {
        return UserId;
    }

    public void setUserId(int userId) {
        UserId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public boolean isMale() {
        return isMale;
    }

    public void setMale(boolean male) {
        isMale = male;
    }
    //內容描述
    @Override
    public int describeContents() {
        return 0;
    }
    //序列化
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(UserId);
        dest.writeString(userName);
        dest.writeByte((byte) (isMale ? 1 : 0));
//        dest.writeParcelable(book,0);

    }
}

Parcelable方法說明

方法功能標記位
createFromParcel(Parcel in)從序列化后的物件中創建原始物件
newArray(int size)創建指定長度的原始物件陣列
writeToParcel(Parcel dest, int flags)將當前物件寫入序列化結構中,其中flags標識有兩種值:0或者1,為1時標識當前物件需要作為回傳值回傳,不能立即釋放資源,幾乎所有的情況都為0PARCELABLE_WRITE_RETURN_VALUE
User(Parcel in)從序列化后的物件中創建原始物件
describeContents回傳當前物件的內容描述,如果含有檔案描述符,回傳1,否則回傳0,幾乎所有的情況都回傳0CONTENTS_FILE_DESCRIPTOR

SerializableParcelable比較

SerializableParcelable
Java序列化介面Android序列化介面
使用簡單使用較麻煩
效率低效率高

3.3 Binder

3.3.1 Binder是什么?

  • 直觀上:Android 的一個類,實作了IBinder介面,
  • **IPC 角度:Android中的一種跨行程通信**,
  • 實作方式角度:一種虛擬的物理設備,
  • Android Framework角度::ServiceManager連接各種ManagerActivityManagerWindowManager等)的橋梁,
  • Android應用層角度:客戶端和服務端進行通信的媒介,

3.3.2 為什么是Binder?

Android系統是基于Linux內核的,Linux已經提供了管道、訊息佇列、記憶體共享和SocketIPC機制,為什么Android還要提供Binder來實作IPC

優勢描述
性能只需要一次資料拷貝,性能上僅次于共享記憶體
穩定性基于C/S架構,職責明確,架構清晰,穩定性好
安全性為每個APP分配UID,行程的UID事鑒別行程身份的重要標志

3.3.3 Binder IPC底層通信原理

3.3.3.1.其他IPC機制完成一次行程間通信是怎么樣的?

? 在不同的行程之間,訊息發送方將要發送的資料存放在記憶體快取區中,通過系統呼叫進入內核態,然后內核程式在內核空間分配記憶體,開辟一塊內核快取區,呼叫 copy*from*user() 函式將資料從用戶空間的記憶體快取區拷貝到內核空間的內核快取區中,同樣的,接收方行程在接收資料時在自己的用戶空間開辟一塊記憶體快取區,然后內核程式呼叫 copy*to*user() 函式將資料從內核快取區拷貝到接收行程的記憶體快取區,

3.3.3.2 Binder IPC完成一次行程間通信又是怎么樣的?
  1. 首先 Binder 驅動在內核空間創建一個資料接收快取區;
  2. 接著在內核空間開辟一塊內核快取區,建立內核快取區內核中資料接收快取區之間的映射關系,以及內核中資料接收快取區接收行程用戶空間地址的映射關系;
  3. 發送方行程通過系統呼叫 copy*from*user() 將資料 copy 到內核中的內核快取區,由于內核快取區和接收行程的用戶空間存在記憶體映射,因此也就相當于把資料發送到了接收行程的用戶空間,這樣便完成了一次行程間的通信,

各種IPC方式資料拷貝次數

IPC資料拷貝次數
共享記憶體0
Binder1
訊息佇列/管道/Socket2

3.3.4 Binder通信程序

Binder框架定義了四個角色:ServerClientServiceManager以及Binder驅動,其中ServerClientServiceManager運行于用戶空間,驅動運行于內核空間,這四個角色的關系和互聯網類似:Server是服務器,Client是客戶終端,ServiceManager是域名服務器(DNS),驅動是路由器,

  1. 首先,一個行程使用 BINDER*SET*CONTEXT_MGR 命令通過 Binder 驅動將自己注冊成為 ServiceManager

  2. Server 通過驅動向 ServiceManager 中注冊 BinderServer 中的 Binder 物體),表明可以對外提供服務,驅動為這個 Binder 創建位于內核中的物體節點以及 ServiceManager 對物體的參考,將名字以及新建的參考打包傳給 ServiceManagerServiceManger 將其填入查找表,

  3. Client 通過名字,在 Binder 驅動的幫助下從 ServiceManager 中獲取到對 Binder 物體的參考,通過這個參考就能實作和 Server 行程的通信,

    這里參考自:寫給 Android 應用工程師的 Binder 原理剖析

問:當服務端行程例外終止的話,造成Binder死亡的話,怎么辦?

在客戶端系結遠程服務成功后,給Binder設定死亡代理,當Binder死亡的時候,我們會收到通知,從而重新發起連接請求,

private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient(){
@Override
public void binderDied(){
if(mBookManager == null){
return;
}
mBookManager.asBinder().unlinkToDeath(mDeathRecipient,0);
mBookManager = null;
// TODO:這里重新系結遠程Service
}
}
mService = IBookManager.Stub.asInterface(binder);
binder.linkToDeath(mDeathRecipient,0);

四、Android中的IPC模式

4.1 Bundle

概念:由于Bundle實作了Parcelable介面,可以方便的在不同行程間傳輸,

  • 范圍:ActivityServiceReceiver間傳遞,
  • 使用:通過Intent發送,

擴展使用:A行程要啟動B行程并把在A行程計算完的資料傳遞給B行程,如何把不支持Bundle的資料由A行程傳入B中?

答:將原本在A行程的計算任務轉移到B行程的后臺Service中去執行,通過Intent啟動B行程的一個Service,讓計算任務在Service完成,計算完成 后再去啟動目標組件,并把資料傳遞給目標組件,

4.2 檔案共享

概念:兩個行程通過讀/寫同一個檔案來交換資料,

  • 檔案范圍:對檔案格式沒有具體要求,
  • 局限性:并發讀/寫,

4.3 Messenger

概念:可以在不同行程中傳遞Message物件,把需要傳遞的資料放進物件中,

  • 底層實作:輕量級的 IPC 方案,它的底層實作是 AIDL

  • 實作Message

1.服務端行程

  • 創建一個Service處理客戶端連接請求
  • 創建一個Handle并通過它創建一個Messenger物件
  • ServiceonBind回傳這個物件的底層Binder

2.客戶端行程

  • 系結服務端的Service
  • 用服務端回傳的IBinder物件創建一個Messenger(客戶端——>服務端)
  • 在客戶端創建一個Handler并由此創建一個Messenger,并通過Message的**replyTo欄位**傳遞給服務器端行程,服務端通過讀取Message得到Messenger物件,進而向客戶端行程傳遞資料,(客戶端 <——>服務端)
//Messenger 服務端代碼
public class MessengerService extends Service {
    private static final String TAG = "MessengerService";
    private final Messenger messenger = new Messenger(new MessengerHandler());
    //處理客戶端發送的訊息
    private static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                   case 1:
                    Log.i("TAG"," "+msg.getData().getString("msg"));
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    }
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();    //回傳它的Binder物件
    }
}
 <service android:name=".MessengerService"
            android:process=":remote"/>   //注冊Service
//客戶端代碼
public class MessengerActivity extends AppCompatActivity {

    private Messenger mService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //系結服務
        Intent intent = new Intent(this,MessengerService.class);
        bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service); //用服務端回傳的IBinder物件創建一個Messenger物件
            Message msg = Message.obtain(null,1);
            Bundle data = new Bundle();
            data.putString("msg","Client");
            msg.setData(data);
            try {
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        unbindService(mConnection);
        super.onDestroy();
    }
}

4.4 使用AIDL

AIDLAndroid Interface Definition Language 的縮寫,意思是Android介面定義語言,用于讓某個Service與多個應用程式組件之間進行跨行程通信,從而可以實作多個應用程式共享同一個Service的功能,其使用可以簡單的概括為服務端和客戶端,類似于Socket 一樣,服務端服務于所有客戶端,支持一對多服務,

4.4.1 MessengerAIDL比較

Messenger缺點:串行方式處理訊息,無法并發處理,

AIDL:可以并發處理請求,

AIDL通信流程

  • 服務端
  • 創建Service監聽客戶端請求
  • 創建AIDL檔案
  • AIDL檔案中申明暴露給客戶端的介面
  • Service實作這個AIDL介面
  • 客戶端
  • 系結服務端的Service
  • 將服務端回傳的Binder物件轉成AIDL介面所屬的型別
  • 呼叫AIDL方法

4.4.2AIDL能夠支持哪些資料型別?

注意:除了基本資料型別,其它型別的引數必須標上方向:in、out或inout,用于表示在跨行程通信中資料的流向,

4.4.3 關鍵類和關鍵方法

  • AIDL介面:繼承IInterface
  • StubBinder的實作類,服務端通過這個類來提供服務,
  • Proxy:服務器的本地代理,客戶端通過這個類呼叫服務器的方法,
  • asInterface():客戶端呼叫,將服務端的回傳的Binder物件,轉換成客戶端所需要的AIDL介面型別物件,

回傳物件:

  • 若客戶端和服務端位于同一行程,則直接回傳Stub物件本身;
  • 否則,回傳的是系統封裝后的Stub.proxy物件,
  • asBinder():回傳代理ProxyBinder物件,
  • onTransact():運行服務端的Binder執行緒池中,當客戶端發起跨行程請求時,遠程請求會通過系統底層封裝后交由此方法來處理,
  • transact():運行在客戶端,當客戶端發起遠程請求的同時將當前執行緒掛起,之后呼叫服務端的onTransact()直到遠程請求回傳,當前執行緒才繼續執行,

4.4.4 產生ANR的情形

  • 客戶端:

    • 呼叫服務端的方法是運行在服務端的Binder執行緒池中,若主執行緒所呼叫的方法里執行了較耗時的任務,同時會導致客戶端執行緒長時間阻塞,易導致客戶端ANR
    • onServiceConnected()onServiceDisconnected()里直接呼叫服務端的耗時方法,易導致客戶端ANR
  • 服務端:

    • 服務端的方法本身就運行在服務端的**Binder執行緒中,可在其中執行耗時操作,而無需再開啟子執行緒**,
    • 回呼客戶端Listener的方法是運行在客戶端的Binder執行緒中,若所呼叫的方法里執行了較耗時的任務,易導致服務端ANR

解決客戶端頻繁呼叫服務器方法導致性能極大損耗的辦法:實作觀察者模式

即當客戶端關注的資料發生變化時,再讓服務端通知客戶端去做相應的業務處理,

4.4.5解注冊失敗的問題

  • 原因: Binder進行物件傳輸實際是通過序列化和反序列化進行,即Binder會把客戶端傳遞過來的物件重新轉化并生成一個新的物件,雖然在注冊和解注冊的程序中使用的是同一個客戶端傳遞的物件,但經過Binder傳到服務端后會生成兩個不同的物件,另外,多次跨行程傳輸的同一個客戶端物件會在服務端生成不同的物件,但它們在底層的Binder物件是相同的,
  • 解決辦法:當客戶端解注冊的時候,遍歷服務端所有的Listener,找到和解注冊Listener具有相同的Binder物件的服務端Listener,刪掉即可,

需要用到RemoteCallBackListAndroid系統專門提供的用于洗掉跨行程listener的介面,其內部自動實作了執行緒同步的功能,

4.5 使用ContentProvider

4.5.1 什么是ContentProvider

ContentProviderAndroid中提供的專門用于不同應用間進行資料共享的方法,它天生就適合行程間通信,

4.5.2 如何自定義一個ContentProvider

  • 用一個物體類繼承ContentProvider
  • 實作onCreatequeryupdateinsertdeletegetType等六種抽象方法,、

注意:

除了onCreate()運行在UI執行緒中,其他的query()update()insert()delete()getType()都運行在Binder執行緒池中,

CRUD四大操作存在多執行緒并發訪問,要注意在方法內部要做好執行緒同步,

一個SQLiteDatabase內部對資料庫的操作有同步處理,但多個SQLiteDatabase之間無法同步,

4.6 使用Socket

4.6.1 什么是Socket

Socket也稱為“套接字”,是網路通信的概念,分為流式套接字和用戶資料報套接字兩種,

  • 流套接字:基于TCP協議,采用流的方式提供可靠的位元組流服務,
  • 資料流套接字:基于UDP協議,采用資料報文提供資料打包發送的服務,

4.6.2 怎么實作Socket通信?

  • 服務端:

    • 創建一個Service,在執行緒中建立TCP服務、監聽相應的埠等待客戶端連接請求;
    • 與客戶端連接時,會生成新的Socket物件,利用它可與客戶端進行資料傳輸;
    • 與客戶端斷開連接時,關閉相應的Socket并結束執行緒,
  • 客戶端:

    • 開啟一個執行緒、通過Socket發出連接請求;
    • 連接成功后,讀取服務端訊息;
    • 斷開連接,關閉Socket

五、IPC方式

各種IPC方式的優缺點比較:

名稱優點缺點適用場景
Bundle簡單易用只能傳輸Bundle支持的資料型別四大組件間的行程間通信
檔案共享簡單易用不適合高并發場景,無法做到行程間的即時通信無并發訪問,交換簡單資料且實時性不高
AIDL支持一對多并發和實時通信使用稍復雜,需要處理執行緒同步一對多且有RPC需求
Messenger支持一對多串行通信不能很好處理高并發,不支持RPC,只能傳輸Bundle支持的資料型別低并發的一對多
ContentProvider支持一對多并發資料共享可理解為受約束的AIDL一對多行程間資料共享
Socket支持一對多并發資料共享實作細節繁瑣網路資料交換

六、Binder連接池

6.1 典型的AIDL使用流程

  • 創建一個Service和一個AIDL介面
  • 創建一個類繼承自AIDL介面中的Stub類并實作Stub中的抽象方法
  • 在Service的onBind方法中回傳這個類的物件

6.2 當有多個不同的業務需要使用AIDL來進行通信,該怎么處理?

可以將所有的AIDL放在同一個Service中去管理,它的作業機制是這樣的:

每個業務模塊創建自己的AIDL介面,向服務端提供自己的唯一標識和對應的Binder物件,對服務端來說,只需一個Service,服務端提供一個queryBinder介面,可以根據業務模塊特征回傳相應的Binder物件,Binder連接池的主要作用就是將每個業務模塊的Binder請求統一轉發到遠程Service去執行,避免重復創建Service

實作方式:

  • 為每個業務模塊創建AIDL介面并具體實作,
  • Binder連接池創建AIDL介面IBinderPool.aidl并具體實作,
  • 遠程服務BinderPoolService的實作,在onBind()回傳實體化的IBinderPool實作類物件,
  • Binder連接池的具體實作,來系結遠程服務,
  • 客戶端的呼叫,

本文參考:

  • 寫給 Android 應用工程師的 Binder 原理剖析

  • 《Android開發藝術探索》

  • 進階之路 | 奇妙的 IPC 之旅

  • Android Bander設計與實作 - 設計篇

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/23885.html

標籤:其他

上一篇:導航系統

下一篇:開發微信小游戲用什么游戲引擎好

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more