Bildübertragung übers Netzwerk mit Boost
-
Ja also ich habe natürlich um mir die arbeit einfach zu machen, erstmal auch versucht einfach zu sagen "übertrage die ganze Datenstruktur" - fertig. aber das hat letztlich wie gesagt dazu geführt dass ich feststellen musste, Bilddaten am anfang des puffers wurden von folgenden Sendungen überschrieben. Dies fand ich schon ziemlich dämlich da ich den Puffer groß genug für das ganze Bild festgelegt hatte. dies bestätigte sich dann als ich eine kleinere Größe übertragen lies, dann hatte ich schon mal Bilddaten, die aber wie gesagt nicht stimmen. Ich wunderte mich nämlich warum nur 0-Werte ankamen und mutmaßte, dass die 2 Hälfte des Bildes, die beim Client schwarz ist, da er sie nicht berechnet, diese den Puffer bei mehreren Sendungen überschrieben, das heisst man muss die Daten nach jedem Read vom Netz auswerten und zwischenspeichern.
Was die Farbkanäle anbetrifft. Es wird pro Farbe ein Float verarbeitet. Man kann z.b. bei OpenGL mit FloatFunktionen mit Werten zwischen 0..1 arbeiten oder ByteFunktionen. Bei der Netzwerkprogrammierung fiel mir wegen der Übertragung von Bytes dies als Nachteil auf. Arbeitet man mit Floats hat man pro Farbe 4 das sind also 12 Byte. Arbeitet man mit Bytes braucht man nur 3. Ich springe auch nicht um ein Byte weiter sondern um ein PixelObjekt. Und da ich von Bytes wieder in Floats umwandeln muss, verwende ich die 3 Bytes in Folge und rechne sie in Floats um die wieder in einem Pixelobjekt gespeichert werden. Ich werde noch nen Link posten zu den Bildern, dann kann man sich die Ergebnisse mal angucken. Was halt sehr komisch ist, dass als ich das Programm am nächsten Tag gestartet hatte ohne was dran zu ändern, die gesendeten Bilddaten noch mehr Fehler aufwiesen und wie gesagt, auf der Kommandozeile stimmen die Werte auch auf den beiden Rechnern nicht überrein auf den ersten Blick.
-
dir ist klar das TCP/IP ein Stream ist d.h. die Daten kommen nicht zwangsläufig als 1 Read so wie du sie gesendet hat - es kann sein das es x Pakete werden bis dein Sendung vollständig empfangen wurde
schreib doch erstmal ein kleines Testprogramm das nur Testdaten sendet und damit validierst du erstmal deine Kommunikation - nicht das noch aus anderen Richtungen Probleme kommen
-
Also ich habe jetzt noch folgendes ausprobiert. Ich habe statt der Pixelobjekte den Pixelstream, den ich versende, am Client ausgegeben... da wird er fast komplett richtig angezeigt. bei Reflexionen im Bild scheint es noch kleine Unstimmigkeiten zu geben. Aber auf dem Server wird nach jedem Durchlauf ein anderes bild angezeigt.
-
so bin jetzt nochmal ein Stück weiter gekommen. Es gibt in dem Readhandler ein Parameter der beschrieben wird nach jedem Read der lautet bytes_transferred. Damit lässt kann ich den Pixelstream scheinbar schonmal halbwegs korrekt abspeichern. Ich erhalte jetzt ein Bild wo die Muster schon mal korrekt sind, aber die Farben noch nicht stimmen. Und wenn ich das Programm noch mal laufen lasse, kriege ich auch die gleichen Ergebnisse. Reflexionen und Objekte sind schon mal an der richtigen Position. Es ist also doch ganz wichtig, sich hier an diesen Parameter bei größeren Datenmengen zu halten, anstelle davon auszugehen, dass der Buffer von ganz allein korrekt beschrieben wird.
-
Klingt so, als würdest du bei der Serialisierung und/oder Deserialisierung deines Bildformats einen Fehler machen. Hat vermutlich etwas mit dem Zeug zu tun, das du da mit den floats anstellst.
-
joa habs gelöst. sogesehen war es ein datentyp Umwandlungsfehler und das Problem beim asynchronen Senden im Netz, wodurch unterschiedlich viele Bytes je Durchlauf versendet worden sind, ich aber immer grundsätzlich davon ausging, dass 1460 Bytes ankämen. Man kann sich bei Boost wenn man sagt, transferiere 1460 Bytes, nicht darauf verlassen dass diese auch in einem Zug empfangen werden. Bei größeren Datenmengen muss man auf jeden Fall den Paramter bytes_trasferred auswerten im Read-Handler, der sich ja immer wieder aufgerufen wird. Ich hatte schließlich nachdem ich versucht hatte, Werte von 0..255 die in den Wertbereich, durch den erst als Char Buffer festgelegten Puffer, -127..128 rutschen wieder zurück zu wandeln, einfacher war es aber einfach das ganze als unsigned char festzulegen. Jetzt läuft es, bis auf ein paar Pixel ist alles korrekt. Und jetzt brauch ich nur noch ne Netzwerkfarm und kann auf beliebig vielen Rechnern nach ein paar Frontend-Anpassungen mit späterem zentralen Deployment und Steuerung zu der totalen Netzwerkapp machen

-
Durch nicht Auswertung der transferred_bytes kamen also Bildverschiebungen zustande, durch den verschobenden Wertebereich Farbfehler.
-
Jetzt, wo du diese Fehler gefunden hast, machst du es am besten noch einmal so, wie du es am Anfang hattest, also ohne dein eigenes Streamingprotokoll über dem eigentlichen Streamingprotokoll zu implementieren.
-
[quote]Man kann sich bei Boost wenn man sagt, transferiere 1460 Bytes, nicht darauf verlassen dass diese auch in einem Zug empfangen werden.
das liegt nicht an Boost sondern an dem TCP/IP-Protokoll, jeder TCP/IP-Stack zeigt dieses Verhalten (egal ob Windows, Linux,...) - das ist so gewollt und voellig normal
Bei größeren Datenmengen muss man auf jeden Fall den Paramter bytes_trasferred auswerten
man muss IMMER den bytes_trasferred Parameter auswerten - mit der Datenmenge hat das nichts zu tun, sollte deine TCP/IP-Verbindung ueber ein sehr schlechte Leitung laufen kann das auch (überspitzt) byteweise raus/reintröpfeln
-
noch Tips zur Performanz-Steigerung:
-der Netzwerk-Transport koennte z.B. auch ueber UDP laufen
da koennte die Latenz geringer sein-mit mehreren Threads in deinem Prozess rechnen (Multi-Threading)
-deine Rechnung auf mehrere Prozesse aufteilen (Multi-Processing) - weil jeder Prozess bekommt vom Scheduler ja nur die CPU-Zeit x - mehrere Prozesse lasten deine CPU besser aus