boost::shared_ptr problem mit getpeername...



  • hallo,

    ich hab ein kleines boost problem...
    ich hab einen server auf dem sich mehrere clients verbinden können,
    ich speichere die client sockets in der Connection klasse, ich brauch nun die ip jedes clients,
    weil ich die ip dem file_transfer_receiver senden muss, wenn 2 clients einen P2P file transfer aufbauen wollen...
    die getpeerbrauch den socket für die ip...
    was mach ich da falsch?

    danke im vorhinein + lg

    ServerSocket klasse ist von Socket Klasse abgeleitet:
    ----------------------------------------------------
    std::auto_ptr<Socket> accept() const
    {
    	assert(isValid());
    
             SOCKET socket = ::accept(socket_, NULL, NULL);
    
    	if(socket == INVALID_SOCKET)
    	{
    		THROW_SOCKET_EXCEPTION("::accept failed!");
    	}
    
    	return std::auto_ptr<Socket>(new Socket(socket));
    }
    
    Connection klasse:
    ------------------ 
    class Connection
    {
    private:
    	boost::shared_ptr<Socket> spSocket_;
    	std::string ip;
    public:
    	Connection(std::auto_ptr<Socket>& spSocket)
    		: spSocket_(spSocket)
    	{
    		sockaddr_in saClientAddr;
    		int iClientAddrSize;
    		iClientAddrSize = sizeof(saClientAddr);
    		memset((char *)&saClientAddr, 0, iClientAddrSize);
    		::getpeername(spSocket.get(), (struct sockaddr*)&saClientAddr, &iClientAddrSize);
                    ip = saClientAddr;   // <--- pseudo
    	}
    };
    
    Server klasse:
    -------------------
    
    // Client Instanz in vector einfuegen
    Connection connection(m_serverSocket.accept());
    m_clients.push_back(connection);
    
    error:
    Server.h(52) : error C2664: 'getpeername' : cannot convert parameter 1 from 'Network::Socket *' to 'SOCKET'
            This conversion requires a reinterpret_cast, a C-style cast or function-style cast
    


  • edit:
    ich speichere die objekte von connection im m_client vector...
    die getpeer braucht den socket für die ip...

    lg



  • hi,
    ich hatte zuerst zuerst einen denkfehler bei getpeername...der erste Param musste ja ein SOCKET sein...

    ok ich hab das nun etwas geändert...es müsste es ausschauen...
    aber ich habe bei aufruf des konstr von der Connection Klasse noch einen error?
    ich hab debugged und rausgefunden es lieg an der zuweisung:

    ip(spSocket->getIp())
    

    was kann da sein? bekomme: first-chance exception at 0x00440b36 in Server.exe: 0xC0000005: Access violation reading location 0x00000014.

    ps.: im konstr der klasse Socket steht die ip schon richtig im string!

    danke mal im vorhinein...
    ciao + n8

    Socket Klasse:
    -----------------
    class Socket
    {
    private:
    	std::string ip;	
    	Socket(const Socket&);
    	Socket& operator=(const Socket&);
    
    public:
    	std::string &getIp()
    	{
    		return ip;
    	}
    
    	Socket(SOCKET socket)
    		: socket_(socket)
    	{
    		assert(isValid());
    	}
    	Socket(SOCKET socket, std::string set_ip)
    		: socket_(socket), ip(set_ip)
    	{
    		assert(isValid());
    	}
    
    	Socket()
    	{	
    		socket_ = ::socket(AF_INET, SOCK_STREAM, 0);
    
    		if(!isValid())
    		{
    			THROW_SOCKET_EXCEPTION("::socket failed!");
    		}
    	}
    .............
    .............
    };
    
    ServerSocket Klasse:
    ------------------------
    class ServerSocket : public Socket
    {
    public:
    	ServerSocket(unsigned short port)
    	{	
    		std::cout << "ServerSocket erstellt an Port: " << port << std::endl;
    
    		if(!isValid())
    		{
    			THROW_SOCKET_EXCEPTION("::socket failed!");
    		}
    
    		bind(port);
    	}
    
    	void bind(unsigned short port) const
    	{
    		assert(isValid());
    
    		sockaddr_in socketAddress = {0};
    		socketAddress.sin_family = AF_INET;
    		socketAddress.sin_addr.s_addr = ADDR_ANY;
    		socketAddress.sin_port = htons(port);
    
    		int bindResult = ::bind(socket_,
    					reinterpret_cast<sockaddr*>(&socketAddress),
    					sizeof(socketAddress));
    
    		if(bindResult == SOCKET_ERROR)
    		{
    			THROW_SOCKET_EXCEPTION("::bind failed!");
    		}
    
    		listen();
    	}
    
    	std::auto_ptr<Socket> accept() const
            {
    		assert(isValid());
    
    		SOCKET socket = ::accept(socket_, NULL, NULL);
    
    		sockaddr_in client_addr = {0};
    		int addrlen;
    		addrlen = sizeof(client_addr);
    		::getpeername(socket, (struct sockaddr*)&client_addr, &addrlen);
    
    		std::stringstream ip;
    		ip << inet_ntoa(client_addr.sin_addr);
    
    		if(socket == INVALID_SOCKET)
    		{
    			THROW_SOCKET_EXCEPTION("::accept failed!");
    		}
    
    		return std::auto_ptr<Socket>(new Socket(socket, ip.str()));
            }
    .........
    ........
    };
    
    class Connection
    {
    private:
    	boost::shared_ptr<Socket> spSocket_;
    	std::string userid;
    	std::string nickname;
    	std::string password;
    	std::string ip;
    public:
    	Connection(std::auto_ptr<Socket>& spSocket)
    		: spSocket_(spSocket)
    		, ip(spSocket->getIp()) // fehler ????????????????
    	{
             }
    ..........
    ..........
    };
    
    Server Klasse:
    --------------
    
    wenn ein neuer client hinzukommt:
    // Client Instanz in vector einfuegen
    Connection connection(m_serverSocket.accept());
    m_clients.push_back(connection);
    };
    


  • cplusplus. schrieb:

    ich hab debugged und rausgefunden es lieg an der zuweisung:

    ip(spSocket->getIp())
    

    was kann da sein?

    Du benutzt da denselben auto_ptr, aus dem du direkt darüber den shard_ptr konstruiert hast. Es würde mich wundern, wenn der noch auf ein Objekt zeigte.
    Wie wärs damit?

    ip(spSocket_->getIp())
    

    Oder du änderst die Reihenfolge der Deklarationen der Member, so dass ip vor spSocket_ initialisiert wird.



  • Warum schmeißt du nicht gleich den auto_ptr raus (die Leute glauben mir nicht, aber der ist wirklich böse) und verwendest immer schön deinen shared_ptr?



  • MFK schrieb:

    cplusplus. schrieb:

    ich hab debugged und rausgefunden es lieg an der zuweisung:

    ip(spSocket->getIp())
    

    was kann da sein?

    Du benutzt da denselben auto_ptr, aus dem du direkt darüber den shard_ptr konstruiert hast. Es würde mich wundern, wenn der noch auf ein Objekt zeigte.
    Wie wärs damit?

    ip(spSocket_->getIp())
    

    Oder du änderst die Reihenfolge der Deklarationen der Member, so dass ip vor spSocket_ initialisiert wird.

    hallo,
    so funktioniert es:

    Connection(std::auto_ptr<Socket>& spSocket)
    		: spSocket_(spSocket)
    		, ip(spSocket_->getIp())
    	{
    	}
    

    danke 😃

    möglichkeit2:
    wenn ich die reihenfolge der deklaration ändere, funktioniert es nicht...warum?
    also das wäre dann ja so:

    Connection(std::auto_ptr<Socket>& spSocket)
    	       : ip(spSocket->getIp()) // fehler	
                    , spSocket_(spSocket)
    	{
    	}
    

    lg + danke



  • cplusplus. schrieb:

    wenn ich die reihenfolge der deklaration ändere, funktioniert es nicht...warum?
    also das wäre dann ja so:

    Connection(std::auto_ptr<Socket>& spSocket)
    	       : ip(spSocket->getIp()) // fehler	
                    , spSocket_(spSocket)
    	{
    	}
    

    Du hast nicht die Reihenfolge der Deklaration geändert, sondern die Reihenfolge in der Initialisierungsliste. Das bewirkt gar nichts.
    Die Member werden in der Reihenfolge initialisiert, in der sie in der Klassendeklaration stehen.


Anmelden zum Antworten