[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    |