我這里有這兩個腳本,send.py和receive.py。Send.py 是一個主機,它打開一個連接并等待 receive.py 連接。一旦連接成功,理論上,我可以將任何檔案從一臺設備(使用 send.py 腳本)發送到另一臺設備(使用 receive.py 腳本)。小問題...我試圖從我在計算機上找到的隨機音樂檔案中讀取,以確保它適用于任何型別的檔案并遇到以下錯誤:
UnicodeDecodeError:“utf-8”編解碼器無法解碼位置 45 中的位元組 0xff:無效起始位元組
是什么導致了這個錯誤?
發送.py:
from socket import *
port = 42069
s = socket(AF_INET, SOCK_STREAM)
s.bind(('0.0.0.0', port))
s.listen(1)
c, addr = s.accept()
buffersize = 128
fname = '?ТГК -Гелик 2022? Gelik?-160 (mp3cut.net).mp3' #input('File Path: ')
with open(fname, 'rb') as file:
readfc = file.read()
c.send(fname.encode())
if len(readfc) > buffersize:
for packet in range(len(readfc) % buffersize):
c.send(readfc[0:buffersize])
和接收.py:
from socket import *
port = 42069
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.0.171', port))
index = 0
while True:
data = s.recv(1024)
if not data:
pass
else:
index = 1
if index == 1:
filename = data.decode()
else:
with open(filename, 'ab') as file:
file.write(data.decode())
這是 msuic 檔案的第一行:
ID3 #TSSE Lavf59.16.100 яыа Info #R ?.3
!$&) .0369:=@CEGJMORUVY\_acfiknqsux{}??…????‘”—?????|??-°??ё??АВЕЗКМПТФЦЩЬЮбгжилортхшъэ Lavc59.18 $@ ?.3ЮЬмf яыаD р i ```
uj5u.com熱心網友回復:
此代碼假設send發件人中的單曲與收件人中的單曲相匹配recv。這個假設對 TCP 來說是錯誤的:TCP 只是一個非結構化的位元組流,而不是一個結構化的訊息傳輸,它會在發送/接收上保留訊息邊界。
這意味著data = s.recv(1024)收件人中的首字母可能不僅包括檔案名,而且可能已經包括音樂檔案的部分內容。因此,它是 utf-8 編碼檔案名(多位元組字符)和二進制音樂資料(位元組)的混合。嘗試filename = data.decode()這樣做將成功解碼初始檔案名。但它將在檔案名結束后繼續解碼資料,因此將二進制音樂資料也視為以 utf-8 編碼的多位元組字符。這將導致觀察到的解碼錯誤。
修復應該是清楚地標記檔案名結束和二進制資料開始的位置,然后僅將檔案名解碼為文本并將其余部分視為位元組。一種常見的方法是在檔案名前面加上長度,以便清楚它的結束位置。另一種方法可能是\0在檔案名的末尾添加 a (因為它不是有效 utf-8 編碼字符的一部分,除了NUL - 它本身在檔案名中無效)并在此分隔符上拆分傳入資料。
除此之外,后者data.decode()在讀取音樂資料時是完全錯誤的,因為發送方沒有匹配encode()。并且不應該有一個,因為這些是二進制資料,即已經是位元組。
uj5u.com熱心網友回復:
除了@StefanUllrich 所說的:
您在第 9 行收到二進制資料。您在第 17 行以二進制模式打開檔案。所有這些都是正確的。為什么你認為你需要將二進制資料解碼為第 18 行的字串???這就是導致您看到的例外的原因。只是不要呼叫.decode(),按原樣寫入資料!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/482898.html
上一篇:反應驗證不適用于套接字
