PC 端的 XX 助手和手机 App 的通讯原理:
1 2
| adb forward tcp:8000 tcp:9000
|
什么是转发?
执行命令后, PC 端的 8000 端口会被 adb
监听, 这个时候我们只需要往 8000 端口写数据, 这个数据就会发送到手机端的 9000 端口上.
PC 端程序
把输入内容发送给 8000 端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class PCClient {
public static void main(String[] args) throws IOException { System.out.println("任意字符, 回车键发送Toast"); Scanner scanner = new Scanner(System.in); while (true) { String msg = scanner.next(); sendToast(msg); } }
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(); } }
|
Android 端程序
监听 9000 端口, 把收到的数据, Toast 在屏幕上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| public class MainActivity extends AppCompatActivity {
private static final String TAG = "ServerThread";
ServerThread serverThread;
Handler handler = new Handler() {
@Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), msg.getData().getString("MSG", "Toast"), Toast.LENGTH_SHORT).show(); } };
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); serverThread = new ServerThread(); serverThread.start(); }
@Override protected void onDestroy() { super.onDestroy(); serverThread.setIsLoop(false); }
class ServerThread extends Thread {
boolean isLoop = true;
public void setIsLoop(boolean isLoop) { this.isLoop = isLoop; }
@Override public void run() { Log.d(TAG, "running");
ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(9000);
while (isLoop) { Socket socket = serverSocket.accept();
Log.d(TAG, "accept");
DataInputStream inputStream = new DataInputStream(socket.getInputStream()); DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
String msg = inputStream.readUTF();
Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("MSG", msg); message.setData(bundle); handler.sendMessage(message);
socket.close(); }
} catch (Exception e) { e.printStackTrace(); } finally { Log.d(TAG, "destory");
if (serverSocket != null) { try { serverSocket.close(); } catch (Exception e) { e.printStackTrace(); } } } } }
}
|
运行效果
源码
Android-Pc-Socket-Connection
实际开发中的问题
1. Android 端的程序 有可能被干掉
2. adb forward
有可能会被干掉
由于连接不稳定性,判断真正连接成功的方法,只有轮询收发握手数据包:
C 发送一个数据包,等待 S 回复;C 如果收到了 S 的回复包,说明连通。
如果接收超时,则认为没有连通,在没有连通的情况下,需要重新建立 Socket,并 Connect(),然后再尝试握手。