socket: binare datei senden - beschleunigen



  • hmm ok - darf recv denn dann trotzdem so aussehen:

    rc=recv(connectedSocket,buf,1024,0);
    

    und auf 1024 warten?

    dann schreibe ich es mit

    out_file.write(buf,sizeof(buf));
    

    wieder in die datei

    mit

    send(s, buf, in_file.gcount(),0);
    

    sende ich

    und mit

    in_file.read(buf, sizeof(buf));
    

    lese ich aus der datei.

    aber es wird trotzdem mehr in die datei geschrieben als in_file.gcount()

    p.s: also in_file.gcount() ist in meinem fall genau 28, wenn ich aber

    in_file.read(buf, 28);
    

    anstatt

    in_file.read(buf, sizeof(buf));
    

    benutze ist die neue txt datei lehr 😕



  • i würd das so machen in etwa...
    is so ein grobentwurf....bitte @all um comments!!!

    cu

    typedef struct NETFILEHEADER
    {
        unsigned long FileSize;
        char pFileName[256];
    };
    
    //////////////// Senden ///////////////////////
    
    char buf[1024]; 
    
    // du solltest zuerst die dateigrösse zum client schicken...
    // am besten du machst eine structur aus dateinamen und dateigrösse und schickst das zum client!
    
    // Dateigrösse bestimmen:
    NETFILEHEADER FileHeader;
    in_file.seekg (0, ios::end);
    FileSize = in_file.tellg();
    in_file.seekg (0, ios::beg);
    
    // NetfileHeader setzten
    FileHeader.FileSize = FileSize;
    
    // Dateinamen bestimmen u dann in structur....musst selber probieren
    // dann den Fileheader zuerst an den client senden...u dann die datei...
    
    // Datei senden
    while(FileSize >= 1024)
    {
      in_file.read(buf, sizeof(buf));
      send(sock, buf, stream.gcount(), 0);   
      FileSize -= 1024;
    }
    
    // Ist Filesize kleiner als 1024
    if(FileSize)
    {
      in_file.read(buf, FileSize);
      send(sock, buffer, stream.gcount(), 0);
    }
    
    /////////////// Empfangen /////////////////////
    
    NETFILEHEADER FileHeader;
    char *FileHeader1 = new(char[sizeof(Netfileheader)];
    unsigned long AlreadyReceived = 0 
    unsigned long rc = 0;
    long FileSize;
    
    //Fileheader empfangen....
    do 
    { 
       rc = recv(client, Fileheader1, sizeof(NETFILEHEADER), 0); 
       AlreadyReceived += rc; 
       memcopy(FileHeader1, Netfileheader, rc);
    
    }while(AlreadyReceived<sizeof(NETFILEHEADER));
    
    FileSize = FileHeader.FileSize;
    
    // Dann öffnest du die datei 
    ofstream out_file (FileHeader.pFileName,ofstream::binary);
    
    // In Datei schreiben
    while(FileSize > 0)
    {
       rc = recv(client, buffer, 1024, 0);
       out_file.write(buf,sizeof(buf));
    
       FileSize -= rc;
    }
    
    //Datei schließen usw....
    


  • was sagst dazu?



  • ich würd sagen ein kriterium ist auch noch das maximum segment size! -> so gross sollte dann das paket sein das gesendet wird....
    bei dsl liegt der glaubi zwischen 1430 - 1450!!
    stimmt das??

    mfg surf



  • Was spricht eigentlich dagegen das Paket so groß wie die Datei zu machen und einfach alles auf einmal zu senden. Oder ist die Paketgröße begrenzt?



  • @surf: Ja, da dieser Wert der systemgegebene Maximalwert ist, wäre es damit wohl optimal, denke ich.

    @Gast: Was ist bei ner 2-GB-Datei? 😉 Der Sendepuffer hat halt auch nur ne bestimmte Größe.



  • Passt sich der Puffer nicht an?
    Wenn nicht, gibts keine Funktion mit der man die Größe rausbekommt und
    dann nimmt man einfach die.



  • Cocaine schrieb:

    @surf: Ja, da dieser Wert der systemgegebene Maximalwert ist, wäre es damit wohl optimal, denke ich.

    1. fuer ISDN, Kabelmodem usw. aber nicht
    2. von diser Segmentgroesse muss immer noch das abgezogen werden, das TCP/IP (und PPP gar auch noch? 😕 ) an Headern fuer sich selbst verbraet!



  • Cocaine schrieb:

    @surf: Ja, da dieser Wert der systemgegebene Maximalwert ist, wäre es damit wohl optimal, denke ich.

    @Gast: Was ist bei ner 2-GB-Datei? 😉 Der Sendepuffer hat halt auch nur ne bestimmte Größe.

    Vor allem muss die Datei erst einmal gelesen werden.

    mfg
    v R



  • sorry ich war im urlaub 😕 deswegen rufe ich diesen post
    erst jetzt nochmal auf...

    also ich habe noch folgendes problem. so "kopiere" ich die datei:

    #include <iostream> 
    #include <string> 
    #include <fstream> 
    
    using namespace std; 
    
    int main() 
    { 
    
    char buf[1024]; 
    
      ifstream in_file("c:\\lol.mp3", ios::in | ios::binary);
      ofstream out_file("c:\\lol2.mp3", ios::out | ios::binary); 
      while(!in_file.eof()) 
      { 
    in_file.read(buf, sizeof(buf));
    out_file.write(buf, in_file.gcount());  
      }
    in_file.close();
    out_file.close();
    }
    

    mit

    send(s, buf, in_file.gcount(),0);
    

    sende ich dann das ausgelesene rüber und mit

    rc=recv(connectedSocket,buf,1024,0);
        if(rc==0)
        {
         exit(1);
        }
        if(rc==SOCKET_ERROR)
        {
         exit(1);
        }
        buf[rc]='\0';
    

    empfange ich es. dann schreibe ich es wieder mit

    out_file.write(buf, rc);
    

    in eine date. nun ist die neu erstellte datei wenn ich es nicht über sockets
    mache sondern nur mit dem beispiel oben genauso groß wie das original (1.313).
    wenn ich es aber so über sockets mache und wieder reinschreibe nur (1.312) - die mp3 läuft aber trotzdem.

    ist das schlimm und woran kann das liegen?



  • Verzeih mir meine Frage, aber warum nutzt du kein MSG_PEEK?



  • was würde MSG_PEEK denn genau machen wenn ich es mit recv benutzen
    würde?

    bei google habe ich leider nichts gefunden!



  • Value Meaning
    MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function then returns the number of bytes currently pending to receive.



  • hi!
    kennst jemand bei mirc die einstellung: packet size beim senden einer datei?

    cu



  • hmm ok ... und was soll es mir jetzt bringen wenn ich

    recv(connectedSocket,buf,1024,MSG_PEEK);
    

    benutze? wenn ich das mache ist die neue datei nicht 1.3 sondern 40.2 groß?!

    #include <iostream> 
    #include <string> 
    #include <fstream> 
    
    using namespace std; 
    
    int main() 
    { 
    
    char buf[1024]; 
    
      ifstream in_file("c:\\lol.mp3", ios::in | ios::binary);
      ofstream out_file("c:\\lol2.mp3", ios::out | ios::binary); 
      while(!in_file.eof()) 
      { 
    in_file.read(buf, sizeof(buf));
    out_file.write(buf, in_file.gcount());  
      }
    in_file.close();
    out_file.close();
    }
    

    wenn ich dann beim netzwerk buf rüber sende kann ich es ja nicht
    wieder mit "out_file.write(buf, in_file.gcount());" hineinschreiben
    da ich in_file.gcount() nicht habe! ich möchte es nicht immer extra
    rüber senden deswegen dachte ich das rc ( rc=recv() ) die gleiche anzahl
    angibt.

    aber es werden trotzdem mehr oder weniger bytes als rc wieder in die
    datei reingeschrieben wenn ich

    out_file.write(buf, rc);
    

    benutze!

    so hab ichs im moment zum ausprobieren gemacht:

    senden:

    while(!in_file.eof()) 
      { 
    
    in_file.read(buf, sizeof(buf));
    
    send(s, buf, in_file.gcount(),0);
    
    rc=recv(s,buf,1024,0);
        if(rc==0)
        {
          printf("Server hat die Verbindung getrennt..\n");
          exit(1);
        }
        if(rc==SOCKET_ERROR)
        {
          printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
          exit(1);
        }
        buf[rc]='\0';
    
    }
    in_file.close();
    send(s,".ende",strlen(".ende"),0);
    exit(1);
    

    empfangen:

    while(1) {
    
        rc=recv(connectedSocket,buf,1024,0);
        if(rc==0)
        {
         exit(1);
        }
        if(rc==SOCKET_ERROR)
        {
         exit(1);
        }
        buf[rc]='\0';
    
    if(!strcmp(buf, ".ende")) {
    out_file.close();
    exit(1);
    }
    
    out_file.write(buf, rc);
    
    send(connectedSocket,".",strlen("."),0);
    


  • was mache ich denn nun noch falsch? ich muss
    bei "out_file.write();" doch die anzahl der bytes angeben die reingeschrieben
    werden sollen oder? und das ist doch die rückgabe von rc...

    ein beispiel wenn ich eine datei sende und immer rc ausgeben ist;

    rc=1024
    rc=1024
    rc=1024
    rc=1024
    ...
    rc=250

    ist ja klar weil die datei ja meist nicht gerade durch 1024 teilbar ist!
    aber ich meine ich mache es doch dann richtig oder? so wie es oben steht?!



  • hi mein filetransfer ist fertig!
    falls du die source willst mail mir!!! oder falls ne frage hast stell da..

    cu


Anmelden zum Antworten