File list gives errors when going through . Decode()

Asked

Viewed 39 times

0

In the following code for file transfer using Python sockets:

Client:

lista_arquivos = ['C:\Users\fulano\Imagens\passaro.jpg', 'C:\Users\fulano\Imagens\cachorro.jpg', 'C:\Users\fulano\Imagens\gato.jpg']

    def transferir_arquivos(self):

        for arquivo in self.lista_arquivos:
            print(arquivo)
            host = socket.gethostname()
            port = 9000
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((host, port))
            # enviado o nome do arquivo
            nome_arquivo = os.path.basename(arquivo)
            s.send(nome_arquivo.encode('utf-8'))
            # próprio arquivo enviado
            with open(f'{arquivo}', 'rb') as arq:
                print(f"Transferindo {arquivo}")
                s.send(arq.read())
                print("Arquivo enviado")
                s.close()
                arq.close()
        self.excluir_lista()

Server:

serversock = socket.socket() host = socket.gethostname() port = 9000 serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversock.bind((host, port)) serversock.listen(5)


while True:
    clientsocket, address = serversock.accept()
    print("Got a connection from %s" % str(address))
    dados = clientsocket.recv(32)
    print(dados) # mostra o conteudo de dados
    nome = dados.decode()
    print(f"Nome: {nome}")
    with open(nome, 'wb') as f:
        print('arquivo aberto')
        print('Recebendo dados...')
        data = clientsocket.recv(301149653)
        f.write(data)
        print("Enviando")
        f.close()
        print('Transferencia Completa!!!') clientsocket.close() print('conexão encerrada')

The following is returned when you arrive at the second item in the list:

Got a connection from ('meu_ip', 55159)
b'passaro.jpg'
Nome: passaro.jpg
arquivo aberto
Recebendo dados...
Enviando
Transferencia Completa!!!
Got a connection from ('meu_ip', 55160)
b'cachorro.jpg\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00`\x00`\x00\x00\xff'
Traceback (most recent call last):
  File ".\server_side.py", line 17, in <module>
    nome = dados.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 11: invalid start byte
  • I don’t usually specify encoding, but if it helps, github.com/Diolante/Server-Web-Simple-in-Python

1 answer

1


The error is that you are assuming that recv() will only receive bytes sent by a send() command. But TCP doesn’t frame the messages, it’s all a byte casing, so your recv() is getting the file name (from the first send) and also a piece of the file content (second send).

To make it work with as few changes as possible, I suggest you turn the file name into a fixed 32-byte string:

   d = arquivo.encode('utf8')
   d = d + (b" " * (32 - len(d)))
   s.send(d)

On the other side, you continue recv(32), which will receive the expected 32 bytes, and remove the spaces doing

nome = dados.decode().strip()

But bearing in mind that it is a nut solution, it will break if the file name has more than 32 characters in size. It’s just to make it work and you have something working so you can improve it. The correct is to insert some encoding in the byte casing so you know where the name ends and the content begins.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.