簡析adb的端口映射功能,將PC端的某端口數據重定向到手機端的一個端口 編程
================================================ 網絡
曾經覺得adb forward是個好東東,由於經過這個映射以後,在PC和設備之間就能夠直接socket通訊了。可如今終於發現,世界不是完美的。 socket
Android Debug Bridge設計的目的,一是用來管理全部鏈接的設備;二是提供各類服務,供PC端有效的控制設備。主要包括三個部分: spa
1) ADB-server 設計
運行在PC端,是一個始終在後臺運行的進程,做爲與手機端交互的惟一接口。ADB-server處理ADB-client的請求,一部分請求無須與 設備交互,直接在PC本地完成;剩下的請求須要與設備端的adbd交互,ADB-server起到了一個switcher的做用。 server
2) ADB-client 接口
運行在PC端,能夠同時存在多個。每一個ADB-client由用戶啓動,完成多種功能。其做用是與ADB-server交互,實現用戶請求的功能。 進程
3) adbd 網絡編程
運行在設備端的常駐進程,同時只存在一個。做用是接收PC端的ADB-server發來的請求,並做出對應操做。 it
這三個可執行程序都是同一套代碼編譯出來的,位於<Android Source Dir>/system/core/adb/
ADB-client和ADB-server對應同一個可執行文件「adb(.exe)」,編譯時有-DADB_HOST=1宏。而adbd對應目 標設備上的可執行文件"adbd",編譯時的參數是-DADB_HOST=0。
. P C Device
-------------------------------------- -------------------------------------
[ADB-client]<----->[Port A:] [:Port A']<------>[Program A]
[ADB-client]<----->[Port B:]ADB-server<----->adbd[:Port B']<------>[Program B]
[ADB-client]<----->[Port C:] [:Port C']---------(empty)
. |<--------Android Debug Bridge---------->|
(這個圖實在是調很差了,無論了)
ADB提供了PC與設備交互的橋樑,結構上清晰明瞭。其中adb forward功能提供了端口映射,但願給用戶提供透明的socket通訊。但惋惜,這與真實的網絡socket有點區別。
在TCP網絡編程中,Client的Socket(C)若是調用Connect()成功,就說明已經和Server端的Socket(S)鏈接上, 能夠通信了。可是若是使用adb forward作端口映射,就不同了。端口映射的實質是,讓ADB-server做爲一個switcher轉發ADB-client的數據包,送給 adbd,adbd再發給設備端的對應端口。所以一旦創建了映射,就至關於ADB-server開始監聽這個目標端口。而此時若是有C去嘗試 Connect這個端口,是必定會成功的,由於與C鏈接的是ADB-server,而非真正的設備上的目標程序。這就出現了,即便Connect()成 功,卻徹底沒法知道到底是否成功鏈接到S。
所以,判斷真正鏈接成功的方法,只有輪詢收發握手數據包。程序中約定好事先作個交互:C發送一個數據包,等待S回覆;C若是收到了S的回覆包,說明 連通;若是接收超時,則認爲沒有連通。在沒有連通的狀況下,須要從新創建Socket,並Connect(),而後再嘗試握手。