Dateitransfehr
-
ich will meinem programm sagen das er ne datei von server zu client schicken soll. hab ich auch schon alles getestet. aber das klappt nur bei *.txt -dateien !! ich mache das so (code habe ich von codeguru
):Server:
void SendFile() { #define PORT 34000 /// Select any free port you wish AfxSocketInit(NULL); CSocket sockSrvr; sockSrvr.Create(PORT); // Creates our server socket sockSrvr.Listen(); // Start listening for the client at PORT CSocket sockRecv; sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection CFile myFile; myFile.Open("C:\\ANYFILE.EXE", CFile::modeRead | CFile::typeBinary); int myFileLength = myFile.GetLength(); // Going to send the correct File Size sockRecv.Send(&myFileLength, 4); // 4 bytes long byte* data = new byte[myFileLength]; myFile.Read(data, myFileLength); sockRecv.Send(data, myFileLength); //Send the whole thing now myFile.Close(); delete data; sockRecv.Close(); }Client:
void GetFile() { #define PORT 34000 /// Select any free port you wish AfxSocketInit(NULL); CSocket sockClient; sockClient.Create(); // "127.0.0.1" is the IP to your server, same port sockClient.Connect("127.0.0.1", PORT); int dataLength; sockClient.Receive(&dataLength, 4); //Now we get the File Size first byte* data = new byte[dataLength]; sockClient.Receive(data, dataLength); //Get the whole thing CFile destFile("C:\\temp\\ANYFILE.EXE", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); destFile.Write(data, dataLength); // Write it destFile.Close(); delete data; sockClient.Close(); }er kopiert die datei ja nicht, sondern ließt die datei aus und sendet die zeichen an den client, der sie dann in eine datei schreibt. oder sehe ich das falsch !?
wenn nein, kennt jemand eine saubere methode um dateien vernünftig zu senden und sie danach noch benutzen zu können ??
-
Hm, der Code scheint richtig zu sein. Müsste also bei jeder Datei funktionieren.
Die SendFile-Funktion liest die Datei Byteweise ein und schickt diese Bytes an den Client, der diese empfangenen Bytes in GetFile in eine Datei schreibt.
Es wird der Datentyp char verwendet, da er genau 1 Byte groß ist.
Allerdings solltest du den Code nicht so verwenden, da z.B. jegliche Art von Fehlerüberprüfung fehlt. Außerdem solltest du (zumindest bei größeren Dateien) die Klasse CAsyncSocket anstatt CSocket verwenden.Grüße Rapha
-
ja, hast recht. das funktioniert ja auch wirklich alles: die dateien kommen auch alle an, egal welche ich suche. nur wwenn ich die dateien dann öffnen will, kann er keine (ausser textdateien) öffnen. das ist genau so als ob du direkt ein bitmap mit dem editor öffnest und dann diesen ganzen müll den er dann ausgibt speicherst. er machts halt genau so wie du gesagt hast !!
aber kennst du auch ne funktion die die dateien so ´von server zu client überträgt, als ob man eine datei wirklich kopiert (mit datei markieren -> kopieren drücken -> wo anders einfügen drücken) und nicht ausließt !?
-
die Funktionen machen nichts anderes als eine Datei über das Netzwerk zu kopieren (was denn sonst
).
Wenn die Datei nicht richtig geöffnet werden kann, dann liegt es an der falschen Dateiendung, die du ihr gegeben hast. Denn wer öffnet schon ein Bitmap mit Notpad?
Grüße Rapha
-
ne, ne. du verstehst nicht was ich meine

ich will die datei vom server zum client senden. wenn ich das mache, dann ließt der server die einzelnnen zeichen aus der datei aus, kopiert sie über das netzwerk zum client und der schreibt alles zeichen für zeichen in eine datei. ich nenne die datei, die ich übertragen hab jetzt mal genau so wie die ausgangsdatei. wenn ich die neue datei dann aber öffne kann er mir ja gar nichts vernünftiges ausgeben. WEIL: er hat den ASCII-code in eine datei geschrieben, genau so als ob man den ganzen kran der da in der datei steht selbst eingeben würde, verstehste was ich meine !?? desswegen kann er doch auch nur normale text-datien korrekt wiedergeben.ich will aber nicht das er die datei zeichen für zeichen dareinschreibt, ich will das er 1 zu 1 kopiert. wenn du eine normale datei in windows kopierst dann schreibt er auch nicht den inhalt den er aus der quelldatei ließt in eine neueangelegte datei und gibt ihr nen entsprechenden dateinamen, abgeletet vom dateinahmen der quelldatei.
ich suche nur ne funktion die genau so kopiert über das netzwerk wie windows das macht.
*puh* das kann man doch jetzt nur noch so verstehen wie ich das meine, oder ?! :D:D
-
Yea

Du hast was falsch verstanden
Du öffnest die Zieldatei (auf dem Client) eindeutig im Binärmodus.
Dann wird nämlich der Parameter data vondestFile.Write(data, dataLength); // Write itnicht als ASCII-Zeichencodes interpretiert, sondern als das, was er eigendlich ist: ein Array von Bytes.
Glaubs mir doch endlich :pGrüße Rapha
-
ja, äh

also kopiert er das schon so wie ich das haben will oder wie !?aber wenn ja: warum kann er die übertragenden dateien nicht öffnen ??
-
Red Skall schrieb:
also kopiert er das schon so wie ich das haben will oder wie !?
Genau

Red Skall schrieb:
aber wenn ja: warum kann er die übertragenden dateien nicht öffnen ??
Wer kann die Dateien nicht öffnen? Du? Das Programm? Existiert die kopierte Datei?
Grüße Rapha
-
wenn ich z.b. eine datei vom verser emfangen hab, kann ich sie nicht öffnen. also wenn ich doppelklick halt auf die emfangene datei machen will
-
Welche Dateiendung hat die Datei?
Was kommt für ein Fehler, wenn du sie öffnest?
-
ist bi allen dateien schätze ich mal die normalerweise nicht im ASCII-format gespeichert werden. aber ich hab zum test ne *.bmp übertragen. eigentlich sind auf dem bild 2 frauen
drauf, und das ist in farbe. wenn ich das bild dann öffne, ist das ganze bild grau !! als ich ne übertragene *.mpg file mit dem windowsmediaplayer öffnen wollte, hat er gesagt das er nicht abspielen kann weil ein unbekannter fehler festgestellt wurde
-
hm, stimmen die Dateigrößen überein?
Der Code ist eigendlich in Ordnung (schon allein deswegen, weil er von Codeproject ist)...
-
Hi,
also das Problem wurde bei Codeguru schon besprochen.
Erst soll es daran gelegen haben,d ass die Dateien größer 10KB
bzw 100Kb waren. Dann hat einer ne Lösung gepostet:http://www.codeguru.com/Cpp/I-N/network/winsocksolutions/comments.php/c2491/?thread=33146
http://www.codeguru.com/Cpp/I-N/network/winsocksolutions/comments.php/c2491/
I changed my "GetFile" function to the one below to get executables to work. ///////////////////////////////////////////////////////////////////////////// void GetFile() { #define PORT 34000 /// Select any free port you wish AfxSocketInit(NULL); CSocket sockClient; sockClient.Create(); // "127.0.0.1" is the IP to your server, same port sockClient.Connect("127.0.0.1", PORT); int dataLength; sockClient.Receive(&dataLength, 4); //Now we get the File Size first CFile destFile("C:\\output.exe", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); byte* data = new byte[dataLength]; int recvBytes = 0; recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it while (recvBytes > 0) { recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it } destFile.Close(); delete data; sockClient.Close(); } /////////////////////////////////////////////////////////////////////////////Ich habs damals auch mal probiert, aber ich glaube es hat nicht so wirklich
geklappt
Good Luck. Wenn es geht bitte ganzen Code hier posten
-
Hm,
Hab zwar noch nie mit CSocket gearbeitet, aber ich finde den Code komisch.Er schreibt einfach alle Bytes bis auf die 1. 4 in eine Datei

Es könnte sein (weiß nicht genau), dass Teile der Pakete verloren gehen.
Start mal den Server und den Clienten auf dem gleichen Rechner und versuche so zu kopieren.
-
hab ich schon gemacht, euf gleichem rechner zu testen. kommt aber das selbe ergebnis raus
. danke für das beispiel von codeproject @Kristof. probiere ich gleich mal aus, muß nur noch was eben im garten machen
...[EDIT]
Ok, habs getestet und siehe da ... es geht :D. danke danke !!
-
Na dann Glückwunsch. Kannst du Client + Server bitte mal hier posten ?
Wäre nett, denn bei mir (oh Wunder) gehts noch nicht. Und die Frage
nach dem Dateitransfer wird sicher noch öfter kommen
-
oh sorry, hast ja gesagt ich solls posten. ok hier ist der code:
(ach ja.: ich habe nur was am client geändert, nichts am server !!)Aber trotzdem der code vom server:
CSocket sockSrvr; CSocket sockRecv; CFile fFile; int iFileLength; AfxSocketInit(NULL); // FILESEND_PORT = port für übertragung sockSrvr.Create(FILESEND_PORT); sockSrvr.Listen(); // hier dem client mitteilen das er den transfehr starten soll, zumindest ist es so bei meinem programm if (sockSrvr.Accept(sockRecv)) { // cFSend_File = quellfile fFile.Open(cFSend_File, CFile::modeRead | CFile::typeBinary); iFileLength = fFile.GetLength(); sockRecv.Send(&iFileLength, 4); // 4 bytes long byte* data = new byte[iFileLength]; fFile.Read(data, iFileLength); sockRecv.Send(data, iFileLength); //Send the whole thing now fFile.Close(); delete data; sockRecv.Close(); } else { // fehlermeldung ausgeben ... }client:
AfxSocketInit(NULL); CSocket sockClient; sockClient.Create(); // cInformation1 = ip adresse, FILESEND_PORT = port für übertragung if (sockClient.Connect(cInformation1, FILESEND_PORT)) { int dataLength; sockClient.Receive(&dataLength, 4); //Now we get the File Size first // cFSend_File = zielfile CFile destFile(cFSend_File, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); byte* data = new byte[dataLength]; int recvBytes = 0; recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it while (recvBytes > 0) { recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it } destFile.Close(); delete data; sockClient.Close(); } else { // fehlermeldung ... }das müsste aber auch bei dir laufen !? ich hab den code auch 1 zu 1 übernommen von codeguru. habe nur die entsprechenden variablen bei mir geändert
-
Hi,
ich halte folgenden Code immer noch für Doppeltgemoppelt
Red Skall schrieb:
int recvBytes = 0; recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it while (recvBytes > 0) { recvBytes = sockClient.Receive(data, dataLength); //Get the whole thing destFile.Write(data, recvBytes); // Write it }Könnte das noch jemand klären/erklären?

-
ich habe mal ne doofe frage,
ich habe die beiträge kurz und sehr leicht überflogen..ich habe es so verstanden die Dateien können nicht korrekt geöffnet werden?
vieleicht liegt an der Länge der Datei, du benutzt nen Int fuer die Länge der Datei...
kann ja sein das der int überläuft bzw. nicht die genaue grösse der Bytes besitzt die geschickt werden sollen?
ich benutze ein DWORD und habe keine probs....MfG
T1c4L
-
Yea, das könnte eine Lösung sein und würde auch erklären
- warum Textdateien erfolgreich geschickt werden können (sie sind so klein, dass es keinen Überlauf gibt)
- warum der Doppelmoppelcode funktioniertandererseits: das int ist signed und wird bei einem Überlauf negativ, was bei folgendem Code Probleme macht: new byte[dataLength]; (Access Violation)
Es müsste schon ein verdammter Glücksfall sein, dass die Dateien gerade so groß werden, dass dataLength bei einem Überlauf wieder positiv wird.
-
word das find ich auch mekrwürdig... da sollte mindestens abstürzen wenn er nen überlauf bekommen sollte...
mhmm ich mache das so ähnlich, aber halt nicht zwischen server/client...
der CFile::Write() braucht als buffer nen const* void.... kann sein das er negative auch nimmt? und deswegen kein fehler auftritt?