Pregunta

Lo que intento hacer es bastante simple: enviar un archivo del cliente al servidor. Primero, el cliente envía información sobre el archivo, el tamaño que tiene. Luego envía el archivo real.

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 solo generará el objeto deserializado:

{'size': 183574528L}

¿Cómo es que? ¿Qué pasó con los 20 caracteres del archivo que quería enviar?

Si usa el " hej " y "wa" envía en su lugar, los recibiré a ambos (en el mismo mensaje, no dos veces).

¿Alguien?

¿Fue útil?

Solución

Ha configurado su servidor en modo sin procesar con setRawMode (), por lo que la devolución de llamada rawDataReceived se llama con los datos entrantes (no lineReceived). Si imprime los datos que recibe en rawDataReceived, verá todo, incluido el contenido del archivo, pero cuando llama a pickle para deserializar los datos, se ignora.

O cambia la forma en que envía los datos al servidor (sugeriría el formato de red) o pasa el contenido dentro del objeto serializado en escabeche, y lo hace en una sola llamada.

self.sendLine(pickle.dumps({"size":filesize, 'content': contents[:20]}))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top