Dateien über Winsock versenden



  • msp schrieb:

    hi,

    also wie ich weiss kannst du files auch binaer oeffnen (zb fopen("datei","b") und dann sollte es einfach sein die datei zu uebertragen. du musst glaub ich aber noch was mit newlein beachten oder so, nur als tip. versuch mal, wuerde mich auch interessieren obs geklappt hat.

    Ja das hab ich auch ausprobiert, das klappt aber bei mir nur, wenn Datei nicht größer als Buffer am andere Ende ist, also wenn gleich alles auf einmal in buffer eingelesen und versendet werden kann. bei mir 1024. Klar kann man das ändern aber nicht doch auf 5-10MB. Hier muß ich entweder Buffer dynamisch anlegen, oder Datei in kleine(1024Byte) Stücke zerlegen und blockweise versenden. Mich würde mal die zweite Methode gern interresieren.
    Hat vieleicht jemand Ideen oder fertige Codebeispiele dazu ???
    Danke.



  • Du darfst die Buffer nur eben nicht als Strings interpretieren, da er sonst "fälschlicherweise" NUL-Zeichen findet. Ansonsten sollte das doch eigentlich nicht anders sein, als bei Strings. Du musst dir eben einen genügend großen Buffer anlegen, in dem du die Datei aus den einzelnen Paketen wieder zusammen setzt 🙂



  • Hier http://www.activevb.de/tipps/vb6tipps/tipp0287.html

    befindet sich ein gute Beispiel dazu, aber es ist in VB geschrieben.
    Weiss jemand wo so änliches in C/C++, finden kann???

    Wie ich Datei blockweise versende ist mir klar, mir ist aber nicht klar wie
    ich auf der Zielseite die Daten wieder zusammensetze...

    need help.....................



  • Hmm...

    Mit folgenden Infos solltest Du doch selber weiterkommen, oder?

    - Du kennst die Größe der zu versendenden Datei
    - send() gibt als Rückgabewert die Anzahl der gesendeten Bytes zurück
    - man kann in einer while()-Schleife so lange send aufrufen, bis die Größe der Datei verschickt wurde

    Ansonsten könnt ich Dir ein WinSock-Tutorial anbieten: www.c-worker.ch



  • cool, cool 😉

    hmm, also ich hab eine ganze file auch noch nie verschickt..
    die datei binär zu öffnen is ja schon mal ganz gut,
    und dann ne schliefe bis die größe erreicht ist.
    naja beim empfänger würd ich probieren die einzelnen pakete wie bauklötze aufeinander zu stapeln. d.h. ich bekomm meinetwegen ein paket aus 512 bytes.. das nächste paket klatsch ich einfach drauf im buffer usw.
    nur.. woher weiss ich was für ne file das überhaupt war ? ich würde dann einfach erstmal den dateinamen als string verschicken, der empänger legt dann so eine datei ersmal an und wenn das senden fertig ist, schreibt der empfänger die bytes in die leere xyz.bmp datei z.b.
    vielleicht sollte man noch die größe übermitteln, damit der empfänger mit malloc und realloc die größe des buffers immer anpassen kann...
    des wär mein erster versuch 😉
    also..
    -größe senden
    -dateiname senden (lol.exe z.b)
    -pakete senden

    wie gesagt, hab sowas noch nie gemacht..

    mfg
    haMMer



  • Hi

    Nunja wenn alles nichts hilft (obwohl es definitiv geht. FTP machts ja auch.).
    Kannst du aus deiner Binärdatei einfach nen String machen. Stichwort ist da Base64. Damit macht sich das Zerteilen in Stücke auch gut, weil es ein Blockformat ist.



  • Wenn du die einzelnen Pakete direkt in die Datei schreibst brauchst du eigentlich gar nicht wissen, wie groß sie ist, oder 😕



  • hi

    flenders hat ganz recht. ich vermute mal du wills ne datei uebertragen, d.h. kopieren ueber netzwerk. dann lass dir zuerst den namen der datei uebermitteln, oeffne sie binaer zum schreiben und in einer schleife kopierst du dann halt jedes zeichen rein, dann is es egal wie gross die datei ist.



  • Hallo,

    also folg. Beispiel funzt bei mir einwandfrei, falls es hier jemanden interesiert...

    Sender (sprich: Client) sendet File

    void SendFile()
    { 
     HANDLE hFile;
     char FileName[] = "C:\\test.exe";
     char *Buff;
     int FileSize      = 0;   bekannt sein 
     DWORD BytesRead   = 0;
    
     hFile = CreateFile(FileName, GENERIC_READ, NULL, NULL,  OPEN_EXISTING,NULL,NULL);
     FileSize = GetFileSize(hFile, NULL);
     Buff = new char[FileSize];
    
     ReadFile(hFile,  (void *)Buff, FileSize, &BytesRead, NULL);
    
     send(sock, Buff, FileSize, 0);  // sending file
    
     CloseHandle(hFile);
     delete [] Buff;
    }
    

    Empfänger (sprich: Server) empfängt File

    void ReciveFile()
    {
     HANDLE hFile;
     char FileName[] = "C:\\NEW_FILE.exe";";// Muß vor dem Aufr. CreateFile() bekannt sein
    
     char *Buff;
     DWORD BytesWritten    = 0;
     int FileSize          = 0;// <<< Dateigröße muß vor dem Aufruf WriteFile 
    
     recv(sock, Buff, FileSize, 0);
    
     hFile = CreateFile(FileName, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL);
     WriteFile(hFile, (void *)Buff, FileSize, &BytesWritten, NULL);
    
     CloseHandle(hFile);
     delete [] Buff;
    }
    

    Also wie gesagt dieses Beispiel funzt bei mir nur, weil ich von Anfang an weiss, wie groß der Datei ist, und wie er heisst. Am sonsten sollte man
    wirklich erst die Name und FileSize an der Server senden, damit der Server weiss
    was für ein File mit CreateFile()zu erstellen ist, und wieviele Bytes mit WriteFile() rein geschrieben werden soll.
    Also bevor man die Funktionen einsetzten kann, muß man sie so ändern, dass der Server erst alle nötige Inf. bekommt ( Name+Size).



  • Du kannst die Datei doch auch block-weise einlesen, dann brauchst du eigentlich nicht vorher zu wissen, wie groß sie ist 🙄



  • Zumal ich bezweifle, das Du so eine Datei auf einen Schlag übers Internet verschickt bekommst...

    Du wirst bei größeren Dateien auf schrittweises Versenden umstellen müssen!

    Und warum für's Datei versenden 2 Funktionen schreiben, dann kannste die kleinen auch schrittweise verschicken... so wärste immer auf der sicheren Seite...



  • Hepi schrieb:

    Zumal ich bezweifle, das Du so eine Datei auf einen Schlag übers Internet verschickt bekommst...

    Du wirst bei größeren Dateien auf schrittweises Versenden umstellen müssen!

    Und warum für's Datei versenden 2 Funktionen schreiben, dann kannste die kleinen auch schrittweise verschicken... so wärste immer auf der sicheren Seite...

    Da hast du Recht, es ist kein gute Methode um große Dateien zu versenden.
    Da sollte man lieber doch Datei in Stücke zu teilen, um ihn dann blockweise zu schicken. Dann geht es wie bei allen FileSharing Programmen, und zwar so lange nicht alle Teile da sind bleibt der Datei in Temp-Ordner 😃

    Da sich aber paar Leuten auch um Mögligkeit Dateien über Winsock zu versenden
    interesierten, hab ich den Code gepostet 😉

    Ob es optimal oder gut ist ist in Moment nicht wichtig 😉
    Es funktioniert einfach, basta 😉



  • Du brauchst auf jeden Fall ein Protokoll (FTP ist auch ein Protokoll!). Der Empfänger sollte ja wissen, was für eine Datei ankommt und wie groß die ist, damit er weiß, wann die Übertragung beendet ist. Meines Wissens hat die Größe deiner eigenen Puffer nichts mit den systeminternen Puffern zu tun, über die letztlich das Senden und Empfangen erfolgt, so daß du über das Zusammenbasteln der einzelnen Datenblöcke auf Empfangsseite nicht umhinkommst.

    Rob'


Anmelden zum Antworten