Multiple adb connections over WiFi
来源:互联网 发布:node.js搭建 编辑:程序博客网 时间:2024/05/17 04:06
先放问题和解决方案吧。
问题:
We are two people and want to connect to a android devicefrom each respective notebook. When one person is connected, the other person gets a device is offline error.android device from multiple machines?
在stackoverflow上找到我的问题multiple-adb-connections-over-wifi,却没找到我需要的答案。
简单点描述就是我有多部电脑,希望通过adb tcpip连接到一部手机上,多部电脑连接的时候,发现只有一部电脑是可以操作手机的,其他电脑都是显示offline
解决方案
(系统级别的解决方案:直接修改android系统)
diff --git a/system/core/adb/transport.cpp b/system/core/adb/transport.cppindex 7350192527..8fe2e5a317 100644--- a/system/core/adb/transport.cpp+++ b/system/core/adb/transport.cpp@@ -938,7 +938,7 @@ int register_socket_transport(int s, const char *serial, int port, int local) return -1; } }-+ #if ADB_HOST for (n = transport_list.next; n != &transport_list; n = n->next) { if (n->serial && !strcmp(serial, n->serial)) { adb_mutex_unlock(&transport_lock);@@ -946,6 +946,7 @@ int register_socket_transport(int s, const char *serial, int port, int local) return -1; } }+ #endif // ADB_HOST t->next = &pending_list; t->prev = pending_list.prev;
解决过程和方法
昨天编译了系统,顺利在VirtualBox上跑了起来,今天都在看adb部分的代码,代码目录是:
/system/core/adb
代码不多,就十几个文件。先是看了网上的一些分析,知道有 adbd
adb(HOST)
。 adbd
就是在手机上运行的守护程序,adb(HOST)
就是在电脑上跑的adb服务端。一开始看了好久的分析,还是有点云里雾里的,后来想了一下,反正系统在我手里,边看日志边改吧。
开启日志
adb_trace.h
打日志就是这一段代码了
# define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0)/* you must define TRACE_TAG before using this macro */#if ADB_HOST# define D(...) \ do { \ if (ADB_TRACING) { \ int save_errno = errno; \ adb_mutex_lock(&D_lock); \ fprintf(stderr, "%16s: %5d:%5lu | ", \ __FUNCTION__, \ getpid(), adb_thread_id()); \ errno = save_errno; \ fprintf(stderr, __VA_ARGS__ ); \ fflush(stderr); \ adb_mutex_unlock(&D_lock); \ errno = save_errno; \ } \ } while (0)# define DR(...) \ do { \ if (ADB_TRACING) { \ int save_errno = errno; \ adb_mutex_lock(&D_lock); \ errno = save_errno; \ fprintf(stderr, __VA_ARGS__ ); \ fflush(stderr); \ adb_mutex_unlock(&D_lock); \ errno = save_errno; \ } \ } while (0)#else# define D(...) \ do { \ if (ADB_TRACING) { \ __android_log_print( \ ANDROID_LOG_INFO, \ __FUNCTION__, \ __VA_ARGS__ ); \ } \ } while (0)# define DR(...) \ do { \ if (ADB_TRACING) { \ __android_log_print( \ ANDROID_LOG_INFO, \ __FUNCTION__, \ __VA_ARGS__ ); \ } \ } while (0)#endif /* ADB_HOST */
调试阶段,我直接把:
define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
改成了
define ADB_TRACING 1 // ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
然后在系统上装个 Terminal
的应用,打开teriminal
输入 su
,拿到root权限
之后输入 logcat
,然后就能看到日志打出来了。
切换到编译出来的out目录下,找到adb,用编译出来的adb作为服务端进行连接(即 ./adb connect 192.168.0.151
)
再换另外一部电脑进行adb connect 192.168.0.151
然后发现执行adb devices
手机terminal
上没有log出来,所以adb devices
应该是本地操作,所以手机知道device offline 是在connect的时候就知道了的,看了下协议,才知道offline就是socket连接不上,电脑本地的报错信息,和手机端一点关系都没有。
顺带说一下adb的通讯协议,在
system/core/adb/protocol.txt
好长,不贴了,和我之前写长连接的东西好像,长连接那个我们是先定义了包结构,然后一开始匿名通讯,然后拿到密钥之后就开始加密通讯,看了下,adb 也是直接用tcp socket. 传输的,感觉亲切了不少。
然后对比了一下connect成功和connect失败的日志
成功的日志
失败的日志
找到对应的代码区域
int register_socket_transport(int s, const char *serial, int port, int local){ atransport *t = reinterpret_cast<atransport*>(calloc(1, sizeof(atransport))); if (t == nullptr) { return -1; } atransport *n; char buff[32]; if (!serial) { snprintf(buff, sizeof buff, "T-%p", t); serial = buff; } D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port); if (init_socket_transport(t, s, port, local) < 0) { free(t); return -1; } adb_mutex_lock(&transport_lock); for (n = pending_list.next; n != &pending_list; n = n->next) { if (n->serial && !strcmp(serial, n->serial)) { adb_mutex_unlock(&transport_lock); free(t); return -1; } } for (n = transport_list.next; n != &transport_list; n = n->next) { if (n->serial && !strcmp(serial, n->serial)) { adb_mutex_unlock(&transport_lock); free(t); return -1; } } t->next = &pending_list; t->prev = pending_list.prev; t->next->prev = t; t->prev->next = t; t->serial = strdup(serial); adb_mutex_unlock(&transport_lock); register_transport(t); return 0;}
代码很简单,有两个出口,我都打了日志,重新编译之后就确定是transport_list这个链表出了问题,问题在于前一部机器注册了host这个键值,后面一部机器再注册就返回了,不管是什么机器serial的值在手机上都是host。
所以问题到这里就很清晰了,就是adbd在transport_list中保存了连接信息,发现重复了,就直接拒绝连接。所以第二部电脑连接的时候就offline了,offline是电脑本地的报错。
因为这份代码在adbd
和 adb(HOST)
都有用到,所以我在前后加了条件编译,在手机上就不去重了,反正函数里面的信息都不足以判断重复。在电脑端(adb(HOST)
)这个要保留,不然同一部电脑会重复连接多次。
修改后自己验证的跑了几十次,确定没问题就提交代码了。
- Multiple adb connections over WiFi
- ADB OVER WIFI
- ADB over WiFi
- Using Android Debug Bridge (ADB) over Wifi
- adb for remote connections
- Patch to allow multiple connections
- adb wifi
- Wifi over SDIO
- Wifi over SDIO
- ADB Debugging over Bluetooth
- adb-with-multiple-devices
- Use adb over Wi-Fi
- Deploying MySQL Cluster over multiple hosts
- adb通过wifi连接
- adb wifi 模式
- wifi连adb
- adb shell wifi
- android手机 wifi adb
- yii2项目实战-了解一下基于角色的访问控制
- AAA Java中使用akka
- maven之jdk升级配置和jar包升级配置
- 计算机网络(二) --- 网络基础 : 传输方式的分类及网络的构成要素
- Python中最基础类的属性和信息
- Multiple adb connections over WiFi
- 转载 使用RAID与LVM磁盘阵列技术
- 数据库中批量插入数据的方法
- Eclipse Juno + Tomcat 9.0 部署web应用
- 237. Delete Node in a Linked List
- 字符串问题---判断字符数组中是否所有的字符只出现了一次
- netfilter----filter机制
- hdu1251
- Yii2如何使用存取控制过滤器(ACF)