adb命令 - adb forward交互流程
命令:
adb forward tcp:6100 tcp:7100 // PC上所有6100端口通信數(shù)據(jù)將被重定向到手機端7100端口server上
或者
adb forward tcp:6100 local:logd // PC上所有6100端口通信數(shù)據(jù)將被重定向到手機端UNIX類型socket上
通過adb forward我們可以接收手機端server[或者unix域socket]程序發(fā)出的所有數(shù)據(jù),
并且可以用自己寫的小程序向手機端server[或者unix域socket]發(fā)送我們自己的數(shù)據(jù)[luther.gliethttp]
表示在PC的HOST端創(chuàng)建一個server監(jiān)聽6100端口,pc上的其它應用程序,比如:A,可以以client身份和6100端口server建立連接,
之后A發(fā)送的所有數(shù)據(jù)將透明傳遞到手機端監(jiān)聽7100端口的一個應用程序,比如瀏覽器程序[luter.gliethttp].
代碼流程如下:
1.在pc上執(zhí)行adb forward tcp:6100 tcp:7100指令,該指令嘗試連接5037端口,觸發(fā)HOST回調函數(shù)ss_listener_event_func執(zhí)行.
2.ss_listener_event_func將為該次連接創(chuàng)建一個local_socket,之后等待該local_socket數(shù)據(jù)[luther.gliethttp],
3.當local_socket數(shù)據(jù),即"host:forward:tcp:6100;tcp:7100",到來之后,將執(zhí)行l(wèi)ocal_socket_event_func回調函數(shù),讀取數(shù)據(jù)之后交由smart_socket_enqueue==>handle_host_request
4.handle_host_request==>install_listener("tcp:6100", "tcp:7100", transport);
創(chuàng)建server監(jiān)聽端口socket_loopback_server(6100, SOCK_STREAM);當有客戶端連接該端口是執(zhí)行l(wèi)istener_event_func回調函數(shù)
5.現(xiàn)在pc上我們寫了一個自己的小應用程序B,和6100端口的server建立連接,于是HOST上的listener_event_func回調函數(shù)執(zhí)行.
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); // 發(fā)送"tcp:7100"到手機端,手機端將建立一個與7100端口server鏈接的gliethttp_client,作為
// 與HOST這里建立的gliethttp_server對象進行數(shù)據(jù)傳輸?shù)氖謾C端程序[luther.gliethttp]
// 如果成功連接之后,手機端adbd將返回"OKAY",進而gliethttp_server和gliethttp_client將綁定在一起
// gliethttp_server發(fā)送的數(shù)據(jù)將通過HOST的daemon直接傳遞給gliethttp_client
// gliethttp_client數(shù)據(jù)將通過手機的adbd直接發(fā)送給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線程將接收到的數(shù)據(jù)傳遞給t->transport_socket句柄,該句柄將調用transport_socket_events==>handle_packet
回調函數(shù)進一步處理我們的"tcp:7100"命令.
handle_packet==>
gliethttp_client = create_local_service_socket("tcp:7100");創(chuàng)建維護對象gliethttp_client,
進一步執(zhí)行socket_loopback_client("7100", SOCK_STREAM);嘗試打開手機端的7100端口(這時手機端應該已經(jīng)打開監(jiān)聽7100端口的server程序)[luther.gliethttp].
之后create_remote_socket(p->msg.arg0, t);表示gliethttp_client從手機端7100端口server上接收到的數(shù)據(jù)將全部傳遞給
HOST端的gliethttp_server端口,進而傳遞給我們的小程序B[luther.gliethttp].