Problem mit recv: Es werden falsche Daten ausgegeben



  • Hallo, ich sende über einen GET request ( GET /test2.txt HTTP/1.1 ) eine Anfrage an einen Webserver. Der Server Antwortet mir auch mit ok, soweit so gut. Nachdem senden des GET requests kommt ja die Antwort vom Server zurück.
    Die Antwort nehme ich mit der recv Funktion auf sowie den Nachfolgenden Inhalt aus der Text-Datei.

    Bei kleinen Text-Dateien gibt es keine Probleme und alles funktioniert einwandfrei. Beispiel einer Text-Datei wo ich den Inhalt ohne Probleme mit recv auslesen kann:
    123
    456
    245
    124
    579

    Jetzt noch ein Beispiel einer Text-Datei wo es Probleme gibt:
    12367567657
    45656756755
    12367567657
    45656756755
    12367567657
    45656756755

    Ich sehe noch über recv das der Server mir zu meinem GET request ein OK zurückgibt. Jedoch werden danach nur noch irgendwelche zufälligen Zeichen ausgegeben.

    Ich wollte die Zeichen welche recv aufnimmt bytes für bytes ausgeben lassen. Hier ist mein Code:

    	long TotalReceivedBytes=0;
    	long rc=0;
    
    	std::vector<char>buf;
    	buf.push_back('\x00');
    
    	do
    	{
    		rc = recv( net.DataTransferSocket, &buf[0], 1 ,0);
    		if ( rc > 0)
    		{
                TotalReceivedBytes = TotalReceivedBytes + rc;
    			std::cout<<&buf[0];
    		}
    
    		else if ( rc == 0 )
    		{
    			std::cout<<"connection closed.\n";
    			return -1;
    		}
    
    		else
    		{
    			std::cout<<"recv error: "<<WSAGetLastError()<<"\n";
    			return -2;
    		}
    	}
    	while( rc > 0  );
    


  • geht das so mit dem vector? also meine vermutung wäre jetzt, dass intern nicht genug speicher angelegt wird. und du weißt schon, dass die windows api eigentlich C und nicht C++ ist?



  • @Bassmaster Sind es immer verschiedene zufällige Zeichen?
    Wird auch die richtige Datei ausgewählt?

    Nur ein Zeichen mit recv zu empfangen ist etwas ineffektiv.



  • Wozu benutzt du einen vector als Puffer, wenn du genau ein Zeichen liest?

    std::cout<<&buf[0]; Da der Puffer kein terminierendes Nullbyte enthält, ist das falsch.



  • Hallo, ja einen vector kann ich mir sparen keine Ahnung wieso ich den gestern verwendet hatte.
    Jedenfalls lag das Problem beim get request. Mit dem request welchen ich zuerst verwendet hatte gab der Server mir zwar ein OK allerdings kam es ja zu dem oben erwähnten Problem. Jetzt habe ich in einem anderen Code gesehen das da der get request anders aussah. Ich habe meinen request string etwas angepasst und danach funktionierte es.

    get request von gestern:

    string str =
    "GET /test.txt HTTP/1.1\x0d\x0a"
    "Host: www.example.com\x0d\x0a"
    "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0\x0d\x0a"
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\x0d\x0a"
    "Accept-Language: de,en-US;q=0.7,en;q=0.3\x0d\x0a"
    "Accept-Encoding: gzip, deflate\x0d\x0a"
    "Connection: keep-alive\x0d\x0a"
    "Upgrade-Insecure-Requests: 1\x0d\x0a"
    "\x0d\x0a\x0d\x0a";
    

    Dieser get request entstand dadurch das ich mit Wireshark und dem Firefox Plugin HTTP Header Live mir angeschaut hatte wie so requests aussehen. Ohne weiter drüber nachzudenken hatte ich diesen so übernommen ....

    Und jetzt der überarbeitete request:

    string str =
    "GET /test.txt HTTP/1.1\x0d\x0a"
    "Host: www.example.com\x0d\x0a"
    "\x0d\x0a\x0d\x0a";
    

    ok \x0d und \x0a kann ich noch jeweils durch \n \r ersetzten.

    	long TotalReceivedBytes=0;
    	long rc=0;
    
    	char buf[512]={'\x00'};
    
    	do
    	{
    		rc = recv( net.DataTransferSocket, &buf[0], 512 ,0);
            buf[rc]='\x00';
    		if ( rc > 0)
    		{
                TotalReceivedBytes = TotalReceivedBytes + rc;
    			std::cout<<&buf[0];
    		}
    
    		else if ( rc == 0 )
    		{
                std::cout<<"\n";
    			std::cout<<"connection closed.\n";
    			return -1;
    		}
    
    		else
    		{
    			std::cout<<"recv error: "<<WSAGetLastError()<<"\n";
    			return -2;
    		}
    	}
    	while( rc > 0  );
    
    	return TotalReceivedBytes;
    


  • @Bassmaster
    std::cout<<&buf[0]; das ist immer noch falsch.



  • @manni66 sagte in Problem mit recv: Es werden falsche Daten ausgegeben:

    @Bassmaster
    std::cout<<&buf[0]; das ist immer noch falsch.

    rc = recv( net.DataTransferSocket, &buf[0], 512 ,0);
            buf[rc]='\x00';
    

    Es wird hier doch Nullterminiert abgesehen davon ist der ganze buffer mit einem Nullterminator initialisiert.

    WIe macht man es den richtig?



  • @Bassmaster sagte in Problem mit recv: Es werden falsche Daten ausgegeben:

    @manni66 sagte in Problem mit recv: Es werden falsche Daten ausgegeben:

    @Bassmaster
    std::cout<<&buf[0]; das ist immer noch falsch.

    rc = recv( net.DataTransferSocket, &buf[0], 512 ,0);
            buf[rc]='\x00';
    

    Es wird hier doch Nullterminiert abgesehen davon ist der ganze buffer mit einem Nullterminator initialisiert.

    WIe macht man es den richtig?

    Die Zuweisung habe ich übersehen, weil sie da auch falsch ist. buf[-1] =…?
    Ebenso buf[512] =….



  • @Bassmaster sagte in Problem mit recv: Es werden falsche Daten ausgegeben:

    WIe macht man es den richtig?

            long TotalReceivedBytes=0;
    	long rc=0;
    
    	char buf[512]={'\x00'};
    
    	do
    	{
    		rc = recv( net.DataTransferSocket, buf, 511 ,0);  //Platz für 0-Byte lassen!
            
    		if ( rc > 0)
    		{
                         buf[rc] = '\x00';  //nur, wenn rc nicht negativ!
                         TotalReceivedBytes = TotalReceivedBytes + rc;
    	             std::cout << buf;
    		}
    
    		else if ( rc == 0 )
                    ...
    


  • man kann auch buf vergrößern.

    0 ist auch nicht negativ.



  • @DirkB
    buf[rc] = 0 für rc == 0 ist auch kein Problem.

    Edit:
    Ah ja ... Blödsinn, mein Kommentar ist natürlich falsch 😟



  • Ja, buf[512]; Element 0 bis 511 sind reserviert. Ich habe länger nicht programmiert wird Zeit nochmal ein paar Grundlagen wieder aufzufrischen ....



  • @Bassmaster Bei recv gibst du die Anzahl (Größe) an.


Log in to reply