I have an android app that opens a socket connection with the server and sends an image to a python server. The server receives that image and is supposed to send a string back to confirm the image has been received. However the socket closes down after I end the Output stream, therefore the server receives the image but the client can't receive a string from the server because the client closed the connection. Therefore, what I want to do is return a string/text confirming the image has arrived to the user client before the socket closes.
This is my Python server that receives the image as bytes decodes and saves it to a directory then sends a message back:
from socket import *
import datetime
import cv2
import PIL.Image as Image
from PIL import ImageFile, Image
import io
import base64
import numpy as np
import pickle
import uuid
date_string = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M")
port = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', port))
s.listen(1)
while True:
conn, addr = s.accept()
img_dir = '/home/Desktop/frames_saved/'
img_format = '.png'
try:
print("Connected by the ",addr)
#date_string = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M")
filename = str(uuid.uuid4())
with open(img_dir+filename+img_format, 'wb') as file:
while True:
data = conn.recv(1024*8)
if data:
print(data)
try:
file.write(data)
except:
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', port))
s.listen(1)
conn.sendall(("Hello World"))
else:
print("no data")
break
finally:
conn.close()
What I am trying to do is receive the encoded string in my android client and print/show a toast.
Android client code:
public class SendImageClient extends AsyncTask<byte[], Void, Void> {
@Override
protected Void doInBackground(byte[]... voids) {
isSocketOpen = true;
try {
Socket socket = new Socket("192.168.0.14",9999);
OutputStream out=socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(out);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while (isSocketOpen){
Log.d("IMAGETRACK", "Wrote to the socket[1]");
dataOutputStream.write(voids[0],0,voids[0].length);
while ((line = input.readLine()) != null)
Log.d("IMAGETRACK3", "Wrote to the socket[3]");
response.append(line);
Message clientmessage = Message.obtain();
clientmessage.obj = response.toString();
Log.d("[MESSAGE]", String.valueOf(clientmessage));
// Tries to receive a message from the server
out.close();
input.close();
if(isSocketOpen == false){
Log.d("CLOSED", "CLOSED CONNECTION");
socket.close();
break;
}
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Additionally I noticed that doing out.close(); will close the stream socket aswell. Here's the log after an image is sent and received by the server:
D/IMAGETRACK: Wrote to the socket[1]
D/IMAGETRACK: Wrote to the socket[1]
W/System.err: java.net.SocketException: Socket closed
W/System.err: at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:124)
at java.net.SocketOutputStream.write(SocketOutputStream.java:161)
at java.io.DataOutputStream.write(DataOutputStream.java:107)
at MyApp.MainActivity$SendImageClient.doInBackground(MainActivity.java:2792)
at MyApp.MainActivity$SendImageClient.doInBackground(MainActivity.java:2780)
at android.os.AsyncTask$3.call(AsyncTask.java:394)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
If I try moving out.close(); after the while loop, the client will send an infinite amount of data to the server and when i close the server to end the infinite data being receive, instead of a 70Kb image, i will have a 10MB image or more depending on how log I received the bytes.
From the looks of it, I think I would need to somehow stop the image being sent without closing the server to listen to the image being sent back. How can I do that without closing the socket?