命令:
adb forward tcp
:
6100 tcp
:
7100
// PC
上所有6100端口通信數據將被重定向到手機端7100端口server上
或者
adb forward tcp
:
6100 local
:
logd
//
PC
上所有6100端口通信數據將被重定向到手機端UNIX類型socket上
通過adb forward我們可以接收手機端server
[
或者unix域socket
]
程序發出的所有數據
,
並且可以用自己寫的小程序向手機端server
[
或者unix域socket
]
發送我們自己的數據
[
luther
.
gliethttp
]
表示在PC的HOST端創建一個server監聽6100端口
,
pc
上的其它應用程序
,
比如
:
A
,
可以以client身份和6100端口server建立連接
,
之后A發送的所有數據將透明傳遞到手機端監聽7100端口的一個應用程序
,
比如瀏覽器程序
[
luter
.
gliethttp
].
代碼流程如下:
1
.
在pc上執行adb forward tcp
:
6100 tcp
:
7100
指令
,
該指令嘗試連接5037端口
,
觸發HOST回調函數ss_listener_event_func執行
.
2
.
ss_listener_event_func
將為該次連接創建一個local_socket
,
之后等待該local_socket數據
[
luther
.
gliethttp
],
3
.
當local_socket數據
,
即
"host:forward:tcp:6100;tcp:7100"
,
到來之后
,
將執行local_socket_event_func回調函數
,
讀取數據之后交由smart_socket_enqueue
==>
handle_host_request
4
.
handle_host_request
==>
install_listener
(
"tcp:6100"
,
"tcp:7100"
,
transport
);
創建server監聽端口socket_loopback_server
(
6100
,
SOCK_STREAM
);
當有客戶端連接該端口是執行listener_event_func回調函數
5
.
現在pc上我們寫了一個自己的小應用程序B
,
和6100端口的server建立連接
,
於是HOST上的listener_event_func回調函數執行
.
static
void
listener_event_func
(
int
_fd
,
unsigned
ev
,
void
*
_l
)
{
alistener
*
l
=
_l
;
asocket
*
s
;
if
(
ev
&
FDE_READ
)
{
struct
sockaddr
addr
;
socklen_t
alen
;
int
fd
;
alen
=
sizeof
(
addr
);
fd
=
adb_socket_accept
(
_fd
,
&
addr
,
&
alen
);
//
首先接受該連接
if
(
fd
<
0
)
return
;
gliethttp_server
=
create_local_socket
(
fd
);
//
為我們的小應用程序建立維護對象gliethttp_server
if
(
gliethttp_server
)
{
gliethttp_server
->
transport
=
l
->
transport
;
connect_to_remote
(
gliethttp_server
,
l
->
connect_to
);
//
發送"tcp:7100"到手機端,手機端將建立一個與7100端口server鏈接的gliethttp_client,作為
//
與HOST這里建立的gliethttp_server對象進行數據傳輸的手機端程序[luther.gliethttp]
//
如果成功連接之后,手機端adbd將返回"OKAY",進而gliethttp_server和gliethttp_client將綁定在一起
// gliethttp_server
發送的數據將通過HOST的daemon直接傳遞給gliethttp_client
// gliethttp_client
數據將通過手機的adbd直接發送給HOST的gliethttp_server,然后傳遞給我們的小程序B[lutehr.gliethttp]
return
;
}
adb_close
(
fd
);
}
}
void
connect_to_remote
(
asocket
*
s
,
const
char
*
destination
)
{
D
(
"Connect_to_remote call /n"
);
apacket
*
p
=
get_apacket
();
int
len
=
strlen
(
destination
)
+
1
;
if
(
len
>
(
MAX_PAYLOAD
-
1
))
{
fatal
(
"destination oversized"
);
}
D
(
"LS(%d): connect('%s')/n"
,
s
->
id
,
destination
);
p
->
msg
.
command
=
A_OPEN
;
//
打開手機端"tcp:7100"端口
p
->
msg
.
arg0
=
s
->
id
;
p
->
msg
.
data_length
=
len
;
strcpy
((
char
*)
p
->
data
,
destination
);
send_packet
(
p
,
s
->
transport
);
}
在手機端
output_thread
線程將接收到的數據傳遞給t
->
transport_socket
句柄
,
該句柄將調用transport_socket_events
==>
handle_packet
回調函數進一步處理我們的
"tcp:7100"
命令
.
handle_packet
==>
gliethttp_client
=
create_local_service_socket
(
"tcp:7100"
);
創建維護對象gliethttp_client
,
進一步執行socket_loopback_client
(
"7100"
,
SOCK_STREAM
);
嘗試打開手機端的7100端口
(
這時手機端應該已經打開監聽7100端口的server程序
)[
luther
.
gliethttp
].
之后create_remote_socket
(
p
->
msg
.
arg0
,
t
);
表示gliethttp_client從手機端7100端口server上接收到的數據將全部傳遞給
HOST
端的gliethttp_server端口
,
進而傳遞給我們的小程序B
[
luther
.
gliethttp
].