Home > Back-end >  Error while reading image received from socket
Error while reading image received from socket

Time:11-07

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

enter image description here

enter image description here

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()
  • Related