File Transfer in Python 3
In this post, we’ll check out file transfer in Python 3 with file size verification check.
In many Python scripts you’ll come across the need for sending and receiving files over the network, so I decided to make this tutorial for a simple yet stable set of scripts to implement whenever needed.
We’ll only use standard Python libraries included with a default installation: socket, time, os and sys.
One nice little detail we’ll implement is file size verification, so that the receiving party can be sure they received the file with the exact amount of bytes the sender intended.
Let’s check it out!
Download Scripts
To begin, download both scripts from the link above and make sure you have Python installed.
Server Side
First we’ll take a look at the server side script:
import socket,time,os # Server configuration host = '0.0.0.0' # Listen on this host port = 4420 # Main port to listen on d = socket.socket(socket.AF_INET, socket.SOCK_STREAM) d.bind((host, port)) d.listen(1) s,a = d.accept() f = s.recv(1024) z = f.decode() if z.endswith("=EOFX="): x = str(z).split() e = str(x[1]) n = str(" ".join(x[2:-1])) print("-- Receive file: " + n + " (" + e + ")") g = open(n, 'wb') while True: l = s.recv(1024) try: if l.decode().endswith('=EOFX=') == True: break except: pass g.write(l) g.close() if e == str(os.path.getsize(n)): print(">> Size verified.") else: print("!! Size mismatch.") s.close()
The script itself is very straightforward:
- Create a socket
- Listen for a connection
- Receive initial payload: “FILE: [length] [filename]”
- Create a new file in binary write mode
- Start writing the received bytes to file
- Close the file once receiving is completed
- Verify that bytes of written file match size from initial payload
I go into more detail on the video above, line by line, so feel free to check it for more insight.
Client Side
Now let’s take a look at the client side:
import socket,time,os,sys PORT = 4420 if len(sys.argv) > 2: host = str(sys.argv[1]) file = str(' '.join(sys.argv[2:])) else: print("> Usage: filesend.py host file") sys.exit() # Configure socket connection z = socket.socket(socket.AF_INET, socket.SOCK_STREAM) z.connect((host, PORT)) flen = str(os.path.getsize(file)) fstr = 'FILE: ' + flen + ' ' + os.path.basename(file) + ' =EOFX=' print("- Send file: " + file + " (" + flen + ")") z.send(fstr.encode()) time.sleep(1) try: with open(file, 'rb') as f: fileData = f.read() # Begin sending file z.sendall(fileData) time.sleep(4) z.send('=EOFX='.encode()) f.close() print('>> Transfer: ' + file + ' complete.\n') except: print('> Error sending file: ' + file + '.\n')
Alright let’s break it down:
- Check for required arguments: host and file
- Create a socket and connect to supplied host and port
- Get file name and length and send initial payload
- Open file in binary read mode and read it to memory
- Send entire file over the socket we created
- Once finished, send delimiter so server knows we’re done
- Print message out to user and exit out of the script
That’s it for this tutorial, hope ya learned something new and I’ll see ya next time! 😉
Leave a Comment