app和PC通信可实现方式
1、app和PC通过socket通信(需要网络)
2、app和PC通过usb通信(不需要网络)
PC之间通过adb控制android手机属于半双工,我们的实现方式是app和PC实现全双工通信。
如:adb forward tcp:8000 tcp:9000 的意思是,将PC端的 8000 端口收到的数据,转发给手机中的 9000 端口。
但是光执行这个命令还不能转发数据,还需要完成下面两个步骤才能传数据:
(a)在手机端,建立一个端口为9000的 server,并打开 server 到监听状态。
(b)在PC端,建立一个 socket client 端,连接到端口为8000的 server 上。
PC端应用与手机端应用 通信建立过程:
(1)执行 adb forward tcp:8000 tcp:9000
(2)启动手机端应用,建立端口为9000的 server,并处于监听状态(LISTENING)
(3)启动PC端应用,连接端口为8000的 server(adb 创建的)
之后,就可以传输数据了
PC端应用与手机端应用之间传输数据的过程:
(1)PC端应用将数据发送给端口为8000的 server(adb 创建的)
(2)adb 将数据转发给手机端 adbd 进程(通过USB传输)
(3)adbd 进程将数据发送给端口为9000的 server(手机端应用创建的)
传递是双向的,第(1)和第(3)步是通过socket实现的,所以通过 socket 的读和写就完成了PC端和手机端的数据传递。
PC端实现代码
//package com.socket.txt;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class adbSocketCont extends Thread {
Socket client;
BufferedOutputStream out;
BufferedInputStream in;
public adbSocketCont() {
try {
client = new Socket("127.0.0.1", 8000);
out = new BufferedOutputStream(client.getOutputStream());
in = new BufferedInputStream(client.getInputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
try {
Scanner scanner = new Scanner(System.in);
String msg = scanner.next();
if (!client.isConnected()) {
return;
}
out.write(msg.getBytes());
out.flush();
while (true) {
String readMsg = "";
if (!client.isConnected()) {
break;
}
readMsg = readMsgFromSocket(in);
System.out.println(readMsg);
if (readMsg.length() == 0) {
break;
}
readMsg = scanner.next();
out.write((readMsg ).getBytes());
out.flush();
}
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String readMsgFromSocket(InputStream in) {
String msg = "";
byte[] tempbuffer = new byte[1024];
try {
int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}
public static void main(String args[]) {
adbSocketCont asc = new adbSocketCont();
asc.start();
}
}
app端实现代码
package com.example.modle;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerThread extends Thread {
private static final String TAG = "ServerThread";
boolean isLoop = true;
public void setIsLoop(boolean isLoop) {
this.isLoop = isLoop;
}
@Override
public void run( ) {
Log.d("anzi", "running");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(9000);
while (isLoop) {
final Socket socket = serverSocket.accept();
new Thread(new SocketReadThread(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Log.d("anzi", "destory");
if (serverSocket != null) {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void sendToast(String msg) throws IOException {
Socket socket = new Socket("127.0.0.1", 8000);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(msg);
socket.close();
}
class SocketReadThread implements Runnable {
private BufferedInputStream in;
private BufferedOutputStream outputStream;
Socket mSocket;
public SocketReadThread(Socket mSocket) throws IOException {
this.in = new BufferedInputStream(mSocket.getInputStream());
outputStream = new BufferedOutputStream(mSocket.getOutputStream());
this.mSocket = mSocket;
}
public void run( ) {
try {
String readMsg = "yyyy";
String currCMD = "";
while (true) {
try {
if (!mSocket.isConnected()) {
break;
}
// 读到后台发送的消息 然后去处理
currCMD = readMsgFromSocket(in);
// 处理读到的消息(主要是身份证信息),然后保存在sp中;
if (currCMD.length() == 0) {
Log.d(TAG,"length = 0");
break;
}
if (currCMD.equals("0002")) {
Log.d(TAG,"0002 0002 0002");
outputStream.write((currCMD + "vclusters").getBytes());
} else {
// 将要返回的数据发送给 pc
outputStream.write((currCMD + "flag").getBytes());
}
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
public String readMsgFromSocket(InputStream in) {
int MAX_BUFFER_BYTES = 2048;
String msg = "";
byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];
try {
int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}
}
代码中只能映射127.0.0.1,需要映射所有ip,参考博客中第四篇:android - adb port forwarding to listen on all interfaces - Stack Overflow
参考博客:
Android -- adb forward实现PC和App的通讯_一只驴在敲代码-CSDN博客_adb forward 原理
Android adb与PC端通信_anqingcheng的博客-CSDN博客_adb通信
Android和C/C++通过原生socket实现通信 - 灰信网(软件开发博客聚合)
android - adb port forwarding to listen on all interfaces - Stack Overflow