1、 adb forward 原理概述
adb forward 的功能是建立一个转发
如:adb forward tcp:8000 tcp:9000 的意思是,将PC端的 8000 端口收到的数据,转发给手机中的 9000 端口。
但是光执行这个命令还不能转发数据,还需要完成下面两个步骤才能传数据:

(a)在手机端,建立一个端口为9000的 server,并打开 server 到监听状态。
(b)在PC端,建立一个 socket client 端,连接到端口为8000的 server 上。
adb forward tcp:8000 tcp:9000 原理示意图:

PC端应用与手机端应用 通信建立过程:
(1)执行 adb forward tcp:8000 tcp:9000
(2)启动手机端应用,建立端口为9000的 server,并处于监听状态(LISTENING)
(3)启动PC端应用,连接端口为8000的 server(adb 创建的)之后,就可以传输数据了
PC端代码====


private static boolean mRunning = true;public static void main(String[] args) {if (!setupAdbForward()) {System.out.println("设置端口转发失败");return;} else {System.out.println("端口转发设置完成");}System.out.println("任意字符, 回车键发送");startClient();}private static boolean setupAdbForward() {try {// todo 将PC端8000端口的数据, 转发到Android端的9000端口上String device = "adb devices";Process process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", device});int ret = process.waitFor();System.out.println("cmy 111:" + device + ";" + ret);String forward = "adb forward tcp:8000 tcp:9000";process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", forward});process.waitFor();System.out.println("cmy 222:" + forward + ";" + ret);return true;} catch (Exception e) {e.printStackTrace();}return false;}private static void startClient() {try {//设置pc端的端口为8000Socket socket = new Socket("127.0.0.1", 8000);// InThread 接收手机端传来的数据new Thread(new InThread(socket)).start();// OutThread 用于从PC端输入并传给手机端Scanner scanner = new Scanner(System.in);while (true) {String msg = scanner.next();sendToServer(socket, msg);}} catch (IOException e) {e.printStackTrace();}}/*** 接收手机端传来的数据*/static class InThread implements Runnable {Socket socket;public InThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {while (mRunning) {if (socket.isClosed()) {mRunning = false;break;}try {DataInputStream dis = new DataInputStream(socket.getInputStream());byte[] buffer = new byte[256];int len = dis.read(buffer);if (len > 0) {System.out.println("\n接收到:" + new String(buffer, 0, len, "UTF-8"));}} catch (IOException e) {e.printStackTrace();}}}}/*** 从PC端输入并传给手机端** @param msg 信息* @throws IOException 异常*/public static void sendToServer(Socket socket, String msg) throws IOException {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeUTF(msg);dos.flush();try {Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();}}

PC端应用与手机端应用之间传输数据的过程:
(1)PC端应用将数据发送给端口为8000的 server(adb 创建的)
(2)adb 将数据转发给手机端 adbd 进程(通过USB传输)
(3)adbd 进程将数据发送给端口为9000的 server(手机端应用创建的)传递是双向的,
第(1)和第(3)步是通过socket实现的,所以通过 socket 的读和写就完成了PC端和手机端的数据传递。
=======andorid 端代码=

public class ServerThread extends Thread {private static final String SERVER_TAG = "server";private ServerSocket serverSocket;private Socket socket;boolean isLoop = true;public Socket getSocket() {return socket;}@Overridepublic void run() {super.run();try {//设置Android端口为9000serverSocket = new ServerSocket(9000);while (isLoop) {try {//从连接队列中取出一个连接,如果没有则等待socket = serverSocket.accept();Log.v(SERVER_TAG, "从连接队列中取出一个连接");EventBus.getDefault().post(new MessageType("发现一个新的客户端加入:"));while (true) {/*** isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()* 这些方法无法判断服务端是否断开,只能判断本地的状态*/// 发送心跳包,单线程中使用,判断socket是否断开socket.sendUrgentData(0xFF);DataInputStream inputStream = new DataInputStream(socket.getInputStream());byte[] buffer = new byte[1024];int bt;String text = "";int index = 0;Log.v(SERVER_TAG, "inputStream.read 之前");while ((bt = inputStream.read(buffer)) != -1) {Log.v(SERVER_TAG, "bt:" + bt + ",," + (index++));text += new String(buffer, 0, bt).trim();Log.e(SERVER_TAG, "------------");Log.e(SERVER_TAG, "text: " + text.trim());/*** 当接收到大数据,inputStream读取完后,由于inputStream通道是一直在的,* inputStream.read(buffer)处在堵塞状态,所以并不会跳出当前循环,* 导致无法判断数据是否传输完,所以PC端传输数据时需要在数据中* 加入报尾,Android设备上接收到报尾,代表此次数据传输完毕,* 也可以加上报头,来表示数据的开始**/if (text.endsWith("-vvv")) {EventBus.getDefault().post(new MessageType("接收:" + text));text = text.substring(0, text.lastIndexOf("-vvv"));Log.v(SERVER_TAG, "内容长度:" + text.length());Log.v(SERVER_TAG, "读取结束,内容为:" + text);Log.v(SERVER_TAG, "inputStream.read 之后");break;}}}} catch (IOException e) {e.printStackTrace();EventBus.getDefault().post(new MessageType("接收:异常"));}}} catch (IOException e) {e.printStackTrace();}}
}
public class SendThread extends Thread {private String data;private Socket socket;public SendThread(String data, Socket socket) {this.data = data + "-vvv";this.socket = socket;}@Overridepublic void run() {super.run();sendDatas();}private void sendDatas() {try {DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());outputStream.write(data.getBytes("UTF-8"));outputStream.flush();LogUtils.e("发送:" + data);EventBus.getDefault().post(new MessageType("发送:" + data));} catch (IOException e) {e.printStackTrace();EventBus.getDefault().post(new MessageType("发送:异常"));}}
}

通过usb利用adb实现android手机和pc机通信相关推荐

  1. 《基于C/S模式的android手机与PC机通信系统的开发》项目

    基于C/S模式的android手机与PC机通信系统的开发 作者:郑海波 单位:南京邮电大学 通信与信息工程学院 信号与信息处理 6班 学号:1012010638 邮箱:zhb931706659@126 ...

  2. 利用ADB固定Android手机的CPU频率

    工作过程中,我需要对Android手机的CPU数据做一些分析,但是发现CPU频率是一直变化的,于是用了以下方法将其固定下来. 1.将手机与电脑连接,确认可以在CMD窗口使用ADB,输入 adb dev ...

  3. ubuntu下adb连接android手机调试

    1.adb连接android手机默认情况下,Ubuntu下通过USB数据线连接G2手机后,adb可能无法正常连接到设备.按照一下步骤可以解决此问题. 1)在terminal下面运行lsusb命令 会发 ...

  4. 阿里软件测试二面:adb 连接 Android 手机的两种方式,看完你就懂了

    前言 随着现在移动端技术的突飞猛进,导致现在市场上,APP 应用数不胜数,那对于测试工程师而言,对于 APP 的测试,那基本就是一个必修课了. 今天,我就来给大家介绍一下,adb 连接 Android ...

  5. ADB连接android手机

    ADB连接android手机 下载ADB连接工具 adb.exe是android开发包的一个插件,可以在官网上下载LINK. 运行adb.exe软件直接使用DOS命令就行:同时切换执行目录. 我们现在 ...

  6. Appium、adb控制Android手机和实战项目

    Appium.adb控制Android手机和实战项目 adb常用命令 Appium中API 元素定位操作API 滑动和拖拽事件(appium<2.0版本) 高级手势TouchAction 手机操 ...

  7. android开发获取手机,通过ADB获取Android手机信息,获取手机信息

    通过ADB获取Android手机信息,获取手机信息 原文:https://blog.csdn.net/fasfaf454/article/details/51438743 1.获取手机系统信息( CP ...

  8. android手机连接PC后怎样切换为U 盘模式

    android手机连接PC后怎样切换为U 盘模式 之前已经发过关于 APK文件怎样安装程序到手机上  已经介绍过了怎样通过手机与 PC 的连接将软件安装至手机.这一次再来讲解一下怎样将你的手机变为&q ...

  9. android手机连接PC无法正常安装驱动

    工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...

最新文章

  1. SQL 2005 删除带有默认值约束的列
  2. go语言基础到提高(7)-数组
  3. fastjson list转json字符串_程序员:JSON、JSONObject 与 JSONArray 简单讲解
  4. 壊小子的学习【日常阅读篇】(三)常规学习类图书
  5. step与matlab的opc,wincc与matlab通过OPC通讯
  6. java文件按时间排序_如何按日期在java目录中排序文件?
  7. HDU 5666 Segment 数论+大数
  8. error Microsoft Visual C++ 14.0 is required 解决方案
  9. android15版本号手机,Lineage OS 15.1正式发布:基于Android 8.1
  10. ubuntu16.04下ROS操作系统学习笔记(三 / 二)ROS基础-ROS通信编程
  11. 那个软件测试cpu温度准确,什么软件测试cpu温度准确_测试cpu温度准确软件汇总...
  12. 128兆内存能运行的linux,128兆内存能干嘛?
  13. OC Extension Font(字体宏定义)
  14. [问题已处理]-mac安装cobra失败
  15. 安卓学习日记——Shortcut
  16. RT-Thread 4.1.0 开启 PM 电源管理框架
  17. C++ Crow web框架使用;升级cmake ;pthread、boost、asio 报错
  18. 废水中COD高怎么办
  19. 基于php新闻发布平台 毕业设计-附源码141646
  20. Android集成Unity

热门文章

  1. Win10开机(更新)后无法进入系统,黑屏一直转圈
  2. 高德地图自定义点标记大小_高德地图 自定义点标记 图标大小
  3. ES6新增——反撇号(`)基础知识
  4. c盘满了怎么迁移软件到其他盘,c盘变红了文件怎么迁移
  5. Z(zombie)僵尸进程和孤儿进程
  6. 一文搞定 | Linux 网络子系统
  7. 十七点学完安全知识超级详细了解进程和病毒知识 转载
  8. linux创建运维账户流程,Linux运维养成记-账户与权限管理
  9. 安卓平板也能优雅刷B站,哔哩哔哩HD内测版
  10. 请问如何使IE支持有swing的aaplet?