filedescriptor - wie waehlen



  • Das mit dem weglassen von stdin hab ich schon probiert, funkt nicht.
    Aber ich mach mal ein flush, vielleicht bringt das was!

    Auf jeden Fall mal danke fuer deine Erklaerungen! 👍



  • Also es will immer noch nicht so richtig.
    Hab das Programm ein wenig veraendert und eigentlich ist es ja schon fast fertig. Hier nur noch die for-Schleife, an der ja eigentlich alles haengt:

    for ( ; ; )
    			{
    				fflush( STDIN_FILENO );
    
    				/* setz den file descriptor zusammen */
    				FD_ZERO( &socks ); /* leert den file descriptor socks, so dass er keine Elemente mehr enthaelt */
    				FD_SET( SERVER_SOCKET, &socks ); /* Fuege den server_socket zum file descriptor */
    				FD_SET( STDIN_FILENO, &socks ); /* Fuege den standard input zum file descriptor hinzu */
    
    				in_sockets = select( max, &socks, (fd_set *)0, (fd_set *)0, NULL );
    
    				if ( FD_ISSET( SERVER_SOCKET, &socks ) )
    				{
    					fprintf( stdout, "\tsocket handler is active!\n" );
    
    					if( ( bytes = recvfrom( SERVER_SOCKET, buffer, strlen( buffer ), 0, NULL, NULL ) ) == -1 ) 
    					{
    						fprintf( stderr, "%s: recvfrom() failure!\n", argv[0] );
    						close( SERVER_SOCKET );
    						exit( EXIT_FAILURE );
    					}
    					buffer[bytes] = '\0';
    
    					fprintf( stdout, "%s\n", buffer );
    				}
    				else if ( FD_ISSET( STDIN_FILENO, &socks ) )
    				{
    					fprintf( stdout, "\tinput handler is active!\n" );
    					if ( (bytes = read( STDIN_FILENO, buffer, strlen( buffer ) ) ) == -1 )
    					{
    						fprintf( stderr, "%s: read() failure!\n", argv[0] );
    						close( SERVER_SOCKET );
    						exit( EXIT_FAILURE );
    					}
    
    					buffer[bytes] = '\0';
    
    					client_address.sin_family = AF_INET;
    					client_address.sin_addr.s_addr = inet_addr( r_addr );
    					client_address.sin_port = htons( r_port ); 
    
    					if( sendto( SERVER_SOCKET, buffer, strlen(buffer), 0, (struct sockaddr *)&client_address, sizeof(client_address) ) == -1)
    					{
    						fprintf( stderr, "%s: sendto() failure!\n", argv[0] );
    						close( SERVER_SOCKET );
    						exit( EXIT_FAILURE );
    					}
    				}
    				else
    				{
    					fprintf( stderr, "select() FD_ISSET failure!\n" );
    				}
    			}
    

    Ich lande immer noch, nachdem ich etwas erhalten oder gesendet habe in einer Endlosschleife - das Select wird einfach uebersprungen. Die Handler setz ich wie du siehst bei jedem Schleifendurchlauf neu.
    fflush hat auch nichts gebracht.
    Die Variablen, die neu Hinzugekommen sind sind alle korrekt. Das Programm uebersetzt auch ohne murren
    [code]gcc -Wall -Werror -ansi chat.c -o chat[/cpp]
    Trotzdem funkt es nicht.
    Vielleicht noch ne Idee?

    mfg



  • moe szyslak schrieb:

    gcc -Wall -Werror -ansi chat.c -o chat
    

    Warum machst du das denn alles? select selbst braucht keine Complier-Flags.

    kann doch sein, dass fflush auch als Schreiboperation interpretiert wird und darum select anschlägt.
    Du willst einen Server bauen, der horcht aber auch reagiert, wenn einer was aintippt, wieso machst du nicht was mit fork und pipe-Kommunikation zwischen der Prozess, der am Server lauscht und dem Eingabe-Prozess, dann könntest du den Pipe-Deskriptor zu deiner select-Menge hinzufügen.



  • gcc -Wall -Werror -ansi chat.c -o chat
    Das sind alles Compilerflags die mir
    -Wall (Alle Warnungen anzeigen)
    -Werror (Warungen und Fehler speziell angezeigt werden)
    -ansi (Verstoesse gegen den ANSI C Standard anzeigen)

    Einen Fehler hab ich glaub ich schon gefunden, im Select muss das max um eins erhoeht werden, also max+1, sonst funktioniert es nicht.
    Nur haeng ich immer noch in der Schleife fest - mal schaun, die Nacht ist noch Jung *g*.

    [edit] Musste gerade ein sehr seltsames Phanomen beobachten. Wenn ich meinen Server starte (die for-Schleife sieht jetzt so aus: )

    for ( ; ; )
    	{
    		FD_ZERO( &filedesc );
    		FD_SET( server_socket, &filedesc );
    		FD_SET( STDIN_FILENO, &filedesc );
    
    		sel_result = select( max+1, &filedesc, NULL, NULL, NULL );
    
    		if ( FD_ISSET( server_socket, &filedesc ) )
    		{
    			if( ( bytes = recvfrom( server_socket, buffer, sizeof(buffer), 0, NULL, NULL ) ) == -1 )
    			{
    				fprintf( stderr, "%s: recvfrom() failure!\n", argv[0] );
    				close( server_socket );
    				exit( EXIT_FAILURE );
    			}
    			if ( buffer[bytes-1] != '\0' )
    				buffer[bytes] = '\0';
    
    			fprintf( stdout, "[Client]: %s\n", buffer );
    			/* break; */
    		}
    		else if ( FD_ISSET( STDIN_FILENO, &filedesc ) )
    		{
    			if ( (bytes = read( STDIN_FILENO, buffer, strlen( buffer ) ) ) == -1 )
    			{
    				fprintf( stderr, "%s: read() failure!\n", argv[0] );
    				close( server_socket );
    				exit( EXIT_FAILURE );
    			}
    
    			if ( buffer[bytes-1] != '\0' )
    				buffer[bytes] = '\0';
    
    			client_address.sin_family = AF_INET;
    			client_address.sin_addr.s_addr = inet_addr( r_addr );
    			client_address.sin_port = htons( r_port );
    
    			if( sendto( server_socket, buffer, strlen(buffer), 0, (struct sockaddr *)&client_address, sizeof(client_address) ) == -1)
    			{
    				fprintf( stderr, "%s: sendto() failure!\n", argv[0] );
    				close( server_socket );
    				exit( EXIT_FAILURE );
    			}
    		}
    		FD_CLR( server_socket, &filedesc );
    		FD_CLR( STDIN_FILENO,  &filedesc );
    	}
    

    und mir mit nc eine UDP-Nachricht zuschicke kann ich mich dann getrost alleine ueber das Programm mit der Gegenstelle unterhalten.
    Wenn ich das mit nc aber vergesse, dann gerate ich wieder in die Endlosschleife ...

    🙄 🙄 😡 😮



  • spontan wuerd ich den timeoutparameter von select() ueberpruefen. ich weiss nicht genau, ob es unendlich bei NULL oder 0.0sekunden wartet.



  • c.rackwitz schrieb:

    spontan wuerd ich den timeoutparameter von select() ueberpruefen. ich weiss nicht genau, ob es unendlich bei NULL oder 0.0sekunden wartet.

    Bringt nichts, schon probiert!

    [Edit] Ok, bringt doch was, aber noch nicht das richtige Ergebnis.
    Wenn ich jetzt was eingebe kommt es auf der Gegenseite nicht kommplett wie z.B.
    hallo
    an, sonern in der art:
    h
    a
    l
    l
    o

    Mal, schaun, vielleicht verwende ich statt strlen sizeof, muss erst kontrollieren!



  • ein/ausgabe ist nicht zeilengepuffert!



  • Och Gott, manchmal ist es schon schlimm, danke fuer den Hinweis, schon geloest. Jetzt funktionierts!



  • c.rackwitz schrieb:

    spontan wuerd ich den timeoutparameter von select() ueberpruefen. ich weiss nicht genau, ob es unendlich bei NULL oder 0.0sekunden wartet.

    Bei NULL ist die Funktion blockiert bis was passiert.



  • Im Moment macht der Timeout-Parameter keinen Unterschied!
    Es funktioniert einfach nicht mehr!
    😞
    Und zwar liegt das Problem hier:

    if( ( bytes = recvfrom( SERVER_SOCKET, buffer, strlen( buffer ), 0, NULL, NULL ) ) == -1 )
    

    Wenn ich versuche ne Struktur statt NULL, NULL mitzugeben dann kann ich nicht mehr empfangen und senden, ist mir unverstaendlich!


Anmelden zum Antworten