I have an android app that sends an image from gallery to a Python server via sockets using DataOutputStream to write to the socket in the client app. The image is loaded from external storage directory and buffered before being sent. The image is received by the server and written to disk memory. When I try to open the image it gives me: "Fatal Error reading the image file. Not a PNG". However the image occupies an actual image size of 430 KiB. When I print the data being received it gives me something that looks like a raw image:
b'\x97\xa7p\xc0\x04\xfbv\xf6\\\xed\x8a\xe9^\xbf\xa4p9\xae\x8eu:N\xb5\x8e\xcc\x06\xa6\xf1\tyL\xf3.^W\xb5RR\xd3)\x7fS\xf3\x8f\x1b\xc6\xf8\xa7\x9b\xf5\xb8\xc3f\xa9\xdf\xa1\xbd\xaa\xbeS\xbc\x84zt\xedT\xbfn|I\xfb\x0e\xfb\xae6\x18sS\x9b\x9e\xd8\xff\xc4>\xaf\xeb\xba\xbe>{\xe2\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87~\xe8\x87\xfe\xbf\xa4\xff\x07\xe5\x9f\xdc\xd5\xe2d\xc5\xcb\x00\x00\x00\x00IEND\xaeB`\x82'
b''
The text is longer but I cut it down..
The client code that loads the image from directory and writes to socket:
class send extends AsyncTask<Void, Void, Void> {
Socket s; //Socket Variable
@Override
protected Void doInBackground(Void... params) {
try {
s = new Socket("192.168.0.14", 9999);
String image = getLatestFilefromDir("/storage/emulated/0/DCIM");
File file = new File(image);
try (InputStream is = new BufferedInputStream(new FileInputStream(file));
DataOutputStream dos = new DataOutputStream(s.getOutputStream())) {
dos.writeLong(file.length());
int val;
while ((val = is.read()) != -1) {
dos.write(val);
}
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
private String getLatestFilefromDir(String dirPath){
File dir = new File(dirPath);
File[] files = dir.listFiles();
if (files == null || files.length == 0) {
return null;
}
File lastModifiedFile = files[0];
for (int i = 1; i < files.length; i ) {
if (lastModifiedFile.lastModified() < files[i].lastModified()) {
lastModifiedFile = files[i];
}
}
return lastModifiedFile.toString();
}
Python server:
#Imports modules
import socket
import datetime
date_string = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M")
listensocket = socket.socket()
listenPort = 9999
numberOfConnections=1
thisIp = socket.gethostname()
listensocket.bind(('', listenPort))
listensocket.listen(numberOfConnections)
print("Started Listening")
(clientsocket, address) = listensocket.accept()
print("Connected")
fname = "/home/pi/Desktop/Images/" date_string ".PNG"
f = open(fname, 'wb')
datain = 1
while datain:
datain = clientsocket.recv(100000000)
print(datain)
bytearray(f.write(datain))
f.close()
listensocket.close()
CodePudding user response:
This answer may not be robust but does demonstrate a mechanism for efficiently transferring files from a Java application to a Python server. Certain paths are hard-coded for demonstration purposes. Also note that this may not be appropriate if the file being transferred is very large due to the fact that the entire file contents will be held in memory on the server side before writing to the target file. Obviously that can be accounted for with more elaborate code.
Here's the Java client:
package com.aprk;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GetImage {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 7070);
File image = new File("/Volumes/G-DRIVE Thunderbolt 3/Pictures/rgb_colour_wheel.png");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(image));
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeLong(image.length());
byte[] buff = new byte[4096];
int n;
while ((n = bis.read(buff, 0, buff.length)) > 0) {
dos.write(buff, 0, n);
}
dos.flush();
} catch (IOException ex) {
Logger.getLogger(GetImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Here's the Python server:
import socket
from struct import unpack
HOST='0.0.0.0'
PORT=7070
def main():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, _ = s.accept()
with conn:
p = conn.recv(8, socket.MSG_WAITALL)
n = unpack('!Q', p)[0]
data = conn.recv(n, socket.MSG_WAITALL)
with open('/tmp/image.png', 'wb') as image:
image.write(data)
if __name__ == '__main__':
main()