probleme mit select()

Dieses Thema im Forum "C/C++" wurde erstellt von Schnabeltasse, 21.02.2007.

  1. #1 Schnabeltasse, 21.02.2007
    Zuletzt bearbeitet: 21.02.2007
    Schnabeltasse

    Schnabeltasse Grünschnabel

    Dabei seit:
    21.02.2007
    Beiträge:
    2
    Zustimmungen:
    0
    Hallo zusammen,

    ich habe folgendes Problem:
    Bin gerade dabei ein "kleines Chatprogramm" zu schreiben.
    Dabei handelt es sich um eine Server-Client Applikation.
    Das Serverprogramm soll auf Linux laufen und der Client auf Windows.
    Nun geht es mir um das Serverprogramm.
    Intern arbeitet das Programm mit zwei Threads einen zur Nachrichtenverarbeitung und einen anderen für die Kommunikation übers Netzwerk und den damit verbundenen Verbindungsaufbau über einen Listen Socket.
    Die Beiden threads kommunizieren über ein Array von Nachrichten in das der eine schreibt und aus dem der andere liest.

    Mein Problem liegt nun im Kommunikationsthread.
    nachdem ich select aufgerufen habe mit einem fd_set, in dem auch der ListenSocket drinne ist, ist dieser nicht gesetzt nachdem sich der Client an dem Server angemeldet hat.
    Also baut der Client erfolgreich eine Verbindung auf aber merkwürdigerweise kriegt der Server das nicht mit (FD_ISSET gibt keinen erfolg zurück).

    Code:
    int iListen;
    	int iMax = 0;
    	int c;
    	int iZahl = 0;
    	int bytes;
    	struct sockaddr_in addr;
    	CClientListe* pSender;
    	bool bDone = false;
    	fd_set fds;
    	char buf[1024];
    
    	iListen = socket(AF_INET, SOCK_STREAM, 0);
    	if(iListen == -1)
    	{
    		perror("socket() failed");
    	}
    	else
    	{
    		addr.sin_addr.s_addr = INADDR_ANY;
    		addr.sin_port = htons(7000);
    		addr.sin_family = AF_INET;
    		bind(iListen, (struct sockaddr*)&addr, sizeof(addr));
    		if(listen(iListen, 3) == -1)
    			printf("Fehler bei liste()\n");
    		struct timeval timeout;
    		while(!bDone)
    		{
    			FD_ZERO(&fds);
    			pthread_mutex_lock(&g_pClients->m_mutex);
    				g_pClients->FillSet(&fds);
    				iMax = g_pClients->m_iMax;
    			pthread_mutex_unlock(&g_pClients->m_mutex);
    			FD_SET(iListen,&fds);
    			if(iMax < iListen)
    				iMax = iListen;
    			timeout.tv_sec = 0;
    			timeout.tv_usec = 1;
    			select(iMax,&fds, NULL,NULL,&timeout);
    			if(FD_ISSET(iListen, &fds))
    			{
    			/// Neuer Client fordert eine Verbindung an ///
    				c = accept(iListen,NULL,0);
    			//	bytes = read(c,buf,sizeof(buf)); // lies den Benutzername des Clients
    				if(bytes != 0)
    				{
    					printf(buf,"Unbekannter Name");
    					pthread_mutex_lock(&g_pClients->m_mutex);
    						g_pClients->ClientAdd(buf,c);
    					pthread_mutex_unlock(&g_pClients->m_mutex);
    				}
    				else
    					printf("Der Client hat den Namen nich Übergeben");
    			}
    			else
    			{
    ... verarbeitung wenn der client etwas sendet
    
    Ich hoffe ihr erkennt das Problem, weil ich sitze jetzt schon mehrere Tage daran und habs bisher noch nicht ans laufen gekriegt...:think:

    ich danke euch

    Jan
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    Kleiner Nachtrag von mir.

    Also es scheint definitiv an der select(..) Funktion zu liegen.
    Da nachdem diese ausgeführt wurde, das übergebene fd_set nicht richtig mit den Werten gefüllt wird.
    Kann es sein, dass ich bei Linux noch irgendwelche Einstellungen machen muss, damit select ordentlich läuft? (Firewall hab ich schon ausgestellt)
    Ich arbeite mit der openSuse Distr. 10.2
    LinuxKernel ist: 2.6.18.2

    Hier hab ich mal ne einfachere Version mit nur einem Client(auch der ist reduziert worden auf ein einfaches Windows konsolenprogramm) und ohne Thread,
    aber auch die funtzt nicht:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/fcntl.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include <unistd.h>
    
    #define PORT 7000
    int main()
    {
    	int iListen;
    	int client = 0;
    	int max = 0;
    	sockaddr_in addr;
    	iListen = socket(PF_INET, SOCK_STREAM,0);
    	addr.sin_addr.s_addr = INADDR_ANY;
    	addr.sin_port = htons(PORT);
    	addr.sin_family = AF_INET;
    	if(bind(iListen,(sockaddr*)&addr,sizeof(addr)) == -1)
    	{
    		perror("bind() failed\n");
    		return 2;
    	}
    	listen(iListen,3);
    	
    
    	fd_set fds;
    	bool bDone =false;
    	char buf[2048];
    	int bytes = 0;
    	printf("Schleife wird betreten\n");
    	while(!bDone)
    	{
    		FD_ZERO(&fds);
    		max = client;
    		if(client > 2)
    			FD_SET(client,&fds);
    		FD_SET(iListen, &fds);
    		if(max < iListen)
    			max = iListen;
    		timeval timeout;
    		timeout.tv_sec = 0;
    		timeout.tv_usec = 0;
    		select(max,&fds,NULL,NULL,&timeout);		
    		if(FD_ISSET(iListen,&fds))
    		{
    			client = accept(iListen,NULL,0);
    			printf("neuer client\n");
    		}
    		if(FD_ISSET(client,&fds))
    		{
    			bytes = read(client,buf,sizeof(buf));
    			if(bytes == 0)
    			{
    				printf("Client hat Verbindung beendet.\n");
    				close(client);
    				client = 0;
    			}
    			else
    			{
    				if(strcmp(buf,"Shutdown")==0)
    				{
    					bDone = true;
    					printf("Client fährt den Server herunter.\n");
    				}	
    				else
    					printf("Client schreibt: %s",buf);
    			}
    		}
    	}
    	close(iListen);
    	if(client > 0);	
    		close(client);
    	return 0;
    }
    
    ich hoffe das diese Info euch irgendwie weiterhilft.

    Danke schonmal

    Jan
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. Sharoz

    Sharoz Mitglied

    Dabei seit:
    10.11.2005
    Beiträge:
    46
    Zustimmungen:
    0
    Wenn ich mich recht entsinne muss dein "max" Wert immer größer sein,
    als der des höchsten, genutzten Filedeskriptors. Also solltest du max
    evtl. noch um 1 erhöhen.

    Außerdem prüfst du deine Sockets NUR auf Lesbarkeit.
    Wenn du welche auf Beschreibbarkeit prüfen willst, musst du
    ein entsprechendes fd_set als drittes Argument bei select()
    angeben.

    Ich gebe zu,ich habe den Code nur überflogen,
    also verzeih mir, wenn ich daneben liege.

    Sharoz
     
  4. #3 Schnabeltasse, 21.02.2007
    Zuletzt bearbeitet: 21.02.2007
    Schnabeltasse

    Schnabeltasse Grünschnabel

    Dabei seit:
    21.02.2007
    Beiträge:
    2
    Zustimmungen:
    0
    Nochmals ein Nachtrag:
    Ich denke das ich die Lösung gefunden habe:
    Nachdem ich select mit dem höchsten Socket +1 mache, dann klappt es soweit.


    Jan
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    @Sharoz: hab gerade deinen Beitrag gelesen, danke dir für die Antwort, damit bin ich beruhig, dass das jetzt wirklich der Grund für die Fehlfunktion war.

    Jan
     
Thema:

probleme mit select()

Die Seite wird geladen...

probleme mit select() - Ähnliche Themen

  1. grub-pc Probleme bei upgrade

    grub-pc Probleme bei upgrade: Hallo, ich habe beim dist-upgrade folgendes Problem: ---------- Nach dieser Operation werden 0 B Plattenplatz zusätzlich benutzt. Trigger für...
  2. Probleme mit YUM

    Probleme mit YUM: Hallo, ich habe CentOs 7 als Dualboot mit Windows 7 auf einen Dell Latitude E5510 installiert. Dies hat soweit auch alles geklappt. Leider habe...
  3. Forscher analysieren Durchsatzprobleme im Linux-Scheduler

    Forscher analysieren Durchsatzprobleme im Linux-Scheduler: Eine Gruppe von Forschern hat Fälle identifiziert, in denen der Scheduler im Linux-Kernel falsche Entscheidungen trifft und die CPUs nicht so gut...
  4. München: LiMux als Sündenbock für IT-Probleme?

    München: LiMux als Sündenbock für IT-Probleme?: Im Münchner Stadtrat soll später in diesem Jahr erneut über den Einsatz von Linux in der Stadtverwaltung diskutiert werden. Die Grünen vermuten,...
  5. BSI-Audit findet keine akuten Probleme in OpenSSL

    BSI-Audit findet keine akuten Probleme in OpenSSL: Das Bundesamt für Sicherheit in der Informationstechnik hat OpenSSL auf seine Sicherheit untersuchen lassen. Die Analyse zeigt vor allem, dass die...