Senden einer Datei



  • Hallo,

    per Winsock also TCP/IP,

    leider kann ich aber nicht mehr als 1 000 000 chars reservieren.

    mfg



  • Hier mal mein Source:

    #include <stdio.h>
    #include <windows.h>
    
    int download(void)
    
    {
    
    unsigned int i=0;
    
    char buffer[1000000];
    
    FILE *datei;
    datei=fopen("C:\\test.wav","r+b");
    FILE *dest;
    dest=fopen("C:\\ergebnis.wav","w+b");
    
     if(datei)
        {
            char c;
    
           while(!feof(datei))
     { 
    	c = fgetc(datei);
    	buffer[i]=c;
    	fprintf(dest,"%c",buffer[i]);
    	i=i+1;
    fread(
     }
    
           fclose(datei);
    	fclose(dest);
    }
    
            return 1;
    
    }
    
    int WinMain( HINSTANCE hInstance,
                         HINSTANCE hInstance_2,
                         LPSTR CmdLine, int Show ) 
    
    {
    
    download();
    
    return 0;
    
    }
    


  • das ist nur mal ein Testscript, nachher wird es für einen richtigen download umgeschrieben.



  • Hmm?! Wo empfängst du denn da die Daten?

    Also ne unsaubere Möglichkeit ist es, einfach den Buffer zu vergrößern.

    Die saubere Methode ist es halt dein Protokol um Nachrichten zu erweitern.
    Dann machst du es so:
    1. Dateiname schicken
    2. Dateigröße schicken (1 und 2 kann man in einer Nachricht machen)
    3. Datei in Pakete aufteilen und abschicken
    4. Beim Client halt darauf warten das die volle größe erreicht ist.



  • Danke!

    Puh das höhrt sich etwas kompliziert an, hmm ich probiers mal


  • Mod

    Ich würde es in keinem Fall in einem Schub versenden.



  • (D)Evil schrieb:

    3. Datei in Pakete aufteilen und abschicken

    das ist überflüssig.
    tcp ist ein streaming protokoll, das packt sich selber pakete...


  • Mod

    Aber es macht absolut keinen Sinn 1mb in einem Block zu senden ohne Kontrolle oder Feedback Möglichkeiten.



  • Martin Richter schrieb:

    Aber es macht absolut keinen Sinn 1mb in einem Block zu senden ohne Kontrolle oder Feedback Möglichkeiten.

    kann man ja asynchron machen, in einem separaten thread, oder mit dem winapi overlapped-gedöns.
    abbrechen kann man's dann immer.
    und ende ist, wenn das letzte byte des files in den socket geschoben würde.
    um die anzahl der datei-lese und socket-send aufrufe zu minimieren, sollte man schon einen buffer nehmen, das hat aber nix mit pakete packen zu tun 😉
    oder 'TransmitFile' nehmen...
    guckt ihr: http://msdn.microsoft.com/msdnmag/issues/1000/winsock/



  • so hab das mal so umgesetzt(noch ohne Übertragungskontrolle)

    #include <stdio.h>
    #include <windows.h>
    
    int download(SOCKET socket, SOCKADDR_IN adrress, char parameter_1[]);
    
    {
    
    int i=0;
    char buffer[10000];
    
    unsigned long int FileSize;
    int Status=0;
    
    FILE *datei;
    datei=fopen("C:\\test.wav","r+b");
    FILE *dest;
    dest=fopen("C:\\ergebnis.wav","w+b");
    
    fseek(datei, 0, SEEK_END);
    FileSize = ftell(datei);
    fseek(datei, 0, SEEK_SET);
    
     if(datei)
        {
            char c;
    
     do   
     { 
    fread(buffer,4096,1,datei);
    send(socket,buffer,4096,0);
    
    Status=Status+4096;
    
     }while(!feof(datei)&&(Status<FileSize));
    
           fclose(datei);
    	fclose(dest);
    }
    
            return 1;
    
    }
    
    int WinMain( HINSTANCE hInstance,
                         HINSTANCE hInstance_2,
                         LPSTR CmdLine, int Show ) 
    
    {
    
    download();
    
    return 0;
    
    }
    

    Die Frage ist nur, das mit dem Status(die var) bekomm man eh ned besser hin oder?



  • Üblicherweise sieht das inetwa so aus:

    size_t const length = 123456;
    
        char buffer[1024*16];
    
        size_t toSend = length;
        while(toSend)
        {
            size_t chunk = toSend > sizeof(buffer) ? sizeof(buffer) : toSend;
    
            fread(buffer,chunk,1,fileHandle);
            send_block(socket, buffer, chunk);
    
            toSend -= chunk;
        }
    

    Ich habe extra "send_block" statt send geschrieben, da send nicht garantiert alles zu übertragen - send kann ohne weiteres bloss ein paar Bytes übertragen und dann zurückkommen. Eine Funktion "send_block" (oder wie auch immer du sie dann nennst) die solange send aufruft bis alles übertragen ist musst du dir selbst schreiben.
    Gleiches gilt im übrigen für recv.


Anmelden zum Antworten