Problem mit accept()



  • Hallo liebes Forum,

    ich möchte einen Server bauen, der in einem extra Thread die ganze Zeit Verbindungen annimmt.
    Leider lehnt mein Server alle eingehenden Verbindugen ab.

    main.cpp

    #include "libserv.h"
    
    using namespace network;
    
    int main()
    {
    	Server test(1330);
    	test.setJoinFlag(true);
    	test.startListening();
    	return 0;
    }
    

    libserv.h

    #ifndef _LIBSERV_H
     #define _LIBSERV_H
     #include <thread>
     #include <unistd.h>
     #include <sys/socket.h>
     #include <netinet/in.h>
     #include <sys/types.h>
     #include <arpa/inet.h>
    
    	namespace network
    	{
    		struct nsocket
    		{
    			int sock; //Socketdateidiskriptor
    			struct sockaddr_in sock_info; //Struktur mit Socketinformationen
    			std::string sock_recv_data; //Empfangene Daten
    		};
    
    		class Server
    		{
    			protected:
    				struct nsocket server_info; //Server-Informationen in der Struktur nsocket
    				bool flag; //Variable die Entscheidet ob neue Verbindungen angenommen werden oder nicht
    				bool joinflag; //Variable die Entscheidet ob der Server blockt oder nicht
    				std::thread server_thread; //Serverthread der Verbindungen annimmt
    				void listening(void); //asynchrone Methode zum Annehmen von Verbindungen
    			public:
    				Server(unsigned short sock_port); //Konstruktor mit Parameter für Port
    				~Server(void){}; //dtor
    				void startListening(void); //startet asynchrone Methode listening | blockt wenn joinflag=true 
    				void setJoinFlag(bool jfl); //Setzt das joinflag
    				void stopServer(void); //Setzt das flag
    		};
    	}
    

    libsrv.cpp

    #include "libserv.h"
    #include <iostream>
    
    using namespace network;
    
    Server::Server(unsigned short sock_port):max_connection(0),flag(true),joinflag(true)
    {
    	this->server_info.sock_info.sin_family = AF_INET;
    	this->server_info.sock_info.sin_addr.s_addr = htonl(INADDR_ANY);
    	this->server_info.sock_info.sin_port = sock_port;
    }
    
    void Server::setJoinFlag(bool jfl)
    {
    	this->joinflag = jfl;
    }
    
    void Server::startListening(void)
    {
    
    	if(this->joinflag == true)  //startet Thread blockend
    	{
    		this->server_thread = std::thread(&Server::listening,this);
    		this->server_thread.join();
    	}
    	else //startet Thread nicht-blockend
    	{
    		this->server_thread = std::thread(&Server::listening,this);
    		this->server_thread.detach();
    	}
    }
    
    void Server::listening(void)
    {
    	int val, len;
    	struct nsocket client_info;
    	this->server_info.sock = socket(AF_INET,SOCK_STREAM,0); //server socket wird erstellt
    	if(this->server_info.sock == -1)
    	{
    		std::cout << "SOCKET_EXCEPTION: Unable to create socket." << std::endl;
    		return 1;
    	}
    	len = sizeof(this->server_info.sock_info);
    	val = bind(this->server_info.sock, (struct sockaddr*)&this->server_info.sock_info, len); //server socket wird gebunden
    	if(val == -1)
    	{
    		std::cout << "SOCKET_BIND_EXCEPTION: Unable to bind socket." << std::endl;
    		return 1;
    	}
    	listen(this->server_info.sock,5); //server socket horcht
    	val = 0;
    	while(this->flag) //solange das flag wahr ist werden eingehende Verbindungen angenommen und der read  thread wird gestartet
    						//, falls eine Verbindung getrennt wird wird die nächste eingehende an seine Stelle treten
    	{
    		client_info.sock = accept(this->server_info.sock,(struct sockaddr*)&client_info.sock_info, (socklen_t*)&len);
    	}
    
    }
    
    void Server::stopServer(void)
    {
    	this->flag = true ;
    }
    

    Ich hab mit "nc 127.0.0.1 1330 -v" überprüft ob er die Verbindung annimmt, aber leider weist er sie ab.

    Hat es vlt was damit zu tun, dass ich das in dem Thread mache, ich weiß nicht weiter.



  • Das kompiliert bei mir noch nicht mal.
    Ist das wirklich der Code, den Du für Deinen Test benutzt?



  • while(this->flag)
    

    Welchen Wert hat flag? Du rufst accept nicht auf? Was ist der Rueckgabewert von accept? Wie sieht es mit errno aus_

    void Server::stopServer(void) 
    { 
         this->flag = true ; 
    }
    

    Vielleicht sind bessere Namen nicht mehr zeitgemaess.



  • Der Code ist abgespeckt, der Volle ist viel zu groß. 😕

    flag wird mit Konstruktor auf true gesetzt



  • ich seh grad das bei stopServer() das flag auf true gesetzt wird, das ist ein fehler der zwar jetzt nix damit zutun hat aber trotzdem gut zu wissen 🙂

    Wer sich den kompletten Code ansehen will http://codeviewer.org/view/code:38c2



  • Ah: ip(7) bringt glaube ich den Durchbruch, Port und Adresse sind in network byte order.

    Server::Server(unsigned short sock_port) :
      max_connection(0), flag(true), joinflag(true)
    {
    	this->server_info.sock_info.sin_family = AF_INET;
    	this->server_info.sock_info.sin_addr.s_addr = htonl(INADDR_ANY);
    	this->server_info.sock_info.sin_port = htons(sock_port);
    }
    


  • Na müssen Sie doch oder etwa nicht?

    Ich seh es der Port ist nicht im Networkbyteorder ich versuchs mal, allerdings erst wieder Montag 😃 Der Code liegt auf Arbeit



  • Hab es getestet, das war der Fehler danke 👍


Log in to reply