通过usb利用adb实现android手机和pc机通信

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端的端口为8000
            Socket 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;
        }

        @Override
        public 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;
    }

    @Override
    public void run() {
        super.run();
        try {
            //设置Android端口为9000
            serverSocket = 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;
    }

    @Override
    public 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("发送:异常"));
        }
    }
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Android中,可以使用adb命令通过IP地址连接手机。首先,确保手机和计算机连接在同一个网络下,并且已经打开了USB调试模式。接下来,打开命令行终端或者命令提示符窗口,在命令行中输入以下命令: 1. 首先,使用adb devices命令查看设备列表,确认设备已被识别并连接。 ``` adb devices ``` 2. 接下来,使用adb tcpip命令,将设备切换至TCP/IP模式。此时,设备将在5555端口等待连接。 ``` adb tcpip 5555 ``` 3. 然后,使用手机的IP地址替换下方命令示例中的"设备IP",输入以下命令连接设备: ``` adb connect 设备IP:5555 ``` 4. 如果连接成功,终端会返回"connected to 设备IP:5555"的信息,并且设备列表中将显示已连接的设备。 5. 现在,您可以使用adb命令与该设备进行交互,例如通过adb shell命令进入设备的shell,进行文件操作、安装应用程序等。 ``` adb shell ``` 6. 如果需要切换回USB模式,使用以下命令: ``` adb usb ``` 通过以上步骤,您可以在不使用USB线缆的情况下通过IP地址连接Android手机,并使用adb命令进行设备管理和调试操作。请注意,如果设备的IP地址发生变化或重启,您可能需要重新执行步骤2和步骤3来重新连接设备。 ### 回答2: 在Android中,我们可以使用adb命令通过IP地址连接手机。首先,确保手机和电脑连接到同一个WiFi网络上。 步骤如下: 1. 打开手机的设置菜单,并找到“关于手机”选项。 2. 在“关于手机”选项中,查找和点击“状态”或“网络信息”。 3. 在“状态”或“网络信息”中,可以找到手机的IP地址。 4. 在电脑上打开命令提示符或终端窗口,输入以下adb命令:adb connect <手机IP地址>:<端口号>。例如,adb connect 192.168.0.100:5555。 5. 如果一切正常,命令提示符或终端窗口将显示“已连接到<手机IP地址>:<端口号>”。 6. 现在,您可以使用其他adb命令与连接的手机进行交互了,例如安装应用程序、传输文件等。 需要注意以下事项: 1. 手机和电脑必须连接到相同的WiFi网络上,否则无法建立连接。 2. 在一些手机上,需要在开发者选项中启用网络调试模式。 3. 如果连接不成功,可以尝试断开连接并重新连接手机,或者重新启动手机和电脑后再次尝试。 通过上述步骤,您就可以在Android中使用adb命令通过IP地址连接手机,并且可以方便地使用各种adb命令来管理和调试您的设备。 ### 回答3: 在Android中,使用adb命令通过IP地址连接手机是非常方便的。步骤如下: 首先,确保手机和电脑连接在同一个局域网环境中。 其次,在电脑上打开终端或命令提示符窗口,进入adb命令所在的目录。如果你已经将adb添加到环境变量中,可以直接在任何路径下使用adb命令。 接下来,通过以下命令查找设备的IP地址:adb shell ifconfig或adb shell ip addr。在返回结果中,找到设备的IP地址。 然后,使用以下命令连接到设备的IP地址:adb connect 设备IP地址。例如,adb connect 192.168.0.100。 最后,在连接成功后,你可以像正常连接设备一样使用adb命令来操作手机了。例如,adb shell可以进入设备的命令行界面,adb install可以安装应用程序等。 需要注意的是,通过IP地址连接手机的方式可能不如通过USB连接稳定和快速,因此在进行开发或调试时,建议使用USB连接。此外,某些设备可能需要在设置中启用ADB网络调试模式才能通过IP地址连接。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值