select() für eine Chatanwendung



  • Hallo,
    vorweg erstmal, ich bin ein C-Neuling.

    ich bin dabei ein einfaches Chatprogramm bestehend aus Client und Server zu implementieren.

    Mein Client soll versuchen eine Verbindung per UDP bzw. sendTo() zum Server aufzubauen. Falls innerhalb von 5 sek keine Antwort kommt, soll er nochmal sendTo() ausführen und wieder 5 Sekunden warten.

    Ich dachte das Problem mit der Wartezeit kann ich mit der select()-Funktion lösen. Wenn ich dem struct timeval 5 Sekunden mitgebe, dann wartet select() 5 Sekunden und falls in der Zeit eine Antowrt vom Server kommt, bricht select das blockieren ab. Habe ich das richtig verstanden?
    Kennt ihr einen anderen Weg ich Wartezeit implementieren kann?

    Ich habe schon ein wenig mit select rumgespielt.
    Hier ein Ausschnit aus meinem Code:

    int counter, res;
    counter = 1;
    fd_set rfds;
    
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    
    while(counter < 4) {
    		FD_ZERO(&rfds);
    		FD_SET(socket_fd, &rfds);
    		FD_SET(0, &rfds);
    		res = select(socket_fd + 1, &rfds, NULL, NULL,&timeout);
    		if (res<=0) {
    			printf("Fehler beim select()!\n");
    		}
    		if (FD_ISSET(socket_fd,&rfds)) {
    			bzero(buff,7);
    			res = read(socket_fd,buff,7);
    			if (res<0) { 
    				printf("Fehler beim read()\n");
    			}
    			if (res==0) printf("Received EOF on fd1!\n");
    			else printf("Received data on fd1: %s\n",buff);
    		}
    	}
    

    Ich würde erwarten, dass das Programm dreimal durch die Schleife läuft und dreimal select() ausführt, also das Programm min. 15 sek läuft. Dies is aber nicht der Fall, es blockiert 5 Sekunden und danach werden alle Ausgaben auf der Konsole ausgegeben und fertig. Warum wird nicht dreimal ein select ausgeführt?

    LG



  • Du hättest mal einen Zähler mit Ausgabe einbauen können, dann hättest du gesehen, dass er dreimal durchläuft.

    Das Problem ist, dass manche select-Implementationen in der struct timout die Restzeit zurückgeben.
    Die ist beim Ablauf des timeout allerdings Null.
    Du rufst select also beim zweiten mal mit timeout = 0 auf. Also sofort zurück.

    Zeile 5 und 6 gehören also in die while-Schleife.

    Welches Betriebssystem hast du denn?



  • Hi,
    achso, das erklärt einiges. Ich benutze Ubuntu 12.04.
    Ist denn die select-Funktion der richtige Weg sowas zu implementieren, oder gibt es da noch was "besseres"?

    LG



  • select wird auch gerne genommen um Zeiten weniger als eine Sekunde zu warten

    select(0, NULL, NULL, NULL,&timeout);
    

    Für das timeout, ist es das Richtige, aber,...
    ob es der richtige Weg für ein Chatprogramm ist, kann ich dir nicht sagen.


Anmelden zum Antworten