![](/img/trans.png)
[英]error UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
[英]Socket error: "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte"
我正在嘗試實現一種使用套接字庫發送和接收文件的方法,但是當我運行代碼時,我不斷收到錯誤消息“UnicodeDecodeError:‘utf-8’編解碼器無法解碼 position 中的字節 0xff 0:無效啟動字節”。
發件人代碼:
import os, socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 9999))
with open("image.jpg", "rb") as file:
file_size = os.path.getsize("send_file.txt")
client.send("image.jpg".encode())
client.send(str(file_size).encode())
data = file.read()
client.sendall(data)
client.send(b"<DATA_END>")
client.close()
收件人代碼:
import socket, tqdm
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 9999))
server.listen()
client, addr = server.accept()
file_name = client.recv(1024).decode()
print(file_name)
file_size = client.recv(1024).decode()
print(file_size)
with open(file_name, "wb") as file:
file_bytes = b""
done = False
progress = tqdm.tqdm(unit="B", unit_scale=True, unit_divisor=1000, total=int(file_size))
while not done:
data = client.recv(1024)
if file_bytes[-10:] == b"<DATA_END>":
done = True
else:
file_bytes += data
progress.update(1024)
file.write(file_bytes)
client.close()
server.close()
您假設 sockets 在接收時遵守發送邊界。 但這不是面向 stream 的協議(如 TCP)的工作方式。 send
可以在發送之前進行緩沖,或者將發送拆分為多個低級數據鏈路數據包。 recv
只獲取當前可用的數據。 值得注意的是,您不會知道您是否是字符串解碼的單詞邊界。 您需要一些其他機制來決定有用的數據塊何時到達。
適用於您的情況的協議是傳遞 header,其中每個字段由換行符分隔。 文件名或大小都沒有換行符,因此很容易區分。 接收器將讀取換行符邊界直到它具有文件名和大小,然后可以讀取有效載荷的確切大小字節。
client.py
import os, socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 9999))
filename = "image.jpg"
with open(filename, "rb") as file:
file_size = os.path.getsize(filename)
# protocol <filename>\n<size>\n<data>
client.sendall(filename.encode("utf-8"))
client.sendall(b"\n")
client.sendall(str(file_size).encode("utf-8"))
client.sendall(b"\n")
data = file.read()
client.sendall(data)
client.close()
服務器.py
def recv_to_newline(s):
buf = []
while True:
c = s.recv(1)
if not len(c):
# socket closed
return None
if c == b"\n":
return b"".join(buf)
buf.append(c)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 9999))
server.listen()
client, addr = server.accept()
file_name = recv_to_newline(client).decode("utf-8")
print(file_name)
file_size = int(client.recv(1024).decode())
print(file_size)
error = False
with open(file_name, "wb") as file:
progress = tqdm.tqdm(unit="B", unit_scale=True, unit_divisor=1000, total=int(file_size))
while file_size:
data = client.recv(min(1024, file_size))
if not data:
print("Error: Truncated recieve")
error = True
break
file.write(data)
progress.update(len(data))
file_size -= len(data)
if error:
os.remove(file_name)
client.close()
server.close()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.