Was ich versuche zu tun, ist ziemlich einfach: Senden Sie eine Datei von Client zu Server. Zuerst sendet der Client Informationen über die Datei - die Größe davon. Dann sendet es die eigentliche Datei.Problem mit Twisted Python - Senden von Binärdaten
Das ist, was ich bisher getan habe:
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()
Der Server wird nur dann ausgegeben, das deserialisiert Objekt:
{'Größe': 183574528L}
Wie kommt es? Was ist mit den 20 Zeichen aus der Datei passiert, die ich senden wollte?
Wenn die "hej" und "wa" stattdessen senden, bekomme ich sie beide (in der gleichen Nachricht, nicht zweimal).
Jemand?
Eine seltsame Sache obwohl. Wenn ich die Daten auf die Festplatte schreibe, sind es immer 2 Bytes mehr als die gesendete Datei. Es spielt keine Rolle, welche Datei, wie groß oder klein sie ist. Das Ergebnis wird immer um 2 Bytes ergänzt. Hast du eine Ahnung, was das sein könnte? – quano
Sie können die Dateien hier finden: http://files.getdropbox.com/u/608462/simpleclient.py http://files.getdropbox.com/u/608462/simpleserv.py – quano
Natürlich sind es zwei Bytes länger. Sie verwenden sendLine, um ein beliebig großes binäres Daten-Blob zu senden. Sie puffern auch die gesamte Sache in den Speicher und blockieren das Protokoll für Datei-IO, nachdem Sie alles empfangen haben, und setzen Ihren Server dann nicht in den Zeilenmodus zurück. Sie müssen immer noch viel Code entfernen, bevor dies korrekt ist. :) – Dustin