Enviar objetos por socket con Python

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

Deje un comentario


NOTA - Puede usar estosHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>