Kleines Problem beim Versenden von Datei über Sockets



  • zeig quellcode



  • Hi, auch daran gedacht, die ankommenden Daten zu Null-Terminieren.

    s=recv(socket,buffer,1024,0);
    buffer[s] = 0;
    


  • KasF schrieb:

    Hi, auch daran gedacht, die ankommenden Daten zu Null-Terminieren.

    s=recv(socket,buffer,1024,0);
    buffer[s] = 0;
    

    Weißt du eigentlich, wieviele Null-Bytes du in einer Mp3-Datei findest?...

    Edit: Wieso ist das Senden von Binär-Daten eigentlich so unpopulär? Gibt doch so viel mehr als nur Texte 😕



  • Badestrand schrieb:

    Weißt du eigentlich, wieviele Null-Bytes du in einer Mp3-Datei findest?...

    Was hat das mit meinem Code zu tun ???



  • Ok, erstmal vielen Dank für diese schnelle Beantwortung.
    Ich hab die beiden Datein im Hex-Editor verglichen und siehe da, am Anfang ist ein Fehler (nur Nullen). Das hilft mir schonmal ziemlich weiter, weil ich den Fehler immer am Ende vermutet hatte.
    Ich halt euch auf dem laufenden, wenn ich den (wahrscheinlich kleinen) Fehler gefunden habe.
    PS: Muss ich wirklich die Datei null-terminieren, denn die MP3-Datein gehen ja auch ohne?



  • SirWyver schrieb:

    Muss ich wirklich die Datei null-terminieren, denn die MP3-Datein gehen ja auch ohne?

    Nein, musst du nicht... Die gesendete Datei soll ja identisch sein, dazu gehört auch die Größen-Gleichheit 🙂

    KasF schrieb:

    Badestrand schrieb:

    Weißt du eigentlich, wieviele Null-Bytes du in einer Mp3-Datei findest?...

    Was hat das mit meinem Code zu tun ???

    Tschuldigung, ich wollte dir nix vorwerfen! Aber das Null-terminieren in deinem Code hat nur Sinn, wenn du Texte verschickst, nicht bei Binärdaten. Oder ich irre mich, dann musst du mich belehren 🤡



  • *Schnaarch* 🙂
    Hmm, ich denke mal das macht doch keinen Unterschied. Wenn er recv sagt dass er 1024 Daten lesen soll, dann kann es sein das mal beim lesen nur 500 gelesen werden und dann die restlichen 624 Bytes meines Array mit irgendwelchen Daten gefüllt sind. Deswegen muss geschaut werden wieviel mit recv gelesen wurde und da entsprechend Null terminieren.

    Es sei denn er passt darauf auf, wenn er in seine Datei schreibt.

    file.write(buffer,s); // s Zeichen schreiben, s returnwert von recv
    

    Ansonsten würde er ja wahrscheinlich ältere/ungültige Bytes reinschreiben.

    Badestrand schrieb:

    KasF schrieb:

    Badestrand schrieb:

    Weißt du eigentlich, wieviele Null-Bytes du in einer Mp3-Datei findest?...

    Was hat das mit meinem Code zu tun ???

    Tschuldigung, ich wollte dir nix vorwerfen!

    Auch sorry 🤡
    Dein Satz kam mir so provokant und angreifend vor, da musste ich genauso blöd zurück antworten.

    Aber kann sein das du auch Recht hast, denn am Ende werden die Dateien ehe über write geschrieben und für den gibts keine Null-Terminierung. Insofern sollte man als zweites Argument bei write den Return-Wert von recv angeben.

    Edit: Hast wahrscheinlich Recht, wenn er die Datei binär behandelt ...



  • Also, ich hab erstmal getestet, ob auch alles eingelesen wird, indem der Client aus den Daten, die er verschickt, selbst nochmal eine Datei erstellt. Diese funktioniert auch einwandfrei, daher muss wohl der fehler beim versenden liegen. Hierzu ein paar Quellcodeschnipsel:
    Der Client, der sendet:

    char buffer[10000];
      unsigned long int FileSize;
      int Status=0;
     FILE *datei;
    datei=fopen("C:\\kal.JPG","r+b");
    fseek(datei, 0, SEEK_END);
    FileSize = ftell(datei);
    fseek(datei, 0, SEEK_SET);
    string laenge;
    ostringstream outStream;
    outStream << FileSize;
    laenge = outStream.str();
    send(sock,laenge.c_str(),strlen(laenge.c_str()),NULL);
    
     if(datei)
        {
          while(!feof(datei)&&(Status<FileSize)&&(FileSize-Status>=1024))
          {
           fread(buffer,1024,1,datei);
           fwrite(buffer,1024,1,datei2);
           send(sock,buffer,1024,0);
           Status=Status+1024;
           cout<<endl<<Status<<"Bytes uebertragen"<<endl;
          }
    
      int klein=FileSize-Status;
      ostringstream outSe;
      outSe << klein;
      laenge = outSe.str();
      cout<<"Noch zu senden: "<<laenge;
    
      fread(buffer,klein,1,datei);
      send(sock,buffer,klein,0);
      Status=Status+klein;
      cout<<endl<<Status<<"Bytes uebertragen"<<endl;
      cout<<"Transfer beendet!"<<endl;
    
      fclose(datei);
    }
    

    Der Server, der empfängt:

    char buffer[1026];
          char laenge[1000];
          unsigned long int Status=0;
          cout<<"Datei senden"<<endl<<endl;
          recv(sockConnected,laenge,1001,NULL);
          unsigned long int FileSize;
          FileSize=atoi(laenge);
          cout<<endl<<"Größe: "<<FileSize;
          FILE *datei;
         datei=fopen("C:\\alfa.JPG","w+b");
         if(datei)
       {
          while(!feof(datei)&&(Status<FileSize)&&(FileSize-Status>=1024))
            {
              recv(sockConnected,buffer,1024,0);
              fwrite(buffer,1024,1,datei);
              Status=Status+1024;
              cout<<endl<<Status<<"Bytes uebertragen"<<endl;
            }
    
        int klein=FileSize-Status;
    
        recv(sockConnected,buffer,klein,0);
        fwrite(buffer,klein,1,datei);
        Status=Status+klein;
        cout<<endl<<Status<<"Bytes uebertragen"<<endl;
        cout<<"Transfer beendet!"<<endl;
        fclose(datei);
       }
    [cpp]  char buffer[10000];
      unsigned long int FileSize;
      int Status=0;
     FILE *datei;
    datei=fopen("C:\\kal.JPG","r+b");
    fseek(datei, 0, SEEK_END);
    FileSize = ftell(datei);
    fseek(datei, 0, SEEK_SET);
    string laenge;
    ostringstream outStream;
    outStream << FileSize;
    laenge = outStream.str();
    send(sock,laenge.c_str(),strlen(laenge.c_str()),NULL);
    
     if(datei)
        {
          while(!feof(datei)&&(Status<FileSize)&&(FileSize-Status>=1024))
          {
           fread(buffer,1024,1,datei);
           fwrite(buffer,1024,1,datei2);
           send(sock,buffer,1024,0);
           Status=Status+1024;
           cout<<endl<<Status<<"Bytes uebertragen"<<endl;
          }
    
      int klein=FileSize-Status;
      ostringstream outSe;
      outSe << klein;
      laenge = outSe.str();
      cout<<"Noch zu senden: "<<laenge;
    
      fread(buffer,klein,1,datei);
      send(sock,buffer,klein,0);
      Status=Status+klein;
      cout<<endl<<Status<<"Bytes uebertragen"<<endl;
      cout<<"Transfer beendet!"<<endl;
    
      fclose(datei);
    }
    

    M.f.G SirWyver



  • code mal deine schleife so das du keine sonderbehandlung für das letzte stück brauchst.



  • Das ist ziemlicher Müll den du da machst.
    Ließ dir das hier durch: http://www.cpp-tutor.de/cpp/le04/le04_03.htm und benutze einheitlich C++ Streams.



  • Ey du überprüfst ja gar nicht den Rückgabewert von recv!



  • Hi,
    ja ich weiß, ich bin noch ein ziemlicher Anfänger (halbes Jahr c++),
    Ich hab jetzt nochmal den Receive-rückgabewerte überprüft und es hat sich herausgestellt, dass er am Anfang oder am Ende (wenn er schon aus der Schleife raus ist) mal zu viel, mal zu wenig schickt. Wie kann ich das denn lösen, dass nicht mehrfach die gleichen Bytes geschickt werden oder dass er was weglässt?



  • Ich glaube der Rückgabewert von send gibt an, wieviele Bytes versendet wurden; können eben auch weniger sein als du wolltest - dann musst du den Rest halt noch mal schicken 🙂



  • Hallo,
    ich bräuchte nochmal Eure Hilfe. Ich hab jetzt die Schleife verbessert und beim ersten Senden macht er alles noch richtig, aber wenn man noch etwas versenden will, dann kommt eigentlich nur noch Mist heraus. Ich vermute, es hängt mit den Arrays zusammen, die ich verwende, dann die schon zum Teil gefüllt sind und dadurch was falsches verschickt wird.

    Hier nochmal mein Sender:

    void SendClient(SOCKET sock)
    {
      string Pfad;
      string Name;
      string tosend;
      FILE *datei;
      string laenge="0";
      unsigned long int FileSize;
      int gesendet;
    while(1)
    {
      cout<<"Welche Datei möchest Du verschicken?"<<endl;
      cout<<"Pfad: ";
      getline(cin,Pfad);
      cout<<"Name: ";
      getline(cin,Name);
      unsigned long int Status=0;
      tosend=Pfad+Name;
      send(sock,Name.c_str(),strlen(Name.c_str()),NULL);
      char buffer[10000];
      datei=fopen(tosend.c_str(),"r+b");
      if(!datei)
      {send(sock,laenge.c_str(),3,NULL);}
      else
      {
        fseek(datei, 0, SEEK_END);
        FileSize = ftell(datei);
        fseek(datei, 0, SEEK_SET);
        ostringstream outStream;
        outStream << FileSize;
        laenge = outStream.str();
        send(sock,laenge.c_str(),strlen(laenge.c_str()),NULL);
    
        while(!feof(datei)&&(FileSize>Status))
          {
           fread(buffer,1024,1,datei);
           gesendet=send(sock,buffer,1024,0);
           Status=Status+gesendet;
           }
        cout<<endl<<"Transfer beendet!"<<endl;
        fclose(datei);
      }
    }
    }
    

    Der Empfänger:

    void Receive(SOCKET sock)
    {
      string name="";
      char name1[1000];
      char laenge[1002];
      recv(sock,name1,1026,NULL);
      name=name1;
      cout<<"Name der Datei: "<<name<<endl;
      recv(sock,laenge,1001,NULL);
      cout<<"Groeße der Datei: "<<laenge<<endl;
      name="C:\\Downloads\\"+name;
      unsigned long int FileSize;
      unsigned long int Status=0;
      FileSize=atoi(laenge);
      if(FileSize!=0)
      {
         FILE *datei;
         datei=fopen(name.c_str(),"w+b");
         int empfangen;
         char buffer[10000];
         if(datei)
       {
          while(!feof(datei)&&(FileSize>Status))
            {
              empfangen=recv(sock,buffer,1024,0);
              fwrite(buffer,empfangen,1,datei);
              Status=Status+empfangen;
            }
        cout<<endl<<Status<<" Bytes uebertragen"<<endl;
        cout<<"Transfer beendet!"<<endl;
        fclose(datei);
       }
      }
    }
    

    Wäre echt nett, wenn Ihr mir helfen könntet 🙂
    Dann vielen Dank im Voraus!


Anmelden zum Antworten