Cuando busqué este tema en Internet, encontré solamente información acerca de envío de strings. Finalmente consulté la guia oficial y unas listas de correo hasta que consegui la misión.
Entonces, convengamos que queremos enviar la instancia de una clase (objeto), en C esto es facil, solo debemos crear una estructura en el programa cliente, otra idéntica en el servidor y enviarlas en una sola linea (el sistema se encargará de gestionar los paquetes segmentados). Pues bien, en Python debemos convertir este objeto en cadenas de texto y luego esta cadena de texto enviarla por el socket.
El modulo encargado de codificar el objeto se llama pickle, si como esas cosas bañadas en vinagre. Existe una implementación mucho mas eficiente llamada CPickle.
Bién, el cliente envia este archivo de texto mediante socket, luego en el servidor al recibirlo y convertirlo nuevamente en un objeto (por medio de Pickle), mágicamente este entiende de que se trata y podemos utilizar los métodos asociados y declarados en el cliente sin “declarar nada en la otra maquina (servidor)”.
Esa es la idea, ahora veamos el código necesario (convengamos que este es un estracto de un programa mas grande, por eso hay cosas que no están relacionadas con el artículo):
El Cliente (que envía en objeto):
import os
import dato
import operacion
import pickle
import archivos
def enviar(conex, archivo, accion,ruta,nombre,nombre_antiguo):
Objeto_accion = operacion.crear_operacion(ruta, nombre, accion,nombre_antiguo) #Creo objeto.
archivos.Crear_archivo_objeto(Objeto_accion) #La funcion para crear un archivo de texto.
Archivo_objeto=archivos.Leer_archivo_objeto()
l = Archivo_objeto.read()
print len(l)
conex.send(str(len(l))) #Envio tamanio de objeto
conex.send(l) #Envio el objeto
#conex.send('Fin de objeto') #Aviso Fin de objeto
if accion=='crear':
Binario_a_enviar = archivo
while 1:
l2 = Binario_a_enviar.read(1024)
conex.send(l2)
print len(l2)
if len(l2)<1024:
break
archivos.Cerrar_archivo(Binario_a_enviar)
print 'Archivo respaldado'
conex.close()
Archivo_objeto.close()
archivos.Cerrar_archivo(Archivo_objeto)
Parte del archivo servidor:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import conectar
import dato
import pickle
import archivos
import os
Borrado=''
while 1:
con = conectar.crear_conexion()
con.SetServidor(9999)
conex=con.Get_socket_servidor()
f = file('outputfile', 'wb')
l = conex.recv(3)
print 'Recibiendo largo de l= ', l
if len(l)>0:
buff=int(l)
print 'L recibido'
l = conex.recv(buff)
f.write(l)
f.close()
#l = conex.recv(13)
f = file('outputfile', 'rb')
x = pickle.load(f)
if x.GetAccion()=='renombrar':
print 'Nombre nuevo: ',x.GetNombre()
print 'Nombre antiguo: ', x.GetNombreAntiguo()
print 'Nombre antiguo: ', x.GetAccion()
Borrado=''
os.rename(os.path.join('config/', x.GetNombreAntiguo()),os.path.join('config/',x.GetNombre()))
Estructura del objeto (llamado desde el cliente como “operacion”):
class operacion: def __init__(self, ruta, nombre, accion,nombre_antiguo): self.ruta=ruta self.nombre=nombre self.accion=accion self.nombreAntiguo=nombre_antiguo def GetRuta(self): return self.ruta def GetNombre(self): return self.nombre def GetAccion(self): return self.accion def GetNombreAntiguo(self): return self.nombreAntiguo def crear_operacion(ruta, nombre, accion, nombre_antiguo): return operacion(ruta, nombre, accion,nombre_antiguo)
Funciones para convertir el objeto a texto, llamado desde el cleinte como “archivo”:
def Crear_archivo_objeto(Objeto):
Archivo = open('config/config.rlp', 'wb')
pickle.dump(Objeto, Archivo)
Archivo.close()
def Leer_archivo_objeto():
Archivo = open('config/config.rlp', 'rb')
return Archivo
Comentarios