Использование одного AsyncTask для отправки и получения данных на сервер Python - PullRequest
1 голос
/ 29 февраля 2020

Я хочу отправить капли размером 40x40px на мой Python сервер, затем обработать его и отправить обратно с идентификатором, представляющим класс изображения (это задача классификации изображения). Я использую AsyncTask, и тут возникает проблема - большой двоичный объект отправляется на сервер, но в моем коде Android часть, отвечающая за получение ответа, не достигается.

Интересно, правильно ли отправлять, а затем получать данные в одном AsyncTask. Я прочитал, что задачи, занимающие около 10 секунд, подходят для этого решения, поэтому теоретически в моем случае проблем быть не должно.

Здесь я прилагаю свой код для Клиента:

public class ServerConnectAsyncTask extends AsyncTask<Void, Void, Integer> {

    private AsyncTaskResultListener asyncTaskResultListener;
    private Socket socket;
    private Mat img;

    ServerConnectAsyncTask(Mat blob, Context c) throws IOException {
        img = blob;
        asyncTaskResultListener = (AsyncTaskResultListener) c;
    }

    @Override
    protected Integer doInBackground(Void... voids) {
        MatOfByte buf = new MatOfByte();
        Imgcodecs.imencode(".jpg", img, buf);
        byte[] imgBytes = buf.toArray();

        try {
            socket = new Socket("192.168.0.109",8888);
            DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
            DataInputStream din = new DataInputStream(socket.getInputStream());

            dout.write(imgBytes);
            dout.flush();

            String str = din.readUTF();     // it seems that it doesn't reach this line

            dout.close();
            din.close();
            socket.close();

            return Integer.valueOf(str);
        } catch (IOException e) {
            e.printStackTrace();
            return 99;
        }
    }

    @Override
    protected void onPostExecute(Integer imgClass) {
        asyncTaskResultListener.giveImgClass(imgClass);
    }
}

И для python сервера:

HOST = "192.168.0.109"
PORT = 8888

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))

s.listen(10)

while True:
    conn, addr = s.accept()
    print("Got connection from", addr)

    msg = conn.recv(4096)

    buf = np.frombuffer(msg, dtype=np.uint8).reshape(-1, 1)
    img = cv2.imdecode(buf, 0)
    cv2.imwrite("output.jpg", img)            # here I save my blob correctly

    if msg:
        message_to_send = "0".encode("UTF-8")     # then I send my "predicted" image class
        conn.send(message_to_send)
    else:
        print("no message")

Также важно, чтобы я назвал AsyncTask.execute() в моем onCameraFrame() методе - время от времени (не в каждом кадре, только когда мой BLOB-объект достаточно «стабилен», что случается довольно редко).

1 Ответ

0 голосов
/ 01 марта 2020

Очевидно, он застрял на readUTF() части. Теперь он работает:

DataInputStream din = new DataInputStream(socket.getInputStream());
int str = din.read();
char sign = (char) str;

dout.close();
din.close();
socket.close();
return Character.getNumericValue(sign);

Теперь он возвращает 0, когда я отправляю «0» с сервера python, поэтому он отлично работает для меня.

...