这是我的服务器:
//server.py
import sys
import socket
HOST = sys.argv[1] if len(sys.argv) > 1 else '0.0.0.0'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
SIZE = 1024
FORMAT = "utf-8"
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
client = s.accept()
while True:
print(f"\033[33m[*] Listening as {HOST}:{PORT}\033[m")
print(f"\033[32m[!] Client connected {client[1]}\033[m")
client[0].send('copy trash'.encode())
filename = client[0].recv(SIZE).decode(FORMAT)
print(f"[RECV] Receiving the filename.")
file = open(filename, "w")
client[0].send("Filename received.".encode(FORMAT))
data = client[0].recv(SIZE).decode(FORMAT)
print(f"[RECV] Receiving the file data.")
file.write(data)
client[0].send("File data received".encode(FORMAT))
s.close()
这是我的客户:
//client.py
import sys
import socket
import subprocess
import tqdm
import shutil
HOST = sys.argv[1] if len(sys.argv) > 1 else '0.0.0.0'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
FORMAT = "utf-8"
SIZE = 1024
s = socket.socket()
s.connect((HOST, PORT))
msg = s.recv(1024).decode()
print('[*] server:', msg)
if(msg.lower() == "copy trash"):
shutil.make_archive("/root/trashcopy", 'zip', "/root/.local/share/Trash")
file = open("/root/trashcopy.zip", "r")
data = file.read()
s.send("trashcopy.zip".encode(FORMAT))
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
s.send(data.encode(FORMAT))
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
我想做什么?
我试图用回收站中的文件制作一个 zip 文件并将其发送到服务器,但是,编码存在问题,并且在这一行抛出错误:
s.send(data.encode(FORMAT))
这是错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x95 in position 124: invalid start byte
我该如何解决这个问题?例如,当它是
.txt
文件时,我可以毫无问题地发送文件。
这是一个解码问题,我尝试过除
utf-8
以外的其他格式解码,但没有成功。
您的代码存在几个问题。例如,读取 zip(二进制)文件时,应将其读取为字节,而不是字符串,然后将其作为字节发送。此外,您的服务器需要提前知道预期的文件大小,以便能够分块读取文件。您可以使用字节排序来做到这一点。下面是一个工作示例。数据接收方法的功劳归于this,该方法稍微修改为按照代码要求以块的形式读取数据。
编辑:服务器已修改为支持客户端重新连接。因此,
client = s.accept()
已移至 while 循环内部,并且客户端的连接在收到文件后关闭。
服务器.py
import sys
import socket
HOST = sys.argv[1] if len(sys.argv) > 1 else '0.0.0.0'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
SIZE = 1024
BYTEORDER_LENGTH = 8
FORMAT = "utf-8"
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
while True:
client = s.accept()
print(f"\033[33m[*] Listening as {HOST}:{PORT}\033[m")
print(f"\033[32m[!] Client connected {client[1]}\033[m")
print(f"Sending 'copy trash' msg")
client[0].send('copy trash'.encode())
print(f"[RECV] Receiving the file size")
file_size_in_bytes = client[0].recv(BYTEORDER_LENGTH)
file_size= int.from_bytes(file_size_in_bytes, 'big')
print("File size received:", file_size, " bytes")
client[0].send("File size received.".encode(FORMAT))
print(f"[RECV] Receiving the filename.")
filename = client[0].recv(SIZE).decode(FORMAT)
print(f"[RECV]Filename received:", filename)
client[0].send("Filename received.".encode(FORMAT))
print(f"[RECV] Receiving the file data.")
# Until we've received the expected amount of data, keep receiving
packet = b"" # Use bytes, not str, to accumulate
while len(packet) < file_size:
if(file_size - len(packet)) > SIZE: # if remaining bytes are more than the defined chunk size
buffer = client[0].recv(SIZE) # read SIZE bytes
else:
buffer = client[0].recv(file_size - len(packet)) # read remaining number of bytes
if not buffer:
raise Exception("Incomplete file received")
packet += buffer
with open(filename, 'wb') as f:
f.write(packet)
print(f"[RECV] File data received.")
client[0].send("File data received".encode(FORMAT))
client[0].close()
s.close()
客户端.py
import sys
import socket
import subprocess
import shutil
import os
HOST = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1'
PORT = int(sys.argv[2] if len(sys.argv) > 2 else 5555)
FORMAT = "utf-8"
SIZE = 1024
BYTEORDER_LENGTH = 8
s = socket.socket()
s.connect((HOST, PORT))
msg = s.recv(SIZE).decode()
print('[*] server:', msg)
if(msg.lower() == "copy trash"):
#shutil.make_archive("/root/trashcopy", 'zip', "/root/.local/share/Trash")
shutil.make_archive("_trashcopy", 'zip', "Trash")
file_size = os.path.getsize('_trashcopy.zip')
print("File Size is :", file_size, "bytes")
file_size_in_bytes = file_size.to_bytes(BYTEORDER_LENGTH, 'big')
print("Sending the file size")
s.send(file_size_in_bytes)
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
print("Sending the file name")
s.send("trashcopy.zip".encode(FORMAT))
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
print("Sending the file data")
with open ('_trashcopy.zip','rb') as f1:
s.send(f1.read())
msg = s.recv(SIZE).decode(FORMAT)
print(f"[SERVER]: {msg}")
s.close()