通过TCP实现python与安卓APK的数据通讯

通过TCP实现python与安卓APK的数据通讯

这里写目录标题

  • 通过TCP实现python与安卓APK的数据通讯
    • 为啥要干这件事
    • 有啥可用的方案
    • 通过adb forward实现端口转发
    • PC端的Python代码实现
    • 安卓端的JAVA代码段实现
  • 写在结尾

为啥要干这件事

最近准备开始新项目的集成测试方案的设计,思考通过uiautomator2的UI获取数据的方案不稳定且速度慢。通过和公司架构大佬沟通,
准备尝试使用通过TCP进行链路数据通信

有啥可用的方案

通过几番搜索还是让我找到了相应的方法,就是通过 adb forward实现USB的通讯,网上搜到的解释是通过端口转发,详细原理,可以参考这个大佬写的博客点击我。这样我们就可以通过这个方案实现TCP的通讯了,接下来就是代码实现了

通过adb forward实现端口转发

在cmd窗口输入adb forward tcp:8000 tcp:9090,前面的8000是PC端要访问的端口,后面得9090是安卓端需要访问的端口,我们通过Socket通讯实现相对应的TCP通讯,其中python作为客户端,安卓作为服务端(这里必须这样做,为啥我也没明白,有懂的大佬指导下),下面的代码,是我调试的代码。java部分代码是参考网上的。大佬们将就看,有兴趣了解的可以私信我,我会一一解答

PC端的Python代码实现

import json
import socket
import threading
import time
from typing import Optional

location_add = "127.0.0.1"  #回环地址
TCP_PORT = 8000     #PC需要连接的端口

class myclient():
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect_state = False
        self.__recvdata = None


    @property
    def recvdata(self):
        return self.__recvdata


    def connect_server(self)->Optional[bool]:
        """
        与服务器进行TCP连接
        """
        try:
            state = self.client.connect((location_add,TCP_PORT))
            if state == None:
                self.connect_state = True
                # self.client_recv()
                return self.connect_state
            else:
                self.connect_state = False
                return self.connect_state
        except Exception:
            self.connect_state = False
            return self.connect_state

    def client_send(self,data: Optional[str]):
        update_json = json.dumps(data)
        self.client.sendall(update_json.encode(encoding='utf-8')+"\n".encode(encoding='utf-8')) #注意这里一定要添加\n,否则数据会等到程序结束才会发送


    def client_recv(self):
        """
        功能开启TCP接收线程
        """
        clent_t = threading.Thread(target=self.recv)
        clent_t.start()


    def recv(self):
        """
        将接收到得TCP数据写进recvdata属性
        """
        while True:
            msg_recv = self.client.recv(1024)
            data = msg_recv.decode('utf-8')
            self.__recvdata = data
            time.sleep(0.1)


me = myclient()
me.connect_server()
me.client_recv()
time.sleep(2)
me.client_send("12")


安卓端的JAVA代码段实现

package com.example.mysocket;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.material.textfield.TextInputEditText;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
    ServerSocketThread serverSocketThread = new ServerSocketThread();
    public static final int connect_state = 1;
    public static final int UPDATE_TEXT = 2;
    private Button send=null;
    private TextView info=null;
    private TextInputEditText TextEdit=null;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case connect_state:
                    TextEdit.setText(msg.obj.toString());
                    break;
                case UPDATE_TEXT:
                    TextEdit.setText(msg.obj.toString());
                    break;
                case 3:
                    TextEdit.setText(msg.obj.toString());
                    break;
                default:
                    break;
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        send=(Button)findViewById(R.id.sendbtn);
        info=(TextView) findViewById(R.id.porttext);
        TextEdit=(TextInputEditText)findViewById(R.id.newlog);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                serverSocketThread.start();

            }
        });
    }
    class ServerSocketThread extends Thread {
//    private Handler handler;
//
//    public void setHandler(Handler handler) {
//        this.handler = handler;
//    }
        @Override
        public void run() {
            try {
                // 创建ServerSocket
                ServerSocket serverSocket = new ServerSocket(9090);
                System.out.println("--开启服务器,监听端口 9999--");

                // 监听端口,等待客户端连接

                Message message1 = handler.obtainMessage();
                message1.what = connect_state;
                message1.obj = "--等待客户端连接--"+"\n";
                handler.sendMessage(message1);
                Socket socket = serverSocket.accept(); //等待客户端连接
                System.out.println("test ok");
                Message message2 = handler.obtainMessage();
                message2.what = UPDATE_TEXT;
                message2.obj = "得到客户端连接:" + socket+"\n";
                handler.sendMessage(message2);

                startReader(socket);


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * 从参数的Socket里获取消息
         */
        private void startReader(final Socket mSocket) {
            new Thread(){
                @Override
                public void run() {
                    try {
                        while (true) {
                        // 获取读取流
                        BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream(),"utf-8"));
                        String line="";
                        while ((line = in.readLine()) != null) {// 读取数据
                            Message message3 = handler.obtainMessage();
                            message3.what = 3;
                            message3.obj = "获取到客户端的信息:" + line+"\n";
                            handler.sendMessage(message3);
                            String newtext = line.replace("\"","");
                            if(newtext.equals("12")){
                                System.out.println("mytest");
                                serverSendMessage(mSocket,"13");
                            }

                        }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }

        //通过socket来给客户端发送消息
        private void serverSendMessage(Socket mSocket,String mServerSendMessage) {
            new Thread() {
                @Override
                public void run() {
                    PrintWriter out;
                    try {
                        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
                        out.println(mServerSendMessage);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }

    }
}







写在结尾

我是一名车载集成测试开发工程师,希望能和志同道合的朋友一起相互学习进步

你可能感兴趣的:(tcp/ip,python,android)