Lo que intento hacer es bastante simple: enviar un archivo de cliente a servidor. Primero, el cliente envía información sobre el archivo, es decir, el tamaño del archivo. Luego envía el archivo real.Problema con Python retorcido: envío de datos binarios
Esto es lo que he hecho hasta ahora:
Server.py
from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver
import pickle
import sys
class Echo(LineReceiver):
def connectionMade(self):
self.factory.clients.append(self)
self.setRawMode()
def connectionLost(self, reason):
self.factory.clients.remove(self)
def lineReceived(self, data):
print "line", data
def rawDataReceived(self, data):
try:
obj = pickle.loads(data)
print obj
except:
print data
#self.transport.write("wa2")
def main():
"""This runs the protocol on port 8000"""
factory = protocol.ServerFactory()
factory.protocol = Echo
factory.clients = []
reactor.listenTCP(8000,factory)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
Client.py
import pickle
from twisted.internet import reactor, protocol
import time
import os.path
from twisted.protocols.basic import LineReceiver
class EchoClient(LineReceiver):
def connectionMade(self):
file = "some file that is a couple of megs"
filesize = os.path.getsize(file)
self.sendLine(pickle.dumps({"size":filesize}))
f = open(file, "rb")
contents = f.read()
print contents[:20]
self.sendLine(contents[:20])
f.close()
# self.sendLine("hej")
# self.sendLine("wa")
def connectionLost(self, reason):
print "connection lost"
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def clientConnectionFailed(self, connector, reason):
print "Connection failed - goodbye!"
reactor.stop()
def clientConnectionLost(self, connector, reason):
print "Connection lost - goodbye!"
reactor.stop()
# this connects the protocol to a server runing on port 8000
def main():
f = EchoFactory()
reactor.connectTCP("localhost", 8000, f)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
El servidor simplemente muestra el objeto deserializado:
{'size': 183574528L}
¿Por qué? ¿Qué pasó con los 20 caracteres del archivo que quería enviar?
Si utiliza el "hej" y "wa" envía en su lugar, voy a obtener los dos (en el mismo mensaje, no dos veces).
Alguien?
Una cosa rara sin embargo. Si escribo los datos que recibí en el disco, siempre serán 2 bytes más que el archivo enviado. No importa qué archivo, qué tan grande o pequeño sea. El resultado siempre será anexado por 2 bytes. ¿Tienes alguna pista de lo que podría ser? – quano
Puede encontrar los archivos aquí: http://files.getdropbox.com/u/608462/simpleclient.py http://files.getdropbox.com/u/608462/simpleserv.py – quano
Por supuesto, son dos bytes más. Está utilizando sendLine para enviar un blob de datos binarios arbitrariamente grande. También está almacenando todo el contenido en la memoria y bloqueando el protocolo para el archivo IO después de recibirlo todo, y luego no reiniciando el servidor en modo línea. Todavía tiene mucho código para eliminar antes de que esto sea correcto. :) – Dustin