Dateien per Sockets versenden



  • Schau mal hier. Ist aus dem WINAPI-Forum und sollte funktionieren.

    Edit: Die Senderoutine steht unten richtig.



  • Vicious Falcon schrieb:

    Schau mal hier. Ist aus dem WINAPI-Forum und sollte funktionieren.

    Edit: Die Senderoutine steht unten richtig.

    Ich habe die beiden Routinen übernommen. Meine Frage war aber, wie eine Sendeschleife aussehen muss, falls die Datei größer als der Puffer ist... Und wie teile ich recv() am besten mit, wir groß die zu schickende Datei ist?
    (Ein send() vorweg?)

    Danke.



  • HELPVISTAWIN7 schrieb:

    Ich habe die beiden Routinen übernommen. Meine Frage war aber, wie eine Sendeschleife aussehen muss, falls die Datei größer als der Puffer ist... Und wie teile ich recv() am besten mit, wir groß die zu schickende Datei ist?
    (Ein send() vorweg?)

    1. Was für ein Puffer beim Senden?
    2. Indem du die Größe vorwegschickst.

    EDIT:
    So geht man damit um, dass send nicht alles auf einmal sendet:

    bool send_all(int s, const char *data, size_t size)
    {
    	size_t sent = 0;
    
    	while (sent < size)
    	{
    		const int rc = send(s, data + sent, size - sent);
    		if (rc > 0)
    		{
    			sent += rc;
    		}
    		else
    		{
    			return false;
    		}
    	}
    
    	return true;
    }
    


  • Bei recv() scheint die Schleife ja zu funktionieren...

    Ich benutze immer

    #define BUF_SIZ 4096

    als Puffergröße für recv() und für send(). Ist da vlt. schon der Fehler? Ich habe gelesen, dass Sockets eine bestimmte Puffergröße nicht mehr "vertragen". Wenn die zu übertragende Datei also z.B. 2 GB groß ist.

    Danke.



  • Du sendest die ersten 4096 Bytes, dann die restlichen 3904 Bytes - sollte aber eigentlich offensichtlich sein.
    Empfangen läuft sowieso immer nach dem gleichen Schema ab: du empfängst solange, bis die Verbindung beendet wird bzw. die gesamte Datei empfangen ist.

    Wenn die zu übertragende Datei also z.B. 2 GB groß ist.

    4096 Bytes < 2 GB. Und zwar deutlich.



  • Du kannst doch per ReadFile immer bspw. 4096 Bytes lesen und an die Send-Methode übergeben.
    ReadFile verrät dir geschickterweise auch noch, wie viele Bytes tatsächlich eingelesen wurden.



  • @ TyRoXx:
    Aaah, danke. Und wie sieht die entsprechende recv() Routine dazu aus?



  • Ich habe es nicht getestet und es ist plattformabhängig, aber folgender Code sollte eine mögliche Lösung darstellen:

    //siehe einige Posts weiter oben für send_all
    
    bool send_file(int s, const char *data, size_t size)
    {
    	return
    		send_all(s, reinterpret_cast<const char *>(&size), sizeof(size)) &&
    		send_all(s, data, size);
    }
    
    bool receive_all(int s, char *data, size_t size)
    {
    	size_t received = 0;
    	while (received < size)
    	{
    		const int rc = recv(s, data + received, size - received);
    		if (rc >= 0)
    		{
    			received += rc;
    		}
    		else
    		{
    			return false;
    		}
    	}
    
    	return true;
    }
    
    bool receive_file(int s, std::vector<char> &data)
    {
    	size_t fileLength;
    	if (!receive_all(s, reinterpret_cast<char *>(&fileLength), sizeof(fileLength)))
    	{
    		return false;
    	}
    
    	if (fileLength == 0)
    		return true;
    
    	data.resize(fileLength);
    	return receive_all(s, &data[0], data.size());
    }
    


  • Vicious Falcon schrieb:

    Du kannst doch per ReadFile immer bspw. 4096 Bytes lesen und an die Send-Methode übergeben.
    ReadFile verrät dir geschickterweise auch noch, wie viele Bytes tatsächlich eingelesen wurden.

    Ich benutze dafür fstream. Daher war mir das nicht bekannt.



  • Danke für eure Hilfe.

    Es hat geklappt.


Anmelden zum Antworten