1

I'm trying to create a tool to transfer binary files in python 3 and running into an odd issue on the server side. In the server code you will see I have one line commented out which prints the data received from the client to the screen.

With this line commented out I receive the error TypeError: argument should be bytes, buffer or ASCII string, not 'NoneType' and the binary file is obviously damaged.

If I uncomment the print statement from the server code the file is transferred as expected and the binary file is received undamaged. I've tried checking for None on self.data, however, a None type is never detected.

I'm completely bewildered as to why the line "print(self.data)" is allowing the code to execute without an error. Any ideas are appreciated.

Server to receive file:

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()

Client to send file:

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 Answer 1

2

append is not in-place

bytearray(self.data).append(0): You are making the mistake in assuming that this returns a value. In reality, it just appends 0 to the array and returns nothing (I really despise this too, especially for code golf). Instead, do this for the else clause:

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

You might also be able to just do f.write(binascii.unhexlify(bytearray(self.data) + [0])) I'm not sure.

Sign up to request clarification or add additional context in comments.

12 Comments

That generated an error: binascii.Error: Non-hexadecimal digit found I replaced array.append(0) with array += b"0" which worked but, the transferred EXE file is still corrupted and would not execute. If I allow the code to print (self.data) then the file transfers properly and the file can be executed. Which is completely bizarre. I would leave it but it slows down the file transfer.
@user4573 Try += b"\u000"?
Anyway, in terms of how the file is then processed, I can't help you; I have no idea how that works. I can only help you with why there's a NoneType error
Resulted in: binascii.Error: Odd-length string
The NoneType error is not generated when #print (self.data) is uncommented. I'm at a loss at how that is playing any role in the resulting data. Thanks for your help though, it is appreciated.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.