我有一個 android 應用程式,它使用 DataOutputStream 通過套接字將影像從圖庫發送到 Python 服務器,以寫入客戶端應用程式中的套接字。影像從外部存盤目錄加載并在發送前緩沖。影像由服務器接收并寫入磁盤記憶體。當我嘗試打開影像時,它給了我:“讀取影像檔案的致命錯誤。不是 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();
}
蟒蛇服務器:
#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()


uj5u.com熱心網友回復:
這個答案可能不可靠,但確實展示了一種將檔案從 Java 應用程式高效傳輸到 Python 服務器的機制。出于演示目的,某些路徑是硬編碼的。另請注意,如果正在傳輸的檔案非常大,這可能不合適,因為在寫入目標檔案之前,整個檔案內容將保存在服務器端的記憶體中。顯然,這可以用更復雜的代碼來解釋。
這是Java客戶端:
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);
}
}
}
這是 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]
data = conn.recv(n, socket.MSG_WAITALL)
with open('/tmp/image.png', 'wb') as image:
image.write(data)
if __name__ == '__main__':
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/351273.html
