El script consta de un cliente y un servidor. Está escrito en catalán, pero es perfectamente inteligible.
Cliente:
Código
# enviar.py v1.2 # -*- coding: cp1252 -*- # --------------- # Changelog: # + Diccionaris # + Avisos de lectura i transferencia # + Funcions de mida d'arxiu # importamos los modulos necesarios: import socket, os # definimos el puerto de control CPORT y el puerto multimedia MPORT CPORT = 9091 MPORT = 9090 # una funcion para transformar un tamaño en bytes a un tamaño más fácil de leer: def midafap(mida): sufixos = [("B",2**10), ("K",2**20), ("M",2**30), ("G",2**40), ("T",2**50)] for suf, lim in sufixos: if mida > lim: continue else: return round(mida/float(lim/2**10),2).__str__()+suf print "Enviar arxius per INTRnet!" # un diccionario, esto es por comodidad mía # pedimos dónde estamos: el instituto, casa, o solo, para probar cosas sel = raw_input("Indica el host remot(institut, casa, sol): ") insdic = {"FAPFAPFAP" : '192.168.171.12', "FAPFAP" : '192.168.171.17', "FAP" : '192.168.171.19'} casadic = {"SERVER" : '192.168.1.34'} soldic = {"Me" : 'localhost'} # ahora tenemos un diccionario dentro de otro: bigdic = {"institut" : insdic, "casa" : casadic, "sol" : soldic} final = bigdic[sel] print final # si hemos elegido "institut", nos dirá las IPs y escribimos FAPFAPFAP. sel2 = raw_input("Indica el host remot de la llista: ") HOST = final[sel2] # el archivo en sí FILE = raw_input("Arrossega l'arxiu: ") # cambiamos comillas, para evitar errores en los archivos con espacios: FILE = FILE.replace('"', '') # creamos un socket que envía la ruta del archivo: cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # se conecta al puerto de control: cs.connect((HOST, CPORT)) # envía la ruta del archivo: cs.send("SEND " + FILE) cs.close() # otro socket, que envía el archivo: ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # se conecta al puerto multimedia: ms.connect((HOST, MPORT)) # abrimos el archivo para leerlo: f = open(FILE, "rb") data = f.read() f.close() # obtenemos el tamaño del archivo, en bytes: midabytes = os.path.getsize(FILE) # usamos la función anterior para convertir el tamaño: # Archivo guarra.fap leído (682,13M) print "Arxiu ", FILE, "llegit (", str(midafap(midabytes)), ")." # enviamos los datos del archivo: ms.send(data) ms.close() # fin print "Arxiu ", FILE, "enviat (", str(midafap(midabytes)), ")." raw_input("Prem una tecla per tancar...")
Servidor:
Código
# rebre.py # importamos módulos, unos cuantos más... import os, socket, time, string, sys, urlparse from threading import * #------------------------------------------------------------------------ # creamos un objeto de tipo StreamHandler: class StreamHandler ( Thread ): #creamos un inicializador: def __init__( this ): Thread.__init__( this ) # nos referimos al objeto mismo def run(this): this.process() #aquí tenemos un método que nos muestra que estamos trabajando con objetos de tipo socket. def bindmsock( this ): this.msock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # enlazamos el "this" al puerto 9090 (Multimedia): this.msock.bind(('', 9090)) this.msock.listen(1) print '[INTR] Esperant al port 9090' def acceptmsock( this ): # aceptamos la conexión... this.mconn, this.maddr = this.msock.accept() print '[INTR] Ieepa, es connecta', this.maddr def bindcsock( this ): # enlazamos al puerto 9091 (Control): this.csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) this.csock.bind(('', 9091)) this.csock.listen(1) print '[Control] Esperant al port 9091' def acceptcsock( this ): # aceptamos... this.cconn, this.maddr = this.csock.accept() print '[Control] Ieepa, es connecta', this.maddr while 1: # captamos datos: data = this.cconn.recv(1024) if not data: break # si los datos recibidos empiezan por SEND, captamos el nombre de archivo if data[0:4] == "SEND": this.filename = data[5:] print '[Control] Preparat per rebre "%s"' % this.filename break def transfer( this ): print '[INTR] Transferint dades de "%s"' % this.filename # captamos solamente el nombre de archivo y su extensión: nomfinal = os.path.basename(this.filename) # lo guardamos en el directorio de Recibido f = open("C:/INTRnet/Rebut/"+nomfinal,"wb") # ahora, el bucle que captura datos en sí: while 1: data = this.mconn.recv(1024) if not data: break f.write(data) f.close() # hemos escrito los datos en el nuevo archivo print '[Media] Rebut "%s"' % this.filename print '[Media] Tancant el flux de "%s"' % this.filename os.popen("msg.exe * S'ha rebut l'arxiu "+ nomfinal) # y ya hemos recibido el archivo! def close( this ): # cerramos todos los sockets: this.cconn.close() this.csock.close() this.mconn.close() this.msock.close() def process( this ): # siempre aceptamos las conexion while 1: this.bindcsock() this.acceptcsock() this.bindmsock() this.acceptmsock() this.transfer() this.close() #------------------------------------------------------------------------ # creamos un objeto StreamHandler: s = StreamHandler() # usamos el método de Thread (dentro del módulo threading) para iniciar: s.start() #fin
Eso es todo. Funciona de maravilla en redes locales, y por IP pública o No-IP también
El problema viene en los archivos con acentos, que dan error. Haré un filtro para eliminar los carácteres.
Cualquier duda, comentad!