Ошибка Python TypeError: аргумент должен быть байтами, буфером или строкой ASCII, а не NoneType

Я пытаюсь создать инструмент для передачи двоичных файлов в Python 3 и столкнулся с нечетной проблемой на стороне сервера. В коде сервера вы увидите, что я закомментировал одну строку, которая печатает данные, полученные от клиента, на экран.

С этой закомментированной строкой я получаю ошибку TypeError: аргумент должен быть байтами, буфером или строкой ASCII, а не NoneType, и бинарный файл явно поврежден.

Если я раскомментирую оператор печати из кода сервера, файл будет передан, как ожидалось, и бинарный файл получен неповрежденным. Я попытался проверить None в self.data, однако тип None никогда не обнаруживается.

Я совершенно сбит с толку, почему строка "print(self.data)" позволяет коду выполняться без ошибок. Любые идеи приветствуются.

Сервер для получения файла:

import socketserver, argparse, sys, binascii
class tcpReceiver(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(4096).strip()
        if self.data.startswith(b"snd:"):
            self.file = self.data.split(b":")[1]
            print ("Receiving File: " + str(self.file, "utf-8"))
            with open(self.file, 'wb') as f:
                while self.data:
                    self.data = self.request.recv(4096).strip()
                    #print (self.data)
                    if len(self.data) % 2 == 0:
                        f.write(binascii.unhexlify(self.data))
                    else:
                        f.write(binascii.unhexlify(bytearray(self.data).append(0)))
        print ("File Received.")
        return

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("port", action="store", help="port", type=int)      
    args = parser.parse_args() # Declare argumnets object to args
    host, port = "", args.port
    server = socketserver.TCPServer((host, port), tcpReceiver)
    server.serve_forever()

Клиент для отправки файла:

import socket
import sys, os, argparse, binascii

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("host", action="store", help="remote host", type=str)
    parser.add_argument("port", action="store", help="remote port", type=int)
    parser.add_argument("file", action="store", help="file to send", type=str)
    args = parser.parse_args() # Declare argumnets object to args
    HOST, PORT = args.host, args.port
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))
    path, file = os.path.split(args.file)
    sock.sendall(b"snd:" + bytes(file, "utf-8"))
    with open(args.file, 'rb') as f:
        dat = f.read(4096)
        while (dat):
            if dat:
                sock.sendall(binascii.hexlify(dat))
            dat = f.read(4096)
    sock.close()

1 ответ

append не на месте

bytearray(self.data).append(0): Вы делаете ошибку, предполагая, что это возвращает значение. На самом деле, он просто добавляет 0 в массив и ничего не возвращает (я действительно презираю это тоже, особенно для кода гольф). Вместо этого сделайте это для else пункт:

array = bytearray(self.data)
array.append(0)
f.write(binascii.unhexlify(array))

Вы также можете просто сделать f.write(binascii.unhexlify(bytearray(self.data) + [0])) Я не уверен.

Другие вопросы по тегам