python-3.x - 在 python3 中通过 tcp 套接字发送不同的文件类型,给出 'UnicodeDecodeError'
问题描述
编写一个小型应用程序,让我可以在家中通过 LAN 网络共享文件,尽可能减少头痛,所以我想支持所有文件扩展名。
发送文本文件时,我使用 .encode() 和 .decode() 函数,它工作得很好,但是当尝试发送其他内容(每个视频)时,它返回以下错误:
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 47: character maps to <undefined>
有没有办法按原样发送文件?无需编码?提到我尝试在没有 .encode() 的情况下发送文件,它返回完全相同的错误。
编码:
def sendfile(file, client):
try:
fd = open(file, 'r')
except:
_media_error('Can not open specific file for sending')
return 0
resp = client.recv(128).decode()
# other side is ready, give them the info
if resp == '[ack]':
buf = fd.read(_readsize)
while buf:
#client.send(buf.encode())
client.send(buf)
buf = fd.read(_readsize)
fd.close()
client.send('[done]'.encode())
return 1
else:
fd.close()
return 0
def recvfile(file, client):
try:
fd = open(file, 'w+')
except:
_media_error('Can not open specific file for receiving')
return 0
# ready give me the info
client.send('[ack]'.encode())
#buf = client.recv(_readsize).decode()
buf = client.recv(_readsize)
while buf:
if buf != '[done]':
fd.write(buf)
buf = client.recv(_readsize)#.decode()
else:
fd.close()
return 1
return 0
(忽略杂乱的回报,我稍后会修复这些)
解决方案
由于您通过网络发送字节,因此最简单的方法是专门使用字节。
以二进制模式打开文件,不要对文件数据进行编码或解码。您仍然需要对您的确认/完成消息进行编码。
def sendfile(file, client):
try:
fd = open(file, 'rb')
except:
_media_error('Can not open specific file for sending')
return 0
resp = client.recv(128)
# other side is ready, give them the info
if resp == '[ack]'.encode():
buf = fd.read(_readsize)
while buf:
#client.send(buf)
client.send(buf)
buf = fd.read(_readsize)
fd.close()
client.send('[done]'.encode())
return 1
else:
fd.close()
return 0
def recvfile(file, client):
try:
fd = open(file, 'wb+')
except:
_media_error('Can not open specific file for receiving')
return 0
# ready give me the info
client.send('[ack]'.encode())
#buf = client.recv(_readsize)
buf = client.recv(_readsize)
while buf:
if buf != '[done]'.encode():
fd.write(buf)
buf = client.recv(_readsize)
else:
fd.close()
return 1
return 0
这种方法假设网络上的所有机器共享相同的字节序。
此外,如果您在具有不同默认编码的机器之间传输,您可能需要考虑特殊大小写的文本文件。例如,Windows 机器倾向于将 cp1252 作为默认的现代 Linux UTF-8。在这种情况下,您需要确定用于传输的默认编码,并在每一侧处理切换编码。
推荐阅读
- sql - 在 Postgres 中执行 SELECT 语句时,如何从 JSONB 字段中获取 JSON 对象列表而不是 ID 列表?
- javascript - 不和谐音乐机器人循环
- google-analytics - 如何在我的网站中使用 API 显示 Google Analytics
- c - 为什么需要使用精确的返回地址来执行 shellcode?
- flutter - dart/flutter BMI 代码返回 bmi 值,但其他值错误
- python - 两个语句返回两个不同结果时的MYSQL存储过程优化
- flutter - 在 Flutter 中部署 ML 分类模型
- vue.js - 似乎无法通过 Vue 中的道具将数据传递给组件
- ios - 如何运行和编译 SPM 以查看结果
- python - 将元组元组转换(和反转)为字典时出错