命令: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_request4.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].
