Winsock datei sende problem



  • Ich hab ein Problem beim senden.Hier der quelltext:
    Server:

    int Filesize;
    rc = recv(cs,buf,11,0);
    if(buf[0]=='2' && buf[1]=='.' &&  buf[2]=='3' || buf[2]=='4')
    {
    
    		buf[0]='0';
    
    			rc = send(cs,buf,10,0);
    			return 0;
    }
    else
    {
    buf[0]=1;
    rc = send(cs,buf,3,0);
    
    rc = recv(cs,buf,11,0);
    if(buf[0]=1)
    {
    	Filesize=sizeof(update);
    	 buf[0]=Filesize;
    
    	rc = send(cs,buf,200,0);
    	char buf2[sizeof(update)];
    	update.get(buf2,sizeof(update));
    	rc = recv(cs,buf,200,0);
    	cout<<buf<<"\n\n";
    
    	cin.get();
    	Sleep(2000);
    	while(Filesize>0)
    	{
    		rc = send(cs,buf2,sizeof(update),0);
    	Filesize=Filesize-1;
    	}
    	update.close();
    
    }
    else
    {
    }
    

    Client:

    //darüber version überprüfung
    else if (test[0]='1')
    {
    	buf[0]='1';
    		rc = send(s,buf,10,0);
    
    		rc = recv(s,buf,3,0);
    
    	Filesize=(int) buf;
    
    char *buf2;
    buf2=new char(100000);
    
    cout<<"Warte auf daten!\n\n";
     rc = send(s,buf2,20,0);
    
     int fz=Filesize;
     cout<<"Zu übertragende Bytes: "<<fz<<"\n";
    
    while(deux>0)
    {
        cout<<"\rÜbertragen: "<<Filesize;
    	rc = recv( s, buf2, fz, 0 );
    
    Filesize=Filesize-1;
    }
    update << buf2;
    cout<<"\n\nFertig\n";
    cin.get();
    
    delete buf2;
    update.close();
    }
    

    Ich will ein Textfile kopieren.Zuerst lese ich mit dem Server
    die grösse aus sende diese dem Client.
    danach wird beim senden die grösse immer um eins verringert.
    Eigentlich steht in der Datei nur ein "hallo wie gehts?".
    Irgend wie sendet der Server nicht und irgendwie empfängt
    der client was aber irgendwie nicht weil im Textfile vom
    Client nichts steht.Das schließe ich daraus das er Filesize rechnet
    obwohl der server nichts tut.Weil eigentlich
    hält das programm bei send oder recv bis es ausgeführt wurde an.
    Beim Clienten ist es nicht so.Un beim Server stimmt
    es irgendwie auch nicht.Ich sende ja die File größe an den Clienten der
    hat dann die zahl 2292240(halt die grösse).Beim server aber ist sie
    nur *mal* 510 oder 540 usw groß es ändert sich immer.
    Und wenn der Client runter gezählt hat und aus ist da
    hat er plötzlich gerechnet und hat am ende 100.
    Was mach ich falsch?



  • Du überprüfst ja gar nicht wieviel du wirklich empfangen hast nach dem Aufruf von recv?!



  • Meinen sie das könnte damit zusammen hängen?Und wie geht das?



  • ich kann ihnen nur empfehlen alles nochmal neu zu schreiben. der code ist momentan grauenhaft.



  • Ok ich hab ihn noch nicht auskommentiert. Mach ich aber noch.



  • Ich poste in solchen fällen immer wieder gerne folgendes:
    http://aluigi.altervista.org/mytoolz/sendrecv.zip



  • achtet mal auf den ordnernamen - mytoolz - hört sich gefährlich an ⚠ ⚠



  • Ich kann es nicht öffnen Winrar sagt es sei beschädigt.



  • kopier mal den link und füg ihn in eine neues browser fenster ein.



  • Problem gelöst.Ich schau's mir dann mal an. Danke so wie dein Programm soll das am ende aussehen. Bei mir hatte ich unter anderen das Problem mit der Dateigröße
    rausfinden.



  • So eine Frage neben bei weil ich ja das ganz selber machen will also nichst
    von irgendjemand rauskopieren schauen was passiert...Jetzt meine Frage ich
    lesen mit GetFileSize die größe aus in ein DWORD.Datei=10.8 MB groß reicht
    DWORD?Und wenn ja Wie kriege ich diese werte in ein char um diese
    per send zu senden und in einen intiger um mein char die richtige größe
    reservieren kann.
    Und das hier weiß hab ich leider vergessen:

    char *buf2;
    buf2=new char(1024);//ist das in den() bit,byte..?
    


  • ja.
    und
    byte.



  • Du dürftest aber eckige Klammern benötigen - so belegst du nur Platz für ein char (mit dem Wert 1024 => 0).



  • Stefan311 schrieb:

    So eine Frage neben bei weil ich ja das ganz selber machen will also nichst
    von irgendjemand rauskopieren schauen was passiert...Jetzt meine Frage ich
    lesen mit GetFileSize die größe aus in ein DWORD.Datei=10.8 MB groß reicht
    DWORD?Und wenn ja Wie kriege ich diese werte in ein char um diese
    per send zu senden und in einen intiger um mein char die richtige größe
    reservieren kann.
    Und das hier weiß hab ich leider vergessen:

    char *buf2;
    buf2=new char(1024);//ist das in den() bit,byte..?
    
    char  cBufToSend[1024];
    HANDLE hFile;
    DWORD dwFileSize;
    
    hFile = GreateFile( bla, bla bla, sorry bin zu faul);
    
    dwFileSize = GetFileSize(hFile, 0);
    
    _snprintf(cBufToSend, sizeof(cBufToSend), "%d", dwFileSize);
    
    send( sock, cBufToSend, lstrlen(cBufToSend), 0);
    

    Server empfängt String und prepariert es:

    DWORD dwFileSize;
    recv( sock, cBufToRecv, sizeof(cBufToRecv), 0);
    
    dwFileSize = atof(cBufToRecv);
    

    so hätte ich es gemacht,

    danach kannst du die Datei Byteweise in cBufToSend einlesen mod:"rb" (bis EOF erkannt wird) und per Socket versenden.
    Der Server empfängt dann den Buffer und schreibt es in vorher mit CreateFile erstellte Datei rein.

    Also du muss ein Protokol entwickeln:
    z.B.

    char buf[1024];
    dann sieht der Transfer so aus
    ->[ part1$$FileSizeFileSize$$FileName.exe$$00000000 binäre data 0000000000000] ->[ part2$$000000000000000000 binäre data 00000000000000000000000000000]
    ...
    ->[ partX$$000000000000000000 binäre data 0000000000000000$$EndOfFile]

    wobei $$$ ein Trenner ist.

    Dein Empfänger muss dann solange die Daten empfangen und in Datei schreiben bis er im String EndOfFile findet. Hoffe du verstehst mich, mein Deutsch ist noch zimlich schlecht 😞

    Stefan311 schrieb:

    char *buf2;
    buf2=new char(1024);//ist das in den() bit,byte..?

    Na was denkst du was das "char" wohl ist??? Bit??? Byte??? oder DWORD???
    Dein Pointer(buf2) zeigt nun auf ein 1024 BYTES große Bereich im Speicher 👍



  • Danke für die vielen antworten.Endlich weiß ich wieder was
    das in der klammer war.Jetzt muss ich erstmal viel nachdenken wie ich
    das am besten mache und muss mich mal noch ein wenig unter msdn
    über Createfile schlau machen.Ich hab schomal(für was anderes) versuch mit
    Createfile etwas zu erstellen.Da war ich überfordert mit DWORD usw..Inszwischen
    hab ich es verstanden.



  • Jetzt hab ich mal wieder ne Frage GetFileSize gibt ja bytes zurück.
    Aber sind 10,8 MB = 4294967295 Bytes sind? Und wenn ja
    warum dauert das senden so lange?

    im moment hab ich das so:

    while(FileSize>0)
    {
    cout<<"\rÜbertragen: "<<FileSize;
    rc = send();
    FileSize=FileSize - rc;
    }
    

    Ist das so richtig?
    Ps:Hab gerade festgestellt das die datei die der Client speichert größer ist
    als die Ausgangsdatei. Was ist falsch?



  • Also Stefan ich verstehe das du alles selber machen willst, aber irgendwie ist
    mir einfacher dir ein Beispiel zu zeigen als das ganze zu erklären. Und ein Beispiel, meiner Meinung nach sagt/zeigt es besser als ich.

    Also ich stünde auch vor langer Zeit vor dem Problem ein Datei über Winsock zu versenden und ich habe es so gemacht:

    Beachte dass das ein einfacher Beispiel ist und evtl. noch verbessert werden kann

    //Sender (Client) Diese Teil versendet ein Datei
    #include <stdio.h>
    #include <winsock2.h>
    
    int startWinsock(void)
    {
    	WSADATA wsa;
    	return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    int main(void)
    {
    	SOCKET s;
    	SOCKADDR_IN addr;
    	FILE *file;
    	char buf[1024];
    	int num;
    
    	char ip[]    = "127.0.0.1";	// Ziel-IP
    	int port     = 123;		// Port
    	char datei[] = "C:\\file.exe";// Datei zum versenden
    
    	printf("\n");
    
    //-----------------------------------------------------------
    	// Winsock initialisieren 	 
    	if( startWinsock() != 0 )
    	{
    		printf("Fehler: Winsock kann nicht initialisiert werden\n\n");
    		return 1; 
    	}
    
    //-----------------------------------------------------------------
    	// Socket erstellen 
    	s = socket(AF_INET,SOCK_STREAM,0);
    	if( s == INVALID_SOCKET )
    	{
    		printf("Fehler: Socket kann nicht erstellt werden\n\n");
    		return 1; 
    	}
    
    //-----------------------------------------------------------
    	// Verbinden mit Zielhost 
    	memset(&addr, 0, sizeof(SOCKADDR_IN));	 
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(port);			
    	addr.sin_addr.s_addr = inet_addr(ip);	
    
    	if( connect(s, (SOCKADDR*)&addr, sizeof(SOCKADDR)) == SOCKET_ERROR )
    	{
    		printf("Fehler: Verbindung mit %s kann nicht hergestellt werden\n\n", ip);
    		return 1; 
    	}
    	printf("Verbunden mit %s\n", ip);
    
    ------------------------------------------------------------------
    	// Datei versenden 
    	if( (file = fopen(datei, "rb")) == NULL )
    	{
    		printf("Fehler: Datei %s kann nicht geoffnet werden\n\n", datei);
    		return 1; 
    	}
    
    	printf("Sende Datei... ");
    	while( !feof(file) )
    	{
    		num = 0;
    		num = fread(buf, sizeof(char), sizeof(buf), file);
    		num = send(s, buf, num, 0);
    		if( num == SOCKET_ERROR )
    		{
    			printf("\nFehler: Fehler beim senden aufgetreten\n\n");
    			return 1; 
    		}
    		printf(".");  
    	}
    	printf("\nDatei erfolgreich versendet!\n\n");
    
    	fclose(file);
    	closesocket(s);
    	WSACleanup();
    
    	return 0;
    }
    
    //Empfänger (Server) empfängt ein Datei	
    #include <stdio.h>
    #include <winsock2.h>
    
    int startWinsock(void)
    {
    	WSADATA wsa;
    	return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    int main(int argc, int *argv[])
    {
    	SOCKET acceptSocket, s;
    	SOCKADDR_IN addr;
    	FILE *file;
    	char buf[1024];
    	int num;
    
    	char datei[] = "C:\\newfile.exe";			// Datei path
    	int port = 123;							// Port
    
    	printf("\n");
    
    //-----------------------------------------------------------
    	// Winsock initialisieren 
    	if( startWinsock() != 0 )
    	{
    		printf("Fehler: Winsock kann nicht initialisiert werden\n\n");
    		return 1; 
    	}
    
    //-----------------------------------------------------------------
    	// Socket erstellen 
    	acceptSocket = socket(AF_INET,SOCK_STREAM,0);
    	if(acceptSocket == INVALID_SOCKET)
    	{
    		printf("Fehler: Socket kann nicht erstellt werden\n\n");
    		return 1; 
    	}
    
    //--------------------------------------------------------
    	// Socket an das Port binden 
    	memset(&addr,0,sizeof(SOCKADDR_IN));
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(port);
    	addr.sin_addr.s_addr = ADDR_ANY;
    
    	if( bind(acceptSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR )
    	{ 
    		printf("Fehler: Socket kann an das port nicht gebunden werden\n\n");
    		return 1;
    	}
    
    //------------------------------------------------------------
    	// Auf Verbindung warten 
    	if( listen(acceptSocket,10) == SOCKET_ERROR )
    	{
    		printf("Fehler: listen()\n\n");
    		return 1; 
    	}
    	printf("Warte auf Verbindung...\n");
    
    //-----------------------------------------------------------
    	// Verbindung akzeptieren 
    	s = accept(acceptSocket,NULL,NULL);
    	if(s == INVALID_SOCKET)
    	{
    		printf("Fehler: accept()\n\n");
    		return 1;
    	}
    	printf("Verbindung akzeptiert\n");
    
    //------------------------------------------------------------------
    	// Datei empfangen 
    	if( (file = fopen(datei, "wb")) == NULL )
    	{
    		printf("Datei %s koennte zum schreiben nicht geoffnet werden\n\n", datei);
    		return 1; 
    	}
    	printf("Datei %s zum schreiben geoffnet\n", datei);
    
    	printf("\nEmpfange Datei...\nBitte warten... ");
    	while( (num = recv(s, buf, sizeof(buf), 0)) > 0 )
    	{
    		fwrite(buf, sizeof(char), num, file);
    		printf("."); 
    	}
    	printf("\nDatei empfangen!\n\n");
    	fclose(file);
    	closesocket(s);
    	WSACleanup();
    	return 0;
    }
    

    Wie du das mit dem FileName etc hinkriegst siehe oben 👍

    Übrigens, ein 10 MB grosse Datei zu versenden wird schon eine gewiesse Zeit in Anspruch nehmen, auch bei DSL.

    Versuch es erst mit kleineren Dateien, wenn du sicher bist, dass alles 100% funktioniert dann kannst du es auch an deinem 10 MB Datei ausüben.



  • Also senden klappt jetzt.Danke 👍 .
    Aber ich kann die exe dann nicht starten. 😕
    Da Flimmert kurz auf und sofort wieder aus.



  • Was für ne exe???
    Vieleicht ist das eine Konsolenanwendung??? 😕
    Bei mir hat das einwandfrei funktioniert 🙄



  • Also hab jetzt nochmal alles extra überprüft, und muss sagen das es funktioniert bei mir.

    Vieleicht machst du was falsch?
    Sender erwartet eine "file.exe" Datei auf Laufwerk C:\ zum versenden.
    Emfänger schreibt dann emfangene Datei in C:\newfile.exe.

    Warum es bei dir nicht geht weiss ich nicht, aber ich vermutte das du eine
    Konsolenanwendung versendet hast, und die startet mann auch normalerweise
    aus Konsole/Eingabeaufforderung aus. Am sonsten passiert das wovon du erzählt
    hast --> "Flimmert kurz auf und sofort wieder aus".

    Grüß


Anmelden zum Antworten