[Python-de] Dateien ueber Sockets uebertragen
Hartmut Goebel
h.goebel at goebel-consult.de
Fre Apr 2 10:50:37 CEST 2004
Hi,
Alexander 'boesi' Bösecke wrote:
> Oh tut mir leid, hatte das CC uebersehen. Aber wieso hab ich dann die
> Mail nicht auch ueber die Liste bekommen? *kopfkratz*
Weil Du nicht über die Liste geantwortet hattest. :-)
So, wir machen jetzt eine kleine Coaching, für das andere Leute 150 EUR
die Stunde zahlen (leider nicht bei mir ;-). Beantworte dazu die
folgenden Fragen:
* Welche Daten fehlen _genau_?
* Was kannst Du tun um dieses festzustellen? Was noch? (Sprich:
Alternativen zum Sniffer)
* Ist die schon das minimale Beispiel, bei dem der Fehler auftritt?
* Was ist das maximale Beispiel, bei dem der Fehler nicht auftritt?
* Welche Zeile(n) unterscheiden das Beispiel, bei dem der Fehler
auftritt, von einem Beispiel, bei dem der Fehler nicht mehr auftritt?
...
...
Erst nach Beantwortung der Fragen weiterlesen
...
...
...
> Ich hab Analyzer (ein Sniffer) die Kommunikation belauschen lassen.
Und was ist das Ergebnis? Ich bezweifle, dass Du das was brauchbares
sehen kannst, wenn Du gepickelte Daten verschickst. Benutze plain Text,
das erleichtert die Arbeit -- auch wenn das Probelm dann erstmal nicht
macht, was es soll.
> Der Server nutzt folgenden Code zum Senden:
Irgendwie scheint mir da was zu fehlen. Für die Zunkunt: Bitte baue
einen minimalen Server und einen minimalen Client, bei dem das Problem
auftritt, und poste die beiden Quelltexte vollständig.
> Den Clienten scheinen beim "file_size = cPickle.loads(self.sockobj.recv
> (self.BlockSize))" die überzähligen Daten jedenfalls nicht zu stören,
> der wirft die mal ebend weg.
Lies Dir nochmal durch, was Du da schreibst! Denn das ist doch genau die
Lösung des Problems.
Du liest 'blocksize' (Annahmen = 1024) Bytes, die unpickles Du und für
unpickle sind nur die ersten vieleicht 5 Bytes interessant. Mit dem Rest
weiß unpickle nichts anzufangen.
> Folgendes hilft auch nicht:
> temp = cPickle.dumps(file_size)
> self.connection.send(temp)
> Dieses send(temp) und das nachfolgende send(data) werden irgendwie
> miteinander vermanscht.
Überlege nochmal scharf: Oben schreibst Du, dass unpickle die Daten
wegwirft. Weshalb hoffst Du dann, das Problem beim _Empfang_ zu lösen,
wenn Du beim _Senden_ eine Variable mehr benutzt? Sollten sich dann die
übertragenen Daten ändern? Doch sicher nicht.
Lösungsvorschläge (alles Skizzen, die dümmsten zuerst):
1) Beim Absender:
data = self.sockobj.recv(self.BlockSize)
# filesize lesen
file_size = cPickle.loads(data)
# Länge der zu gehörigen Daten ermitteln
len_data = len(cPickle.dumps(file_size))
# abschneiden
data = data[len_data:]
2) Beim Sender:
self.connection.send(cPickle.dumps(file_size))
self.connection.send('\n')
Beim Empänger:
data = self.sockobj.recv(self.BlockSize)
file_size, data = data.split('\n',1)
file_size = cPickle.loads(file_size)
3) Beim Sender:
self.connection.send('%s\n' % file_size)
Beim Empänger:
data = self.sockobj.recv(self.BlockSize)
file_size, data = data.split('\n',1)
file_size = int(file_size)
4) Und das schlage ich wirklich vor:
Benutze SimpleHTTPServer oder BaseHTTPServer und du brauchst Dich
um diese Probleme nicht zu kümmern. Der Vorteil von Standards ;-)
Wenn Du komplexere Protokolle hast, wären die XMLRPC-Server auch
eine gute Möglichkeit.
> Wie schon gesagt, lokal funktioniert alles, leider scheint Analyzer kein
> localhost zu kennen.
Analyzer -> Tonne. BTW, welcher ist das?
--
Regards
Schönen Gruß
Hartmut Goebel
| Hartmut Goebel | IT-Security -- effizient |
| h.goebel at goebel-consult.de | www.goebel-consult.de |