读取从套接字接收到的图像时出错

Error while reading image received from socket

我有一个 android 应用程序,它通过套接字将图像从画廊发送到 Python 服务器,使用 DataOutputStream 写入客户端应用程序中的套接字。图像从外部存储目录加载并在发送前进行缓冲。图像由服务器接收并写入磁盘内存。当我尝试打开图像时,它给我:“读取图像文件时出现致命错误。不是 PNG”。然而,该图像占用的实际图像大小为 430 KiB。当我打印接收到的数据时,它会给我一些看起来像原始图像的东西:

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''

文字比较长,我删减了..

从目录加载图像并写入套接字的客户端代码:

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 服务器:

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

这个答案可能不够可靠,但确实展示了一种有效地将文件从 Java 应用程序传输到 Python 服务器的机制。出于演示目的,某些路径是硬编码的。另请注意,如果正在传输的文件非常大,这可能不合适,因为在写入目标文件之前,整个文件内容将保存在服务器端的内存中。显然,这可以用更详细的代码来解释。

这是 Java 客户端:

package com.aprk;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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));
            BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
            bos.write(nio(image.length()));
            byte[] buff = new byte[4096];
            int n;
            while ((n = bis.read(buff, 0, buff.length)) > 0) {
                bos.write(buff, 0, n);
            }
            bos.flush();
        } catch (IOException ex) {
            Logger.getLogger(GetImage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private static byte[] nio(long n) {
        byte[] v = new byte[8];
        int shift = 56;
        for (int i = 0; i < 8; i++) {
            v[i] = (byte)(n>>shift);
            shift -= 8;
        }
        return v;
    }
}

这是 Python 服务器:

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]
            with open('/tmp/image.png', 'wb') as image:
                while n > 0:
                    data = conn.recv(n)
                    image.write(data)
                    n -= len(data)


if __name__ == '__main__':
    main()