Ich übertrage über Tcp eine Bild-Datei, es funktioniert auch alles, außer, das der empfänger der Datei in der Schleife zum empfangen der einzelnen blocks hängen Bleibt
@ceddy: Woher soll der Empfänger wissen wann die Daten zuende sind? Du müsstest beim Sender nach den letzten Daten das `socket` schliessen, sondern wartet der Empfänger ewig ob da noch etwas kommt.
@ceddy: Dann musst Du Dir ein Protokoll ausdenken bei dem der Sender dem Empfänger kommunizieren kann wie viele Daten er lesen muss oder wann er aufhören kann. Woher soll der Empfänger, wie schon gefragt, sonst wissen wann die Daten für das eine Bild zu Ende sind?
@ceddy: Die Bytewerte für die Zeichenfolge EOF könnten auch zufällig irgendwo in den Daten vorkommen. Ausserdem darfst Du nicht davon ausgehen, dass die Daten immer in 1024 Byte grossen „Häppchen” ankommen, nur weil Du sie in diesen Grössen beim Sender an die `socket`-API übergibst. Und selbst wenn dem so wäre, kann Dein Code nur funktionieren wenn die Byteanzahl der Bilddaten genau durch 1024 teilbar wäre, denn nur dann würde *genau* das EOF am Ende für einen einzigen `recv()`-Aufruf übrig bleiben.
Aber da Du sicherstellen musst, dass eine Endmarkierung niemals innerhalb der Nutzdaten vorkommen kann, ist das sowieso keine gute Idee. Besser Du überträgst am Anfang wie viele Daten zu dem Bild gehören. Und beim Empfänger musst Du auch damit rechnen mehr zu lesen — nämlich schon den Anfang vom nächsten Bild beziehungsweise die Daten, die sagen wie gross das ist (+ ein bisschen vom Anfang des Bildes).
Anstelle vom BMP-Format könntest Du auch über PNG nachdenken — das komprimiert besser. Sofern BMP überhaupt komprimiert ist.
#
# Sender
#
data = ImageGrab.grab().tostring('png')
self.socket_file.write('%d\n' % len(data))
self.socket_file.write(data)
self.socket_file.flush()
#
# Empfänger
#
size = int(self.socket_file.readline())
image_data = self.socket_file.read(size)
if len(image_data) != size:
raise ValueError('incomplete image received')
with open('ss.png', 'wb') as image_file:
image_file.write(image_data)
Wobei `self.socket_file` das Ergebnis eines `makefile()`-Aufrufs auf dem ursprünglichen Socket ist. Denn sonst wird das ganze komplizierter, weil man sich mit den der Socket-API herumschlagen muss. Dein senden war bisher zum Beispiel nicht robust, weil `socket.send()` nicht garantiert, dass auch wirklich alle Daten gesendet werden die man übergibt. Man muss sich den Rückgabewert anschauen und gegebenenfalls `send()` so lange mit den jeweiligen Restdaten aufrufen, bis auch wirklich alles raus ist.