socket: binare datei senden - beschleunigen



  • hmm ich habe nochmal ein bischen nachgedacht und habe mir das hier
    zusammengefriemelt:

    #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()) 
      { 
          //getline(in_file, text);
    
    in_file.read(buf, sizeof(buf)); 
    
          out_file << buf << endl;  
    
      }
    in_file.close();
    out_file.close();
    
    }
    

    nur leider ist lol.mp3 "1.313kb" groß und lol2.mp3 nur "0.131kb"
    was mache ich falsch?

    die farge mit recv von oben gilt noch 😉



  • bitte meckert mich nicht an oder so 😕 aber es ist 1.14 und ich
    habe schon sehr viel kaffee getrunken <-- habe frei!

    nun habe ich es so geschafft:

    #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()) 
      { 
          //getline(in_file, text);
    
    in_file.read(buf, sizeof(buf));
    
          //out_file << buf << endl;
    
    out_file.write(buf, sizeof(buf));
    
      }
    in_file.close();
    out_file.close();
    
    }
    

    aber wie genau muss ich das denn nun bei recv machen?`
    ich geh nun oder versuche nun mal schlafen zu gehen 😛
    txh schonmal bis hier hin!



  • hallo!
    du solltest ja x mal 1024b auslesen, do gross halt die datei ist, oder hab ich das falsch verstanden!?

    lg



  • sorry machst du e;-) aber was ist wenn die datei kleiner als 1024b ist? oder 10000b ist? hm...

    lg



  • ja, ich habe ja schon ein Beispiel gepostet. Mit infile.gcount() bekommt man raus, wieviel gelesen wurde und mehr sollte man auch nicht senden.



  • hmm nehmen wir mal an die datei ist größer als 1024 😃

    also wenn cih zum senden dies hier benutze:

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

    kommt ein fehler beim kompilieren:

    Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
    tc.cpp:
    Error E2193 tc.cpp 93: Too few parameters in call to '__stdcall send(unsigned in
    t,const char *,int,int)' in function main()
    *** 1 errors in Compile ***
    

    und wie müsste ich es dann mit recv annehmen?
    bei recv(sock,buf,1024,0); kann es ja sein das weniger als 1024 kommen,
    wie müsste ich das denn dann machen?



  • du hast da einen parameter vergessen, deshalb hast du einen error
    schau dir mal das an:

    send:

    int send (  SOCKET s, const char FAR * buf, int len, int flags );
    

    -s: Socket über den wir die Daten senden wollen
    -buf: Pointer auf einen Buffer in dem die zu sendenden Daten enthalten sind
    -len: Wieviele Bytes von buf gesendet werden sollen
    -flags: Brauchen wir nicht

    Rückgabewert: Anzahl der gesendeten Bytes oder SOCKET_ERROR bei einem Fehler.

    recv:

    int recv (  SOCKET s, char FAR* buf, int len, int flags );
    

    -s: Socket über den wir Daten empfangen wollen
    -buf: Pointer zu einem Buffer in dem die empfangenen Daten gespeichert werden sollen
    -len: Grösse des Buffers (oder wieviele Daten im Buffer gespeichert werden sollen)
    -flags: benötigen wir nicht

    Rückgabewert: Anzahl der empfangenen Bytes, 0 falls die Verbindung vom Partner getrennt wurde oder SOCKET_ERROR bei einem Fehler.



  • long rc;
    
    rc=recv(s,buf,1024,0);
    

    Hier werden maximal 1024 Zeichen empfangen, es können auch weniger empfangen werden, bei recv dient der dritte Parameter nur dazu die grösse des Buffers im zweiten Parameter anzugeben. Wieviele Zeichen wirklich empfangen wurden sieht man im Rückgabewert (in diesem Falle rc)!!

    also dann schaust du einfach: wie viele zeichen sind in rc, würd ich mal sagn!!
    oder was meint ihr?

    cu



  • wow 🙂 ok also bis jetzt klappt alles super!

    aber was muss ich noch tun wenn die datei die gesendet werden soll
    kleiner als 1024b ist? wenn ich so (nicht binar) eine txt-datei
    mit dem inhalt "hallo dies ist ein test" versenden will, steht
    nacher das hier drin:

    hallo dies ist ein test û Æ2@ @û *{ Xû '·@ ôtA ìú     *{ Xû     ¼wA °þ ù¦@ ¨0{ ¨0{ °þ *{ 46@ *{ |û ­H@ ÀtA X){ œ({ ÌtA µ7@ ÌtA     ˜û '·@ œwA @û  ü ô2@  ü ¨û '·@ ütA pû     û *{         Ìû Æ2@  ü *{ 8ü '·@ >èw¸  
       Ðû pèw¸  ø«A     çÝ0     “      ÿÿÿÿÿÿÿ       ,   <1{ ü  (@ ,   ø«A $ü <1{ ø«A hü šý@ §A     0   X){ <1{ _é@    ,1{     ¨0{ ­A ý '·@ $bA <ü        È){     xü ÉA  { X){ (ý Ù¡@    X){ ¨0{ ¨0{ ,   <1{ ¤ü  (@ ,   ø«A Äü <1{ ø«A ý šý@ §A     0   ,1{ <1{ _é@ &1{ ¨0{  ý     LC_M ý øü ´&@ ,1{ ý Ñ@ ,1{ ý 4@ ,1{ ý D@ ,1{ ,ý ?¢@ ,1{ [   ¨ý È–@  ý    ¨0{ ¨†A °þ     7  ÆŒw    Z   z   lý @    Ìý '·@  ‹A <ý    |({ °þzZ    '·@ ÀŠA xý X){ „ý    ,1{ øý  ¬@ ¨0{ °þ °þ ¨0{ |({ (þ     (þ '·@ T‘A ¸ý         8      øý y3@     Xþ Ù«@ °þ ¨0{ ¨†A <þ Vg@ |({ Pþ '·@ āA þ    '·@ ‘A     °þ lþ Vg@ |({ €þ '·@ āA Hþ    |({        àþ @    ½A ¼þ '·@ ôaA pþ     |({        ¨þ ÜQ@ ¨0{ äþ ¸Q@ àþ     ‹A ½A ÿ '·@ zA
    

    ich schreibe mit "out_file.write(buf,sizeof(buf));" wieder in die datei,
    habs mit out_file.write(buf,rc); versucht, beim binaren senden einer mp3
    klappt es, aber bei unbinaren senden der txt steht nacher nichts in der txt!



  • hmm ok, ich würde dann überprüfen ob die datei kleiner als 1024
    ist, und wenn dann würde ich buf so groß machen wie die datei ist.

    wenn ich die dateigröße in der int x gespeichert habe wie kann
    ich buf dann als größe x übergeben?

    int x=28;
    char buf[x];
    

    klappt leider nciht 😕



  • senden:

    ich würds so machen:

    [/cpp]
    char buf[1024];

    ifstream in_file("c:\\lol.mp3", ios::in | ios::binary);

    while(!in_file.eof())
    {
    in_file.read(buf, sizeof(buf));
    send(sock, buf, stream.gcount(), 0); // Mit infile.gcount() bekommt man raus, wieviel gelesen wurde zb.: kleiner als 1024, dieser parameter sagt ja wieviel zeichen vom buffer gesendet werden sollen!!!
    }

    in_file.close();
    [cpp]

    poste dann mal den fertigen code für senden u empfangen...

    cu



  • 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


Anmelden zum Antworten