Tutorial 30: Transfer a File using Socket File Transfer
In the context of the Cookie Thief project we need to back up any pictures we take with our Raspberry Pi. I show you how to do that in this tutorial. In this tutorial I show you how to transfer or backup a file using Python 3, sockets and two Raspberry Pis.
This tutorial is a little older (published in 2015!). The main principles are still relevant, so I haven't needed to update this lesson.
- How to transmit a file between two computers using Python 3
You can copy / paste the code below if you’re having issues with typos or want a shortcut. However I recommend that you follow along in the tutorial to understand what is going on!
import socket from cookieLED import callLED host = '' port = 5560 def setupServer(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("Socket created.") try: s.bind((host, port)) except socket.error as msg: print(msg) print("Socket bind comlete.") return s def setupConnection(): s.listen(1) # Allows one connection at a time. conn, address = s.accept() print("Connected to: " + address + ":" + str(address)) return conn def storeFile(filePath): picFile = open(filePath, 'wb') print("Opened the file.") pic = conn.recv(1024) while pic: print("Receiving picture still.") picFile.write(pic) pic = conn.recv(1024) picFile.close() def dataTransfer(conn): # A big loop that sends/receives data until told not to. while True: # Receive the data data = conn.recv(1024) # receive the data data = data.decode('utf-8') # Split the data such that you separate the command # from the rest of the data. dataMessage = data.split(' ', 1) command = dataMessage if command == 'GET': reply = GET() elif command == 'REPEAT': reply = REPEAT(dataMessage) elif command == 'STORE': print("Store command received. Time to save a picture") storeFile(dataMessage) reply = "File stored." elif command == 'LED_ON': callLED() reply = 'LED was on' elif command == 'EXIT': print("Our client has left us :(") break elif command == 'KILL': print("Our server is shutting down.") s.close() break else: reply = 'Unknown Command' # Send the reply back to the client conn.sendall(str.encode(reply)) print("Data has been sent!") conn.close() s = setupServer() while True: try: conn = setupConnection() dataTransfer(conn) except: break
import socket from time import sleep from time import time host = '192.168.2.2' port = 5560 def setupSocket(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) return s def sendPic(s, filePath): print(filePath) pic = open(filePath, 'rb') chunk = pic.read(1024) s.send(str.encode("STORE " + filePath)) t = time() while chunk: print("Sending Picture") s.send(chunk) chunk = pic.read(1024) pic.close() print("Done sending") print("Elapsed time = " + str(time() - t) + 's') s.close() return "Done sending" def sendReceive(s, message): s.send(str.encode(message)) reply = s.recv(1024) print("We have received a reply") print("Send closing message.") s.send(str.encode("EXIT")) s.close() reply = reply.decode('utf-8') return reply def transmit(message): s = setupSocket() response = sendReceive(s, message) return response def backup(filePath): s = setupSocket() response = sendPic(s, filePath) return response
import P3picam import picamera from datetime import datetime from subprocess import call from time import sleep from cookieClient3 import backup from cookieAnalog2 import getTemp motionState = False picPath = "/home/pi/Desktop/cookie/images/" sleepTime = 3 triggerTemp = 20 def captureImage(currentTime, picPath): # Generate the picture's name picName = currentTime.strftime("%Y.%m.%d-%H%M%S") + '.jpg' with picamera.PiCamera() as camera: camera.resolution = (1280, 720) camera.capture(picPath + picName) print("We have taken a picture.") return picName def getTime(): # Fetch the current time currentTime = datetime.now() return currentTime def timeStamp(currentTime, picPath, picName): # Variable for file path filepath = picPath + picName # Create message to stamp on picture message = currentTime.strftime("%Y.%m.%d - %H:%M:%S") # Create command to execute timestampCommand = "/usr/bin/convert " + filepath + " -pointsize 36 \ -fill red -annotate +700+650 '" + message + "' " + filepath # Execute the command call([timestampCommand], shell=True) print("We have timestamped our picture.") def tempMonitor(): print("About to take a reading.") temp = float(getTemp()) print("Out temp is: " + str(temp)) if temp > float(triggerTemp): message = "LED_ON" print("Transmitting data.") response = transmit(message) print(response) while True: currentTime = getTime() picName = captureImage(currentTime, picPath) print("Took a picture") completePath = picPath + picName print(completePath) backup(completePath) print("Everything should be backed up now.") break #motionState = P3picam.motion() #tempMonitor() #sleep(sleepTime) #print(motionState) #if motionState: # currentTime = getTime() # picName = captureImage(currentTime, picPath) # timeStamp(currentTime, picPath, picName)