Server - Client Problem



  • Hallo Forumsgemeinde,

    ich bin neu hier und werde in vermutlich in Zukunft öfters hier vorbeischauen 😉

    Ich habe bei meiner Anwendung noch folgende Probleme:

    1. Wenn ich vom Client den Befehl DATA an den Server (der eigentlich in einer Dauerschleife rennt .. also nie off geht) sende soll der Server an den Client alle Dateinamen die im Verzeichnis sind den Client zurückgeben und der Client soll es auflisten.

    Problem: der server gibt sie zwar an den Client zurück, nur der Client haut sie in einer Zeile raus (also ohne \n bzw abstand) ich hab versucht den dateistring + \n in einem buffer zusammenzufügen und dann zum client zu schicken, aber das funktioniert nicht. Zudem bekommt der Server nachdem er die Dateinamen zum Client gesendet hat.

    1. Mit COME <Dateiname> soll eine Datei vom Server zum Client transferiert werden und es soll blockweise über den Socket übertragen werden und im ClientVerzeichnis gespeichert werden.

    Problem: Ich habe keine Ahnung wie ich es hinbekommen soll, dass der Client mit COME <Dateiname> den Befehl gibt. Bei Data war es noch einfach einfach strcmp genommen. Aber hier müsste ich ja irgendwie abfragen ob sich die Datei am Server existiert oder nicht. Am server würde ich dann sendfile() verwenden (ich hoffe das geht) oder was ist mit "blockweise über den Socket übertragen" gemeint?

    Ich hoffe es kann mir wer helfen.

    Lg hh 😉



  • Hamburger_Jung schrieb:

    Ich hoffe es kann mir wer helfen.

    wohl kaum, wir können nämlich nicht hellsehen.



  • supertux schrieb:

    Hamburger_Jung schrieb:

    Ich hoffe es kann mir wer helfen.

    wohl kaum, wir können nämlich nicht hellsehen.

    was meinst du damit jetzt genau?

    hier der servercode, als zweites argument muss beim server das verzeichnis[argv2] angegeben werden:

    do {
    	//Befehl von Client erhalten
            size = recv (new_socket, buffer, BUF-1, 0);
            if( size > 0)
            {
             	buffer[size] = '\0';
    
    		if(strncmp(buffer, "DATA",4) == 0)
    		{
    
    				printf ("Message received: %s\n", buffer);
    				ptr = argv[2];
    				if((num_entries = scandir(ptr, &namelist, 0, alphasort)) < 0)
    				{
    					fprintf (stderr, "Unerwarteter Fehler\n");
    					exit (EXIT_FAILURE);
    				}
    
    				chdir(ptr);
    				getcwd (wd, BUF);
    				printf("%d Dateien im Verzeichnis: %s\n", num_entries, wd);
    				if(num_entries > 0 )
    				{
    					for(i = 0, list = namelist; i <= num_entries; i++, list++)
    					{
    						//printf("%s\n", (*list)->d_name);
    						//strcat((*list)->d_name,"\n");
    						strcpy(buffer,(*list)->d_name);
    						send(new_socket, buffer, strlen(buffer),0);
    						free (*list);
    					}
    					free(*namelist);
    					printf("\n");
    
    				}
    				else { err++; }
    				printf("\n");
    
    			//ok falls kein Fehler besteht
    			if(err==0)
    			{
    				strcpy(buffer,"OK");
    				send(new_socket, buffer, strlen(buffer),0);
    			}
    			else
    			{
    				strcpy(buffer,"ERROR");
    				send(new_socket, buffer, strlen(buffer),0);			
    			}
    		}
    

    und hier der client:

    do {
         //printf ("Send message: ");
         fgets (buffer, BUF, stdin);
    
    	if(strcmp(buffer,"DATA\n") == 0)
    	{
    		//DATA Befehl an server übertragen
    		send(create_socket, buffer, strlen (buffer), 0);
    
    		//bekommt OK vom Server bei Erfolg
    		size=recv(create_socket,buffer,BUF-1, 0);
    		if (size>0)
    		{
    			buffer[size]= '\0';
    			printf("%s\n",buffer);
    		}
         	}
    	else if(strcmp(buffer,"COME\n") == 0)
    	{
    		/*...*/
         	}
    	else
    	{
    		printf("Es werden nur folgende Befehle erkannt: DATA, COME und QUIT\nBitte erneut versuchen\n");
    	}
      }while (strcmp (buffer, "QUIT\n") != 0);
    


  • Hi,

    ok also mein Problem hat sich in zwischen aufgelöst. Das Problem war einfach, das ich mit Polling arbeite und die Poll-Struktur nur Filedescriptoren entgegennimmt. Da ich mit den spezifischen File-Methoden fopen & Co. gearbeitet hatte, konnte ich natürlich nicht das Filehandle in die Poll-Struktur packen. Die Lösung war einfach die allgemeineren Methoden open & Co. zu verwenden. Somit hatte ich dann einen Filedescriptor mit dem ich arbeiten konnte 👍

    Trotzdem danke 🙂

    Lg Tobi



  • T0bi schrieb:

    Hi,

    ok also mein Problem hat sich in zwischen aufgelöst. Das Problem war einfach, das ich mit Polling arbeite und die Poll-Struktur nur Filedescriptoren entgegennimmt. Da ich mit den spezifischen File-Methoden fopen & Co. gearbeitet hatte, konnte ich natürlich nicht das Filehandle in die Poll-Struktur packen. Die Lösung war einfach die allgemeineren Methoden open & Co. zu verwenden. Somit hatte ich dann einen Filedescriptor mit dem ich arbeiten konnte 👍

    Trotzdem danke 🙂

    Lg Tobi

    kann es sein, dass du den falschen thread benutzt? 😕



  • Nimm statt strcmp lieber http://www.manpagez.com/man/3/strstr/ .



  • Paul Müller schrieb:

    Nimm statt strcmp lieber http://www.manpagez.com/man/3/strstr/ .

    Hallo, das strcmp funktioniert doch 😉
    mit strstr such ich doch nach einem Teil in einem Wort? Wenn ich den Befehl DATA bzw COME an den Server schicke reargiert er ja.



  • Hat sich beim Überfliegen so angehört, als ob du nicht wüsstest, wie du erkennst, dass ein bestimmtes Wort im Text vorkommt. Wobei man mit strncmp() auch ganz gut das Kommando erkennen kann, wenn man annimmt, dass das Kommando mit dem ersten Zeichen im Text beginnt. Alternativ kann man zwar testen, aber strstr() bietet sich da mehr an. Es ist übrigens auch kein Problem C++ mit C-Funktionen zu mischen, bis auf Ausnahmen (zB. malloc). Wenn du das aber machst, solltest du das Projekt möglichst vollständig in C++ machen. Das gilt besonders für die Dateiendung (.cpp), viele Compiler, wenn nicht sogar alle, entscheiden die Sprache Anhand der Erweiterung. Sonst musst du den C++-Objekt-Files noch zusätzlich beibringen, dass du gegen C-Objekt-Files linkst (Stichwort: extern "C"). Ist auch nicht weiter tragisch oder kompliziert, kann aber frustrierend sein, wenn es nicht in kurzer zeit auffällt.



  • Paul Müller schrieb:

    Hat sich beim Überfliegen so angehört, als ob du nicht wüsstest, wie du erkennst, dass ein bestimmtes Wort im Text vorkommt. Wobei man mit strncmp() auch ganz gut das Kommando erkennen kann, wenn man annimmt, dass das Kommando mit dem ersten Zeichen im Text beginnt. Alternativ kann man zwar testen, aber strstr() bietet sich da mehr an. Es ist übrigens auch kein Problem C++ mit C-Funktionen zu mischen, bis auf Ausnahmen (zB. malloc). Wenn du das aber machst, solltest du das Projekt möglichst vollständig in C++ machen. Das gilt besonders für die Dateiendung (.cpp), viele Compiler, wenn nicht sogar alle, entscheiden die Sprache Anhand der Erweiterung. Sonst musst du den C++-Objekt-Files noch zusätzlich beibringen, dass du gegen C-Objekt-Files linkst (Stichwort: extern "C"). Ist auch nicht weiter tragisch oder kompliziert, kann aber frustrierend sein, wenn es nicht in kurzer zeit auffällt.

    hmm.. ja schön und gut, aber mein problem zu 1) ist dass der server ein segmentation fault bekommt wenn er die namen der files die im verzeichnis stehen an den client zurück schickt und der client listet sie nicht auf sondern schreibt sie in einer zeile direkt hintereinander also zb: textadatei1.txttextdatei2.txttextdatei3.txt

    und ich will es so:
    textdatei1.txt
    textdatei2.txt ...

    und ich weiß nicht wie ich dem server ein \n mitgib 😉 das der client dann annimmt 😃 ich wollt jetzt 2 strings zusammenbinden sprich textdatei1.txt + \n, das gefällt ihm aber ganz und garnicht 😉 und dann ist auch noch das segmentation fault. das auch noch auftritt 🤡



  • Hamburger_Jung schrieb:

    hmm.. ja schön und gut, aber mein problem zu 1) ist dass der server ein segmentation fault bekommt wenn er die namen der files die im verzeichnis stehen an den client zurück schickt

    Bist du dir sicher, dass die ganzen free() an der Stelle richtig sind? Sonst würde ich mal mit dem Debugger die Stelle eingrenzen, wo der Segfault zu Stande kommt.

    Hamburger_Jung schrieb:

    und der client listet sie nicht auf sondern schreibt sie in einer zeile direkt hintereinander also zb: textadatei1.txttextdatei2.txttextdatei3.txt

    Probiere mal statt strcpy(), lieber sprintf() zu nutzen.

    Hamburger_Jung schrieb:

    ich wollt jetzt 2 strings zusammenbinden sprich textdatei1.txt + \n, das gefällt ihm aber ganz und garnicht 😉

    Wie schon erwähnt, man kann problemlos C-Funktionen in C++ nutzen. Arrays über den Additionsoperator zu verknüpfen geht in beiden Sprachen nicht. Aber du kannst in C++ std::string nutzen, welcher eine solche Funktion bietet.

    Hamburger_Jung schrieb:

    und dann ist auch noch das segmentation fault. das auch noch auftritt 🤡

    Wie schon erwähnt, der Debugger ist dein Freund. Ich weiß auch nicht, woher die Abneigung gegen valgrind kommt. Einfacher kann man Speicherfehler nicht finden.


Anmelden zum Antworten