Ce que j'essaie de faire est assez simple: envoyer un fichier du client au serveur. Tout d'abord, le client envoie des informations sur le fichier - la taille de celui-ci. Ensuite, il envoie le fichier réel.Problème avec python Twisted - envoyer des données binaires
C'est ce que je l'ai fait jusqu'à présent:
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()
Le serveur ne sortie de l'objet désérialisé:
{'size': 183574528L}
Comment ça se fait? Qu'est-ce qui est arrivé aux 20 caractères du fichier que je voulais envoyer?
Si j'utilise les envois "hej" et "wa" à la place, je les aurai tous les deux (dans le même message, pas deux fois).
Quelqu'un?
Une chose étrange cependant. Si j'écris les données que j'ai reçues sur le disque, ce sera toujours 2 octets de plus que le fichier envoyé. Peu importe le fichier, qu'il soit grand ou petit. Le résultat sera toujours ajouté de 2 octets. Vous avez une idée de ce que cela pourrait être? – quano
Vous pouvez trouver les fichiers ici: http://files.getdropbox.com/u/608462/simpleclient.py http://files.getdropbox.com/u/608462/simpleserv.py – quano
Bien sûr, il s'agit de deux octets plus long. Vous utilisez sendLine pour envoyer un blob de données binaires arbitrairement grand. Vous mettez également tout le tampon dans la mémoire et bloquez le protocole pour le fichier IO après avoir tout reçu, puis ne pas réinitialiser votre serveur en mode ligne. Vous avez encore beaucoup de code à supprimer avant que ce soit correct. :) – Dustin