Overview
Features
Download
Documentation
Community
Add-Ons & Services

Problems using own SocketAcceptor Implementation

Please post support and help requests here.

Problems using own SocketAcceptor Implementation

Postby Kreek » 20 Jul 2010, 17:45

Hey Poco Guys!

I implemented my own SocketAcceptor class, but I'm stuck on a compiler error I cannot figure out. The class is defined as follows:

Code: Select all
class Node;
class ClientHandler;

//FIX: compiler error
template <>
ClientHandler* SocketAcceptor<ClientHandler>::createServiceHandler(StreamSocket& socket) {return 0;}
//End of compiler error fix

class ClientSocketAcceptor : public SocketAcceptor<ClientHandler> {
   protected:
      Node* fNode;

      ClientHandler* createServiceHandler(StreamSocket&);
   public:
      ClientSocketAcceptor(ServerSocket&, SocketReactor&, Node*);
};

#endif /* CLIENTSOCKETACCEPTOR_H_ */


When I compile it without the compiler error fix, I get the following error:

Code: Select all
Building node/ClientSocketAcceptor.cpp
external/include/Poco/Net/SocketAcceptor.h: In member function 'ServiceHandler* Poco::Net::SocketAcceptor<ServiceHandler>::createServiceHandler(Poco::Net::StreamSocket&) [with ServiceHandler = ClientHandler]':
external/include/Poco/Net/SocketAcceptor.h:144:   instantiated from 'void Poco::Net::SocketAcceptor<ServiceHandler>::onAccept(Poco::Net::ReadableNotification*) [with ServiceHandler = ClientHandler]'
external/include/Poco/Net/SocketAcceptor.h:123:   instantiated from 'void Poco::Net::SocketAcceptor<ServiceHandler>::registerAcceptor(Poco::Net::SocketReactor&) [with ServiceHandler = ClientHandler]'
external/include/Poco/Net/SocketAcceptor.h:105:   instantiated from 'Poco::Net::SocketAcceptor<ServiceHandler>::SocketAcceptor(Poco::Net::ServerSocket&, Poco::Net::SocketReactor&) [with ServiceHandler = ClientHandler]'
src/node/ClientSocketAcceptor.cpp:10:   instantiated from here
external/include/Poco/Net/SocketAcceptor.h:153: error: no matching function for call to 'ClientHandler::ClientHandler(Poco::Net::StreamSocket&, Poco::Net::SocketReactor&)'
src/node/ClientHandler.h:28: note: candidates are: ClientHandler::ClientHandler(Poco::Net::StreamSocket&, Poco::Net::SocketReactor&, Node*)
src/node/ClientHandler.h:26: note:                 ClientHandler::ClientHandler(const ClientHandler&)
make: *** [bin/node/ClientSocketAcceptor.o] Error 1


I noticed something with the createServiceHandler() method was wrong, so I used the above template definition to fix it. However, then I get the following error:

Code: Select all
In file included from src/node/Node.h:16,
                 from src/runNode.cpp:8:
src/node/ClientSocketAcceptor.h:28: error: specialization of 'ServiceHandler* Poco::Net::SocketAcceptor<ServiceHandler>::createServiceHandler(Poco::Net::StreamSocket&) [with ServiceHandler = ClientHandler]' in different namespace
src/node/ClientSocketAcceptor.h:28: error:   from definition of 'ServiceHandler* Poco::Net::SocketAcceptor<ServiceHandler>::createServiceHandler(Poco::Net::StreamSocket&) [with ServiceHandler = ClientHandler]'
make: *** [bin/runNode.o] Error 1


Placing the template definition in the same namespace Poco::Net gives me duplicate symbol (linker) errors..
Oh Yeah, my ClientHandler class is defined as follows:

Code: Select all
blabla

class Node;

class ClientHandler {
public:
   ClientHandler(StreamSocket&, SocketReactor&, Node*);
   ~ClientHandler();

   void onReadable(const AutoPtr<ReadableNotification>& pNf);
   void onShutdown(const AutoPtr<ShutdownNotification>& pNf);
private:
   StreamSocket fSocket;
   SocketReactor& fReactor;
   Node* fNode;
};


Any ideas on how to fix this? It's a really weird error.. Or shouldn't I use the template definition and do something else?

Thanks..
Last edited by Kreek on 20 Jul 2010, 18:26, edited 1 time in total.
Kreek
 
Posts: 7
Joined: 21 Dec 2009, 18:55

Re: Problems using own SocketAcceptor Implementation

Postby Kreek » 20 Jul 2010, 18:17

The error actually also occurs in the Poco sources (in SocketAcceptor.h):

Image

I have defined my own createServiceHandler() method.. but it won't use it.. that's why I introduced the template..
Kreek
 
Posts: 7
Joined: 21 Dec 2009, 18:55

Re: Problems using own SocketAcceptor Implementation

Postby Kreek » 20 Jul 2010, 21:25

Ok. I Fixed it, but it had nothing to do with the Poco library really.. For those interested:

I added the namespace Poco::Net back to the template declaration, but then it gave me those duplicate symbol linker errors. On the internet, I found this post:

Code: Select all
The problem could be the result of several different things, and no one can tell you specifically without seeing the code. Another possible cause, besides the ones I already mentioned previously, is putting the implementation code in a header file. In that case it will be duplicated in every *.cpp file that uses the header file, thus the duplicate error message(s). The solution is to put the implementation code in one *.cpp file, leaving only the class declaration in the header file.


This gave me the idea of putting the template declaration not in the header file, but in the implementation (.cpp) file of my class. Stupidly enough, it worked!

Thanks anyway for this wonderful forum where I can ask my questions :mrgreen:
Kreek
 
Posts: 7
Joined: 21 Dec 2009, 18:55

Re: Problems using own SocketAcceptor Implementation

Postby flomll » 24 May 2012, 14:13

Kreek wrote:Ok. I Fixed it, but it had nothing to do with the Poco library really.. For those interested:

This gave me the idea of putting the template declaration not in the header file, but in the implementation (.cpp) file of my class. Stupidly enough, it worked!

Thanks anyway for this wonderful forum where I can ask my questions :mrgreen:


Did you split your own MySocketAcceptor class or the Poco::Net::SocketAcceptor calls? I split my own derived MySocketAcceptor calls but the problem also exists. Now I am working on the Poco::NetSocketAcceptor. Can you explain what I have to do? Only split the SocketAcceptor.h template file into .h/.cpp or are there some other things to do?
flomll
 
Posts: 28
Joined: 18 May 2012, 08:58
Location: Austria

Re: Problems using own SocketAcceptor Implementation

Postby flomll » 24 May 2012, 14:55

Now I split the code of the Poco::Net::SocketAcceptor into .h/.cpp file but I get the error:
Code: Select all
src/SocketAcceptor.cpp: In member function ‘virtual void Poco::Net::SocketAcceptor<ServiceHandler>::registerAcceptor(Poco::Net::SocketReactor&)’:
src/SocketAcceptor.cpp:77:11: error: invalid use of incomplete type ‘struct Poco::Net::SocketReactor’
include/Poco/Net/SocketNotification.h:52:7: error: forward declaration of ‘struct Poco::Net::SocketReactor’
src/SocketAcceptor.cpp: In member function ‘virtual void Poco::Net::SocketAcceptor<ServiceHandler>::unregisterAcceptor()’:
src/SocketAcceptor.cpp:91:12: error: invalid use of incomplete type ‘struct Poco::Net::SocketReactor’
include/Poco/Net/SocketNotification.h:52:7: error: forward declaration of ‘struct Poco::Net::SocketReactor’
make[1]: *** [/home/muf/Workspace/externals/poco-1.4.3p1-all/Net/obj/Linux/i686/debug_shared/SocketAcceptor.o] Error 1
make[1]: Leaving directory `/home/muf/Workspace/externals/poco-1.4.3p1-all/Net'
make: *** [Net-libexec] Error 2


This is the .cpp file:
Code: Select all
#include "Poco/Net/SocketAcceptor.h"

namespace Poco {
namespace Net {

template <class ServiceHandler>
SocketAcceptor<ServiceHandler>::SocketAcceptor(ServerSocket& socket):
   _socket(socket),
   _pReactor(0)
   /// Creates an SocketAcceptor, using the given ServerSocket.
{
}

template <class ServiceHandler>
SocketAcceptor<ServiceHandler>::SocketAcceptor(ServerSocket& socket, SocketReactor& reactor):
   _socket(socket),
   _pReactor(0)
   /// Creates an SocketAcceptor, using the given ServerSocket.
   /// The SocketAcceptor registers itself with the given SocketReactor.
{
   registerAcceptor(reactor);
}

template <class ServiceHandler>
SocketAcceptor<ServiceHandler>::~SocketAcceptor()
   /// Destroys the SocketAcceptor.
{
   unregisterAcceptor();
}

template <class ServiceHandler>
void SocketAcceptor<ServiceHandler>::registerAcceptor(SocketReactor& reactor)
   /// Registers the SocketAcceptor with a SocketReactor.
   ///
   /// A subclass can override this and, for example, also register
   /// an event handler for a timeout event.
   ///
   /// The overriding method must call the baseclass implementation first.
{
   _pReactor = &reactor;
   _pReactor->addEventHandler(_socket, Poco::Observer<SocketAcceptor, ReadableNotification>(*this, &SocketAcceptor::onAccept));
}

template <class ServiceHandler>
void SocketAcceptor<ServiceHandler>::unregisterAcceptor()
   /// Unregisters the SocketAcceptor.
   ///
   /// A subclass can override this and, for example, also unregister
   /// its event handler for a timeout event.
   ///
   /// The overriding method must call the baseclass implementation first.
{
   if (_pReactor)
   {
      _pReactor->removeEventHandler(_socket, Poco::Observer<SocketAcceptor, ReadableNotification>(*this, &SocketAcceptor::onAccept));
   }
}

template <class ServiceHandler>
void SocketAcceptor<ServiceHandler>::onAccept(ReadableNotification* pNotification)
{
   pNotification->release();
   StreamSocket sock = _socket.acceptConnection();
   createServiceHandler(sock);
}


template <class ServiceHandler>
ServiceHandler* SocketAcceptor<ServiceHandler>::createServiceHandler(StreamSocket& socket)
   /// Create and initialize a new ServiceHandler instance.
   ///
   /// Subclasses can override this method.
{
   return new ServiceHandler(socket, *_pReactor);
}

template <class ServiceHandler>
SocketReactor* SocketAcceptor<ServiceHandler>::reactor()
   /// Returns a pointer to the SocketReactor where
   /// this SocketAcceptor is registered.
   ///
   /// The pointer may be null.
{
   return _pReactor;
}

template <class ServiceHandler>
Socket& SocketAcceptor<ServiceHandler>::socket()
   /// Returns a reference to the SocketAcceptor's socket.
{
   return _socket;
}


} } // namespace Poco::Net


Can anyone help me?
flomll
 
Posts: 28
Joined: 18 May 2012, 08:58
Location: Austria

Re: Problems using own SocketAcceptor Implementation

Postby rakesh » 24 May 2012, 16:33

Looks like you need to include SocketAcceptor, which is what the incomplete struct message implies.
rakesh
 
Posts: 78
Joined: 13 Apr 2011, 17:43
Location: Chicago


Return to Support

Who is online

Users browsing this forum: No registered users and 2 guests

cron