Suche: logischer Fehler



  • Hallo!

    Ich will sowas wie ein echo-server machen.
    Also einfach ein Programm welches auf einem Port horcht und Verbindungen annimmt. Die Zeichenkette, die ankommt, soll wieder zurückgegeben werden.
    Kompilieren tut es prima nur nimmt er keine Verbindungen an!
    Das ist auch mein Problem...

    Hier der Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <iostream>
    #include <fstream>
    
    #define PORT_NR 7000
    #define MAX_CLIENTS 10
    
    int main()
    {
    	int i, s, c, clients[MAX_CLIENTS];
    	struct sockaddr_in addr;
    	socklen_t addr_len;
    	addr_len = sizeof(addr);
    	fd_set fdSet;
    	long rc;
    	char buf[256];
    	char buf2[300];
    
    	s = socket(PF_INET, SOCK_STREAM, 0);
    	if (s == -1)
    	{
    		printf("Fehler: Der Socket konnte nicht erstellt werden, Fehlercode: ");
    		return 1;
    	}else
    	{
    		cout << "Socket erstellt!" << endl;
    	}
    
    	memset(&addr,0,sizeof(sockaddr_in));
    	addr.sin_addr.s_addr = INADDR_ANY;
    	addr.sin_port = htons(PORT_NR);
    	addr.sin_family = AF_INET;
    
    	if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
    	{
    		perror("Fehler: bind, fehler code: ");
    		return 2;
    	}else
    	{
    		cout << "Socket an Port " << PORT_NR << " gebunden!" << endl;
    	}
    
    	if (listen(s, 3) == -1)
    	{
    		perror("listen() failed");
    		return 3;
    	}else
    	{
    		cout << "Socket ist im listen Modus...." << endl;
    	}
    
    	// alle Clients auf keine Verbindung setzen
    	for(i=0;i<MAX_CLIENTS;i++)
    	{
    		clients[i]=-1;
    	}
    
    	while(true)
    	{
    		FD_ZERO(&fdSet); // Inhalt leeren
    		FD_SET(s,&fdSet); // Den Socket der Verbindung annehmen
    
    		// alle gueltigen Client Sockets hinzufuegen (nur die die nicht -1 sind)
    		for(i=0;i<MAX_CLIENTS;i++)
    		{
    			cout << clients[i] << endl;
    			if(clients[i]!=-1)
    			{
    				FD_SET(clients[i],&fdSet);
    			}
    		}
    		if(select(0,&fdSet,NULL,NULL,NULL)==-1)
    		{
    			cout << "Fehler: select, fehler code:" << endl;
    			return 1;
    		}
    		// s ist im fd_set? => Verbindung annehmen (sofern es Platz hat)
    		if(FD_ISSET(s,&fdSet))
    		{
    			// einen freien Platz fuer den Client suchen
    			for(i=0;i<MAX_CLIENTS;i++)
    			{
    				if(clients[i]==-1)
    				{
    					clients[i]=accept(s,(struct sockaddr*)&addr, &addr_len);
    					cout << "Neuen Client angenommen (" << i << ") mit IP:" << inet_ntoa(addr.sin_addr)  << endl;
    					// printf("Client from %s\n", inet_ntoa(addr.sin_addr));
    					break;
    				}
    			}
    		}
    		// pruefen welcher Client sockets im fd_set sind
    		for(i=0;i<MAX_CLIENTS;i++)
    		{
    			if(clients[i]==-1)
    			{
    				continue; // ungueltiger socket, dh kein verbundener Client an dieser Position im Array
    			}
    			if(FD_ISSET(clients[i],&fdSet))
    			{
    				if(recv(clients[i],buf,256,0)==-1) // pruefen ob die Verbindung geschlossen wurde oder ein Fehler auftrat
    				{
    					cout << "Client " << i << " hat die Verbindung geschlossen!" << endl;
    					close(clients[i]); // Socket schliessen
    					clients[i]=-1; // Platz wieder freigeben
    				}else
    				{
    					buf[rc]='\0';
    					// Daten ausgeben und eine Antwort senden
    					cout << "Client " << i << " hat folgendes gesandt: " << buf << endl;
    					// Antwort senden
    					sprintf(buf2,"Du mich auch %s\n",buf);
    					send(clients[i],buf2,(int)strlen(buf2),0);
    				}
    			}
    		}
    	}
    	close(s);
    	return 0;
    }
    

    Ich hoffe, dass jemand mir helfen kann! 🙂



  • Die Reihenfolge ist falsch!
    Du machst zuerst ein select() und danach erst ein accept().
    Wie sollen den Daten "anliegen", wenn du die Verbindung noch gar nicht angenommen (accept()) hast?

    Mehr dazu findest du auch in meinem Buch "C und Linux" 😉

    Martin


Anmelden zum Antworten