Search code examples
javaandroidandroid-asynctask

Using single AsyncTask to both send and then receive data to/from Python server


I want to send 40x40px blobs to my Python server, then process it there and send back a reply with id representing the image class (its an image classification task). I use AsyncTask and here comes a problem - the blob is sent to the server but then the part responsible for receiving the reply is not reached in my Android code.

I wonder whether it is correct to both send and then receive data in single AsyncTask. I have read that tasks taking about <10 seconds are fine for this solution, so theoretically there should be no problem in my case.

Here I enclose my code, for Client:

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);
    }
}

And for python server:

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")

What is also important is that I call the AsyncTask.execute() in my onCameraFrame() method - once a while (not in every frame, only when my blob is sufficiently "stable", which happens rather rarely).


Solution

  • Apparently it got stuck on readUTF() part. Now it works:

    DataInputStream din = new DataInputStream(socket.getInputStream());
    int str = din.read();
    char sign = (char) str;
    
    dout.close();
    din.close();
    socket.close();
    return Character.getNumericValue(sign);
    

    Now it returns 0 when I send "0" from the python server, so it works fine for me.