Datei binär kopieren
-
Das kann man so machen und es wird funktionieren und es ist (bis auf die Paketgröße) auch die übliche Methode.
-
Verhält es sich tatsächlich so, das die Daten in 64k Blöcken verschickt wird?
-
Auf den unteren Ebenen des Schichtenmodells schon, doch sind nicht alle Bytes deine Daten, da ist noch einiges an Verwaltungskram dabei.
Doch so mit um die 30-40 bytes deiner eigenen Daen kannst du schon rechnen.Das hängt halt damit zusammen dass sichergestellt werden muss, dass ein Sender lange genug schreibt bis die Daten in der Theorie die größte Strecke in einem Segment zwei mal zurücklegen können, halt hin und zurück und zwar noch bevor der Sender mit schreiben fertig ist.
Falls dich sowas interessiert mal ein Paar Begriffe zum nachschlagen:
Jam Signal, CSMA/CD, Ethernet, Ethernetframe, payload, Netwerk segment
ISO OSI SchichtenmodellSo genau kenne ich mich da jedoch auch nicht aus.
Zum einen gilt das so wie hier nur in klassichen Ethernet umgebungen (worum es sich bei so gut wie jedem "normalen" Heimnetzwerk wohl noch handeln dürfte) und zum anderen ist es ziemlihc lange her alsich mich zuletzt damit beschäftigt habe, weswegen das eventuell auch schon veraltet sein kann, ka.
Bin halt kein Techniker.EDIT:
Aber das sind jetzt keine Werte mit denen man ohne tiefere Ahnung wirklich rumrechnen kann.
Diese Ethernetframes sind was anderes als TCP Pakete und sobald du diese komischen Dinger ins Internet loslässt wo ja die Sendetechnik geändert ist, wird der ganze Kram nochmal in ganz anderen Kram umgewandelt.
-
Ah okay. Vielen Dank für die Informationen.
Ich schaus mir gleich mal an.
-
Also. Ich habe jetzt eine Methode gefunden, eine Datei zu kopieren. Dafür benutze ich folgenden Code:
ifstream DateiLesen ("C:\\read.exe", ios::binary); ofstream DateiSpeichern ("C:\\save.exe", ios::trunc | ios::binary); DateiSpeichern << DateiLesen.rdbuf (); DateiSpeichern.close (); DateiLesen.close ();Das ganze klappt auch, jedoch weiß ich nicht, wie ich das auf mein Client Server Modell übertragen kann.
-
Du musst die Datei schon in irgendeine Datenstruktur einlesen, die du dann in Pakete packst und verschickst. Ein char Array bietet sich für so etwas an.
Pseudocode Server:
Datei öffen; Schicke ein Signal an Client, dass es losgeht; So lange noch nicht Dateiende erreicht { Lese ein Stückchen der Datei in char Array; Verschicke char Array; } Schicke ein Signal an Client, dass fertig;Pseudocode Client:
Wenn Signal zum loslegen empfangen{ So lange bis Endsignal empfangen { Empfange Paket; Hänge Paketinhalt an Datei an; }
-
Ja, das klingt sinnvoll, jedoch war ich mir nicht sicher ob dies funktioniert.
Kannst du mir sagen, wie ich ein einzelnes Zeichen (oder Zeichenblöcke) aus einer Datei kopieren kann?
-
DerCoder schrieb:
Kannst du mir sagen, wie ich ein einzelnes Zeichen (oder Zeichenblöcke) aus einer Datei kopieren kann?
Entweder ist die Antwort trivial oder ich verstehe nicht, was du meinst. Weißt du etwa nicht wie man aus Dateien liest?
-
Doch doch, das weiß ich schon
Nur frage ich mich ob es schnell genug ist, wenn ich eine Zeile aus der Datei auslese und sie komplett versende oder immer nur substrings...*edit*
Okay es klappt
Ich war mir nicht sicher. Vielen Dank für deine Hilfe.*edit2*
Lol, doch nicht.
Ich benutze folgenden Code um die Datei Blockweise zu verschicken:ifstream fileIn("C:\\programmIn.exe", ios::binary); while (!fileIn.eof ()) { string stringFileBuffer (""); char buffer[64]; fileIn.read (buffer, sizeof(buffer)); stringFileBuffer = buffer; MyMessObj.SendMessagePort (stringFileBuffer); } fileIn.close ();und zum empfangen:
// im header bereich: ofstream fileOut ("C:\\programmOut.exe", ios::trunc | ios::binary); // im rec thread: char temp[4096]; int iStat; iStat = recv (sRecSocket, temp, sizeof (temp), 0); if (iStat == -1) { m_vClientList.remove (sRecSocket); return 1; } else { string InputMessage (temp); fileOut.write (InputMessage.c_str (), sizeof(InputMessage.c_str ())); fileOut.flush (); } // programm ende: fileOut.close ();Die erstellte Datei ist allerdings nur 1KB groß.
-
Der Fehler liegt bei dir in der Umwandlung von char* nach string: der Konstruktor string(char
erwartet einen null-terminierten C-String!!!Und der zweite Fehler: der Rückgabewert von 'recv' gibt die Anzahl der gelesenen Bytes an, d.h. kopiere die Daten direkt:
int count = recv(...); if(count >= 0) { fileOut.write (temp, count); }Edit: Tippfehler...
P.S. habe gerade noch deinen 3. Fehler entdeckt: sizeof(InputMessage.c_str ())
Überleg mal, welcher (konstante) Wert da raus kommt...
-
Arg. Ist mir nichtmal aufgefallen.
Die Datei kommt allerdings immernoch nicht komplett an:iStat = recv (sRecSocket, temp, 4096, 0); if (iStat >= 0) { fileOut.write (temp, iStat); fileOut.flush (); }
-
Du hast beim Senden den selben Fehler drin (char * -> string)!!!
-
Hilft auch nicht wirklich ...
*edit*
Ich hab jetzt anstattfileOut.write (temp, iStat);fileOut.write (temp, 64);ausprobiert. Die Datei kommt jetzt sogar noch größer an, als die Quelledatei ist.
-
Ich schrieb: Senden !!!
stringFileBuffer = buffer; MyMessObj.SendMessagePort (stringFileBuffer);Ändere deine Methode SendMessagePort so ab, daß sie einen char-Zeiger und eine Größe erhält, also:
MyMessObj.SendMessagePort (buffer, fileIn.gcount());Vllt. solltest du dich ersteinmal mit den Unterschieden zwischen ASCII und Binär sowie std::string und C-Strings auseinandersetzen, um auch den Code zu verstehen...
-
Hmm okay. Das hatte ich nicht bedacht. Vielen Dank für deine Geduld.