如何查看已上传的图片内容?
要查看上传的图片内容,您需要下载它并在本地打开。根据您的代码,上传文件后返回了文件的 MD5 值和状态。您可以使用相同的客户端代码来下载该文件。
以下是修改后的代码,用于下载已上传的图片并保存到本地:
import argparse
import hashlib
import os
import struct
import time
import uuid
from socket import *
import json
MAX_PACKET_SIZE = 20480
# Const Value
OP_SAVE, OP_DELETE, OP_GET, OP_UPLOAD, OP_DOWNLOAD, OP_BYE, OP_LOGIN, OP_ERROR = 'SAVE', 'DELETE', 'GET', 'UPLOAD', 'DOWNLOAD', 'BYE', 'LOGIN', 'ERROR'
TYPE_FILE, TYPE_DATA, TYPE_AUTH, DIR_EARTH = 'FILE', 'DATA', 'AUTH', 'EARTH'
FIELD_OPERATION, FIELD_DIRECTION, FIELD_TYPE, FIELD_USERNAME, FIELD_PASSWORD, FIELD_TOKEN = 'operation', 'direction', 'type', 'username', 'password', 'token'
FIELD_KEY, FIELD_SIZE, FIELD_TOTAL_BLOCK, FIELD_MD5, FIELD_BLOCK_SIZE = 'key', 'size', 'total_block', 'md5', 'block_size'
FIELD_STATUS, FIELD_STATUS_MSG, FIELD_BLOCK_INDEX = 'status', 'status_msg', 'block_index'
DIR_REQUEST, DIR_RESPONSE = 'REQUEST', 'RESPONSE'
def make_request_packet(operation, data_type, json_data, bin_data=None):
'''
Make a packet for request
:param operation: [SAVE, DELETE, GET, UPLOAD, DOWNLOAD, BYE, LOGIN]
:param data_type: [FILE, DATA, AUTH]
:param json_data
:param bin_data
:return:
'''
json_data[FIELD_OPERATION] = operation
json_data[FIELD_DIRECTION] = DIR_REQUEST
json_data[FIELD_TYPE] = data_type
return make_packet(json_data, bin_data)
def make_fileRequest_packet(operation, data_type, file_key, file_size, block_index, token, json_data, bin_data):
'''
Make a packet for fileRequest
:param file_size:
:param block_index:
:param token:
:param file_key:
:param operation: [SAVE, DELETE, GET, UPLOAD, DOWNLOAD, BYE, LOGIN]
:param data_type: [FILE, DATA, AUTH]
:param json_data
:param bin_data
:return:
'''
json_data[FIELD_KEY] = file_key
json_data[FIELD_SIZE] = file_size
json_data[FIELD_TOKEN] = token
json_data[FIELD_OPERATION] = operation
json_data[FIELD_DIRECTION] = DIR_REQUEST
json_data[FIELD_TYPE] = data_type
json_data[FIELD_BLOCK_INDEX] = block_index
return make_packet(json_data, bin_data)
def make_packet(json_data, bin_data=None):
'''
Make a packet following the STEP protocol.
Any information or data for TCP transmission has to use this function to get the packet.
:param json_data:
:param bin_data:
:return:
The complete binary packet
'''
j = json.dumps(dict(json_data), ensure_ascii=False)
j_len = len(j)
if bin_data is None:
return struct.pack('!II', j_len, 0) + j.encode()
else:
return struct.pack('!II', j_len, len(bin_data)) + j.encode() + bin_data
def get_tcp_packet(conn):
'''
Receive a complete TCP "packet" from a TCP stream and get the json data and binary data.
:param conn: the TCP connection
:return:
json_data
bin_data
'''
bin_data = b''
while len(bin_data) < 8:
data_rec = conn.recv(8)
if data_rec == b'':
time.sleep(0.01)
if data_rec == b'':
return None, None
bin_data += data_rec
data = bin_data[:8]
bin_data = bin_data[8:]
j_len, b_len = struct.unpack('!II', data)
while len(bin_data) < j_len:
data_rec = conn.recv(j_len)
if data_rec == b'':
time.sleep(0.01)
if data_rec == b'':
return None, None
bin_data += data_rec
j_bin = bin_data[:j_len]
try:
json_data = json.loads(j_bin.decode())
except Exception as ex:
return None, None
bin_data = bin_data[j_len:]
while len(bin_data) < b_len:
data_rec = conn.recv(b_len)
if data_rec == b'':
time.sleep(0.01)
if data_rec == b'':
return None, None
bin_data += data_rec
return json_data, bin_data
def login(clientSocket,id):
login_data = {
"username": id,
"password": hashlib.md5(id.encode()).hexdigest(),
}
clientSocket.send(make_request_packet(OP_LOGIN, TYPE_AUTH, login_data))
json_data, bin_data = get_tcp_packet(clientSocket)
return json_data
def get_file_size(file_path):
fsize = os.path.getsize(file_path) # 获取文件大小:以字节为单位
return fsize
def _argparse():
parse = argparse.ArgumentParser()
parse.add_argument("--server_ip", default='10.7.219.224', action='store', required=False, dest="ip",
help="The IP address bind to the server. Default bind all IP.")
parse.add_argument("--port", default='1379', action='store', required=False, dest="port",
help="The port that server listen on. Default is 1379.")
parse.add_argument("--f", default='', action='store', required=False, dest="f",
help="The file path. Default is none.")
parse.add_argument("--id", default='2037319', action='store', required=False, dest="id",
help="The id. Default is none.")
return parse.parse_args()
def uploadFile(clientSocket, fileName, token):
save_data = {}
file_size = get_file_size(fileName)
file_key = str(uuid.uuid4()) + os.path.splitext(fileName)[-1]
clientSocket.send(
make_fileRequest_packet(operation=OP_SAVE, data_type=TYPE_FILE, file_key=file_key, file_size=file_size,
block_index=None, token=token, json_data=save_data, bin_data=None))
json_data, bin_data1 = get_tcp_packet(clientSocket)
total_block = json_data["total_block"]
block_size = MAX_PACKET_SIZE
block_index = 0
while block_index < total_block:
f = open(fileName, 'rb')
f.seek(block_size * block_index)
bin_data = f.read(block_size)
f.close()
clientSocket.send(
make_fileRequest_packet(OP_UPLOAD, TYPE_FILE, file_key, file_size, block_index, token, save_data, bin_data))
json_data, bin_data2 = get_tcp_packet(clientSocket)
block_index = block_index + 1
print(json_data)
print(type(clientSocket))
return file_key
def get_file_md5(filename):
'''
Get MD5 value for big file
:param filename:
:return:
'''
m = hashlib.md5()
with open(filename, 'rb') as fid:
while True:
d = fid.read(2048)
if not d:
break
m.update(d)
return m.hexdigest()
def check_file_state(clientSocket, file_key, token):
clientSocket.send(
make_fileRequest_packet(operation=OP_GET, data_type=TYPE_FILE, file_key=file_key, file_size=None,
block_index=None, token=token, json_data={}, bin_data=None))
json_data, bin_data = get_tcp_packet(clientSocket)
print(json_data)
return json_data["md5"]
def downloadFile(clientSocket, file_key, token):
clientSocket.send(
make_fileRequest_packet(operation=OP_DOWNLOAD, data_type=TYPE_FILE, file_key=file_key, file_size=None,
block_index=None, token=token, json_data={}, bin_data=None))
json_data, bin_data = get_tcp_packet(clientSocket)
file_data = b""
while json_data["status"] == 200:
if bin_data:
file_data += bin_data
if json_data["status_msg"] == "OK. This is the last block.":
break
json_data, bin_data = get_tcp_packet(clientSocket)
return file_data
def save_file(file_data, filename):
with open(filename, 'wb') as f:
f.write(file_data)
def main():
parser = _argparse()
server_ip = parser.ip
server_port = parser.port
file_path = parser.f
id = parser.id
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((server_ip, int(server_port)))
json_data = login(clientSocket,id)
token = json_data["token"]
file_key = uploadFile(clientSocket, file_path, token)
md5 = check_file_state(clientSocket, file_key, token)
print("Token:", token)
print(json_data)
if md5 == get_file_md5(file_path):
print("upload successfully")
# 下载文件并保存到本地
file_data = downloadFile(clientSocket, file_key, token)
save_file(file_data, file_path)
print("文件已下载并保存到本地:", file_path)
clientSocket.close()
if __name__ == '__main__':
main()
在代码中,我添加了一个名为downloadFile的函数来下载文件,并将其保存到本地。然后,我定义了一个名为save_file的函数来保存下载的文件。在main函数中,我调用了这两个函数来完成下载和保存文件的操作。
您只需要将文件路径file_path设置为您希望保存下载文件的本地路径。运行修改后的代码后,它将上传文件并下载并保存到本地。请确保在运行代码之前已经上传了文件,并提供正确的服务器IP地址、端口和用户ID。
请注意,代码假设文件已成功上传到服务器并且服务器已正确响应下载请求。如果下载失败,请检查服务器的响应和网络连接等因素。
原文地址: https://www.cveoy.top/t/topic/lO5 著作权归作者所有。请勿转载和采集!