Написание небольшого приложения, которое позволяет мне обмениваться файлами по локальной сети дома с максимально возможной головной болью, поэтому я хочу поддерживать все расширения файлов.
При отправке текстового файла я использую функции .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
(Не обращайте внимания на грязные возвраты, я исправлю их позже)





Поскольку вы отправляете байты по сети, проще всего работать исключительно с байтами.
Открывайте файлы в двоичном режиме и не кодируйте и не декодируйте данные файла. Вам все равно нужно будет закодировать сообщения ack/done.
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. В этой ситуации вам необходимо выбрать кодировку по умолчанию для передачи и обработать кодировку переключения на каждой стороне.
Да я только что понял это! Я был в середине написания ответа: D Большое спасибо