安卓与PC使用USB一种Socket通信方案
来源:互联网 发布:php 菜鸟教程 编辑:程序博客网 时间:2024/06/06 01:06
安卓设备和PC之间有很多种通信方式,比如基于无线网络等等。有的时候我们可能需要一些其他的通信方式。安卓设备和PC之间可以通过使用USB来进行通信。使用USB通信能够比无线通信速度更快,效率更高,这一点在分布式中的研究中很有用处,比如我们使用多台手机做实验,记录下log,这几个log的时间最好是一样的,那么我们可以每次记录下log的时候,向PC获取一次时间,把PC的时间作为标准时间。以下给出基于USB通信的原理和实现方式。
通信原理与机制
安卓设备能够和PC之间使用Socket通信的关键一点是能够使用adb转发,所以手机要有adb模式。adb对端口进行映射,转发Socket中的数据,在Socket通信结构中,PC端只能作为Client端,安卓设备是作为Server端。
具体实现
先看安卓端的实现,安卓端的步骤是建立服务端的监听过程,在连接上之后做各种处理。代码如下:
ServerSocket serverSocket = new ServerSocket(ADBExecutor.ANDROID_PORT);Socket socket = serverSocket.accept();SomeService.INSTANCE.setIOStream(socket);
这里ADBExecutor.ANDROID_PORT是自己定义的一个端口,这个用户自己随意定义。对于SomeService类也在这里给出代码吧:
public enum SomeService { INSTANCE; private DataInputStream inputStream = null; private DataOutputStream outputStream = null; public void setIOStream(final Socket socket){ try { inputStream = new DataInputStream(socket.getInputStream()); outputStream = new DataOutputStream(socket.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void pollingTime(){ try { outputStream.writeUTF("REQ"); outputStream.flush(); long time = inputStream.readLong(); System.out.println("PC time:" + time + " \n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
可以在这中间做想要的事情。比如我定义了一个方法为pollingTime(),就是获取PC的时间并打印。
接下来看PC端的代码的操作。在PC端需要首先确定有哪些设备通过USB连接上的,这个可以得到当前连接的设备的机器序列号。然后通过执行如下命令:
adb -s device_id forward tcp:host_port tcp:to_port
来完成端口的转发映射。其中device_id就是对应的机器的硬件地址。host_port是PC定义的一个端口,to_port是指定的转发到的端口。而关于device_id怎么得到呢,执行如下命令即可:
adb devices
关于怎么在java中执行命令,以及收集命令执行的结果,建立端口的映射,建立Socket连接,给出如下代码:
public class ADBExecutor { public static final int ANDROID_PORT = 30000; public static final int HOST_BASE_PORT = 35000; private final String adb_directory; public ADBExecutor(String adb_directory){ this.adb_directory = adb_directory; } //得到当前连接上的设备的序列号 public List<String> execAdbDevices() { System.out.println("adb devices"); List<String> ret_device_id_list = new ArrayList<String>(); Process proc = null; try { proc = new ProcessBuilder(this.adb_directory, "devices").start(); proc.waitFor(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (InterruptedException ire) { ire.printStackTrace(); } String devices_result = this.collectResultFromProcess(proc); String[] device_id_list = devices_result.split("\\r?\\n"); if (device_id_list.length <= 1) { System.out.println("No Devices Attached."); return ret_device_id_list; } /** * collect the online devices */ String str_device_id = null; String device = null; String[] str_device_id_parts = null; // ignore the first line which is "List of devices attached" for (int i = 1; i < device_id_list.length; i++) { str_device_id = device_id_list[i]; str_device_id_parts = str_device_id.split("\\s+"); // add the online device if (str_device_id_parts[1].equals("device")) { device = str_device_id_parts[0]; ret_device_id_list.add(device); System.out.println(device); } } //System.exit(0); return ret_device_id_list; } //对于当前连接上的设备都进行映射 public Map<String, Integer> execAdbOnlineDevicesPortForward() { List<String> device_id_list = this.execAdbDevices(); Map<String, Integer> device_hostport_map = new HashMap<String, Integer>(); int index = 0; for (String device : device_id_list) { int host_port = ADBExecutor.HOST_BASE_PORT + index * 10; this.execAdbSingleDevicePortForward(device, host_port, ADBExecutor.ANDROID_PORT); device_hostport_map.put(device, host_port); index++; } return device_hostport_map; } //具体的映射过程 public void execAdbSingleDevicePortForward(String device_id, int host_port, int to_port) { System.out.println("adb -s " + device_id + " forward tcp:" + host_port + " tcp:" + to_port); Process proc = null; try { proc = new ProcessBuilder(this.adb_directory, "-s", device_id, "forward", "tcp:" + host_port, "tcp:" + to_port).start(); proc.waitFor(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (InterruptedException ire) { ire.printStackTrace(); } } //手机命令执行之后的结果 private String collectResultFromProcess(Process proc) { StringBuilder sb_result = new StringBuilder(); BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream())); String result_line = null; try { while ((result_line = stdInput.readLine()) != null) { sb_result.append(result_line); sb_result.append("\n"); } while ((result_line = stdError.readLine()) != null) { sb_result.append(result_line); sb_result.append("\n"); } } catch(IOException ioe) { ioe.printStackTrace(); } return sb_result.toString(); }}
以上是ADB执行各种操作的类,比如查看当前连接的设备,建立端口映射。接下来给出PC上执行的主要过程:
package com.example.adbforward;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import java.util.HashMap;import java.util.Map;public class PCHost { private final Map<String, Integer> device_hostport_map; private final Map<String, Socket> device_hostsocket_map = new HashMap<String, Socket>(); public PCHost(Map<String, Integer> device_hostport_map){ this.device_hostport_map = device_hostport_map; this.createDeviceHostConnection(); } //创建连接 private void createDeviceHostConnection() { String device = null; int host_port = -1; for(Map.Entry<String, Integer> device_hostport : this.device_hostport_map.entrySet()) { device = device_hostport.getKey(); host_port = device_hostport.getValue(); Socket device_hostsocket = null; try { device_hostsocket = new Socket("localhost", host_port); } catch (UnknownHostException uhe) { uhe.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } this.device_hostsocket_map.put(device, device_hostsocket); } } public void startTimeService(){ //启动某些服务线程 } public static void main(String[] args) throws InterruptedException { ADBExecutor adb_executor = new ADBExecutor("E:\\eclipse\\sdk\\platform-tools\\adb.exe ");//这是我的abd.exe的位置 Map<String, Integer> device_hostport_map = adb_executor.execAdbOnlineDevicesPortForward(); final PCHost host = new PCHost(device_hostport_map); host.startTimeService(); }}
以上就是整个android和PC之间通过USB采用Socket通信的主要过程。给出的代码能够对连接在PC上的多个设备都开启服务,即如果有多个设备连接在PC上。以上来自师兄的指点,在此感谢。
- 安卓与PC使用USB一种Socket通信方案
- 安卓与pc 的socket通信
- 安卓与pc 的socket通信
- 手机与pc USB连接adb socket通信
- 手机与pc USB连接adb socket通信
- 安卓 USB通信
- PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- Android与PC的Socket(TCP/IP)通信(by USB) 拒绝连接的
- C# PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)(转载)
- PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- Android与PC的Socket(TCP/IP)通信(by USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- PC客户端与Android服务端的Socket同步通信(USB)
- Poj2777(线段树+标记+状态压缩)
- JDBC URL中关于字符编码的配置参数
- HDUOJ Let the Balloon Rise 1004
- VIM常用操作
- [UnityShaderCookbook 读书笔记] [01] Unity Shader 基础
- 安卓与PC使用USB一种Socket通信方案
- Python向MySQL批量插入数据
- 判断中间目录是否存在
- Makefile经典教程(掌握这些足够)
- 将字符串按照单词逆序
- linux内核bootsect.S和setup.S流程
- 信息安全入门指南
- python-文件输入输出
- 什么是霍夫曼编解码?