You know that sockets are a low level of network programming, are not they? It's a point where you have to worry about each byte read, send messages - etc ... are so complex details, that in the real world, there are protocols built on the sockets to abstract details.
So I could give you an example of how to save a file listening on the raw socket here - but it would be something complicated - we would have to devise an 'ad hoc' protocol - if only to know when the file name be saved had arrived - and at least one field to know the size of the file.
Well, HTTP is the protocol used by the Web, which puts a good number of abstractions into the messages - it specifies headers, and "Post" methods - so using the Flask framework, for example, would be possible make a minimalist application just to save files with maybe 5 or 6 lines in total. But this implementation would still require you to retrieve the data and content of the body of the HTTP message, which is like what is posted on a form on a web page - has some more bureaucracy.
Python, however, has long-standing versions of a remote method call server that responds to HTTP, and encodes the parameters of the methods as XML transparently. This is in the python library under "xmlrpc". The Python implementation is from a more "innocent" time - it does not consider anything security - and in Python 2, no data conversion as well. By switching to Python3, using Python's xmlrpc got a bit more bureaucratic - some considerations of server consistency and conversion of text-etnram data into game - but it's still going to be orders of magnitude simpler than doing an equivalent implementation in Sockets . (Just about 5 times simpler than deploying on sockets without any security considerations, etc ...).
Note that an XMLRPC server will respond to any request without any type of authentication - not even a static token - so if you are not on a closed network between your client and server, it is best to use Flask or Pyramid to put some authentication - and set up an HTTP server up front, such as NGINX to provide encryption by https for your data. (But if the two machines are on the internet, read about creating "ssh tunnels" - it's going to be a lot simpler and safer than putting a web-server with authentication just for that. server to allow connection to the xmlrpc port only through the tunnel.)
With this in mind, Python XMLRPC server example to save a file in the "date /" folder ( adapted from official documentation ):
from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
from xmlrpc.client import Binary
# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)
# Create server
with SimpleXMLRPCServer(("0.0.0.0", 8010), allow_none=True,
requestHandler=RequestHandler) as server:
#server.register_introspection_functions()
def save_image(name, content):
# Dados do tipo "bytes" chegam aqui wrapped na classe "Binary"
if isinstance(content, Binary):
content = content.data
with open("data/" + name.replace("..", ""), "wb") as file_:
file_.write(content)
server.register_function(save_image, "save_image")
server.serve_forever()
And to use "save_image" on your client, as if it were a call to a local method, these three lines are enough:
import xmlrpc.client
s = xmlrpc.client.ServerProxy('http://localhost:8010')
s.save_image(<nome_do_arquivo como string>, <conteudo do arquivo como bytes>)
Note that although very insecure, I still put a "replace" in the name to avoid a very simple type of attack in which the name of the image is put paths of type "../../etc/shadow" o which would overwrite the system password configuration file (if xmlrpc is running as root, of course).