Bild in Bytestrom umwandeln und über Sockets verschicken
-
Hallo,
ich habe 2 Sockets (clienet/Server) die mit einander kommuniztieren können. Jetzt will ich ein Bild in einen Bytestrom umwandeln und es dann über diese Verbindung verschicken.
Wie mache ich das am Besten. Was haltet ihr von Base64-Kodierung?Vielen Dank
E
-
Von Base64 halte ich viel, für diesen Anwendungszweck halte ich jedoch nichts davon, Base64 zu verwenden.
Lies die Bilddatei in Blöcken ein und verschick diese über den Socket. Warum Rechenzeit und Bandbreite an Base64 verschwenden

-
Base64 ist also zu aufwendig. Wie zerlege ich denn das Bild in Blöcke und wie setzte ich es nachher wieder zusammen?
Vielen Dank!
-
du liest es mit fstream::read() blockweise ein, schickst die einzelnen Blöcke jeweils durch's Netz und speicherst sie wieder mit fstream::write().
-
tcp/ip bzw. die sockets sorgen schon selber für pufferung und zerstückelung in pakete. man braucht nix nochmal in blöcke zerlegen. einfach verbindung öffnen, daten senden, verbindung schliessen - fertig. genau so einfach, als würde man in eine datei schreiben.
-
@net:
Wenn das Programm intelligent geschrieben ist wirst Du aber nicht z.B. 1,53 MB an Daten in einem char-array vorliegen haben, sondern eben in Blöcken einlesen.
-
Hallo,
beim Verschicken der Pakete *musst* du beachten:
Die Sockets entscheiden sich selbstständig in wie großen Paketen sie deine Daten schicken. Faustregel: Alles was größer als 1KB groß ist *kann* in mehreren Stücken ankommen. Deshalb musst du dir noch Gedanken über ein eigenes Übertragungsprotokoll machen und die Daten selber wieder zusammenflicken.
-
Du meinst wohl größer als 1 Byte. :p
-
Und das bedeutet jetzt konkret, dass ich mir keine Gedanken machenm muss, wie ich das Bild zerlege.
Ich habe jetzt geschrieben:
char list[255]; int gelesen; FILE* bild; if( (bild = fopen( "C:\\blue_horse_col.bmp","a+" )) != NULL ) { gelesen = fread( list, sizeof( bild ), sizeof (bild) , bild ); cout << "Number of items read = " << gelesen << endl; cout << "Contents of buffer = " << list << endl; fclose( bild ); } else cout << "File could not be opened" << endl;das sollte mir doch dann eigentlich in "bild" das Bild gelegt haben und jetzt muss ich "bild" rüberschicken?
Und was mache ich dann auf Serverseite?
Vielen Dank
E
-
Die Fragen, die einige User dort stellen, sind so strunzdumm, dass es mir das Essen aus dem Magen treibt. Manchmal frag ich mich wirklich wie diese Kreaturen es ueberhaupt geschafft haben, sich in einem Board zu registrieren?!
-
ach und ich erhalte eine ganz seltsame Ausgabe:
Number of Items read: 4
Contents of Buffer: BM@[e]pi[/e] "Herz"Hmmm ?? Woran liegt das?
Thanx
E.
-
dein fread()-Aufruf stimmt nicht so ganz:
gelesen=fread(list/*Ziel*/,sizeof(list)/*Anzahl Datensätze*/,1/*Größe eines Datensatzes (char=1 Byte)*/,bild);(und außerdem solltest du das ganze in eine Schleife packen, die solange liest und sendet, bis du ans Dateiende (feof(bild)) kommst)
PS: hinter 'bild' steckt eine Datenstruktur, mit deren Hilfe dein System die Datei einlesen kann - der zu übertragende Datenblock steht in 'list' (und die Länge hat fread() als Antwort zurückgegeben).
PPS: Auf der Gegenseite mußt du die einzelnen Blöcke empfangen und mit "fwrite(list,empfangen,1,bild);" in deine Zieldatei speichern - auch wieder in einer Schleife, solange etwas über die Leitung kommt.
-
CStoll (off) schrieb:
dein fread()-Aufruf stimmt nicht so ganz:
gelesen=fread(list/*Ziel*/,sizeof(list)/*Anzahl Datensätze*/,1/*Größe eines Datensatzes (char=1 Byte)*/,bild);(und außerdem solltest du das ganze in eine Schleife packen, die solange liest und sendet, bis du ans Dateiende (feof(bild)) kommst)
Das habe ich getan:
char list[255]; int gelesen; FILE* bild; if( (bild = fopen( "C:\\blue_horse_col.bmp","a+" )) != NULL ) { while(!feof(bild)){ gelesen = fread( list, sizeof( list ), 1 , bild );} cout << "Number of items read = " << gelesen << endl; cout << "Contents of buffer = " << list << endl; fclose( bild ); } else cout << "File could not be opened" << endl;Als Ausgabe erhalte ich :
Numbers of Item read : 0
Contents of Buffer: I ς blalba Irgendwelche kryptischen Sachen.
Schicke ich "bild" rüber bevor ich fclose sage?vielen Dank E
-
Erstens: Wenn du lesen willst, öffne die Datei doch als "rb" (read, binär).
Zweitens: Daß die Ausgabe etwas kryptisch aussieht, braucht dich nicht zu stören - BMP-Dateien sind in einem Format, daß nicht unbedingt leserlich aussieht
Drittens: Du mußt den Inhalt von list über das Netzwerk schicken (jeweils in der Schleife).
-
ich habe da a+ durch rb ersetzt und jetzt habe ich :
Number of read Items: 0
Content of Buffer:Da steht jetzt nichts..............
-
Ja, du gibst ja auch den letzten Block aus, den du lesen wolltest - da feof() erst anschlägt, nachdem das LEsen fehlgeschlagen ist, ist das ein leerer Block.
while(!feof(bild)) { gelesen=fread(list,sizeof(list),1,bild); send(list,gelesen);//hier kommt die Socket-Funktion zum senden rein //Debug-Ausgaben: cout<<"gelesen:"<<gelesen<<endl; cout<<"Daten :"<<list<<endl; } fclose(bild);
-
Headhunter schrieb:
Deshalb musst du dir noch Gedanken über ein eigenes Übertragungsprotokoll machen und die Daten selber wieder zusammenflicken.
quatsch, das macht tcp/ip alles schon selber.
-
Headhunter meinte wohl sowas wie HTTP, FTP oder IRC.
-
super super....
Vielen vielen Dank....
Es tut soweit.Wie kann ich mir jetzt aber auf Serverseite das Bild darstellen lassen um zu testen, ob es auch wirklich da ist?
-
FILE* bild=fopen("...","wb"); empfangen=1; while (empfangen>0) { recv(list,empfangen);//hier wieder die Socket-Funktion zum empfangen eintragen fwrite(list,empfangen,1,bild); //Debug-Ausgaben: cout<<"gelesen:"<<empfangen<<endl; cout<<"Daten :"<<list<<endl; } fclose(bild);(Die Debug-Ausgaben sollten das selbe anzeigen wie auf der Senderseite - außerdem kannst du dir hinterher das empfangene und gespeicherte Bild im Explorer aufrufen)