0

Im using boost asio for implementing TCP sockets. I've followed the chat server example. The first time that I run the socket server it works ok. Im doing it like this:

     void ActiveSocketServer::run() throw (ActiveException){

     initBoost();

     server->startAccept();

     t=new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
    }

    void ActiveSocketServer::initBoost(){

       if (isIpV6){
            endpoint=new tcp::endpoint(tcp::v6(), port);
       }else{
            endpoint=new tcp::endpoint(tcp::v4(), port);
       }
       server=new ActiveSocketServerConnection(io_service,
                    *endpoint,
                    port,
                    id,
                    maxSizePacket,
                    this);

}

After start it, I call stop method, written like this:

 void ActiveSocketServer::stop(){
     io_service.stop();
     if (t){
        t->join();
        delete t;
        t=NULL;
      }

      if (endpoint){
        delete endpoint;
        endpoint=NULL;
      }

      if (server){
         delete server;
         server=NULL;
      }
   }

And after this, the port is not up (netstat doesnt show). Later, I try to call run again and any error is thrown, port is up (I can see with netstat) but any connections are accepted (async_accept is never waking up).

I think that could be something about the io_service, but if make reset in stop method, and error 125 (operation cancelled) is thrown.

Any idea?


Yes, at the same moment that I call startAccept I'm receiving a new connection but with error 125. It is normal? where can I read something about it?

My startAccept:

   void ActiveSocketServerConnection::startAccept(){

       sessionId++;

        newSession=new ActiveSocketServerSession(   io_service_,
                        getPort(),
                        getId(),
                        maxSizePacket,
                        activeSocketServer,
                        sessionId);

        acceptor_.async_accept( newSession->socket(),
                 boost::bind(&ActiveSocketServerConnection::handleAccept, 
                         this, newSession,
                 boost::asio::placeholders::error));
        }

And the handle accept:

   void ActiveSocketServerConnection::handleAccept(ActiveSocketServerSession* newSession,
                                                          const boost::system::error_code& error){
     if (!error){
       newSession->start();

         }else{

    activeSocketServer.onException(error);
}
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
opernas
  • 154
  • 1
  • 10

2 Answers2

1

In the documentation it states that any calls to run (or similar) will return immediately until io_service::reset() is called.

If you plan to call run again, then I don't believe there is any harm in "priming" the io_service like so:

void ActiveSocketServer::stop(){
     io_service.stop();

     // prime to make ready for future run/run_one/poll/poll_one calls
     io_service.reset();
     
     // ...
   }
Chad
  • 18,706
  • 4
  • 46
  • 63
  • If I do this, im getting error code 125 (operation cancelled) in the handle accept... – opernas May 09 '12 at 17:36
  • Assuming your `StartAccept()` function accepts one connection then immediately tries to accept another? Then that is expected, and the handler is being executed from your previous call to `stop()`. – Chad May 09 '12 at 17:38
1

The 125 you get right after the second call to "run" is normal : it's the previous pending handler that was cancelled when you called Stop. AFAIN the only way to get rid of that is destroy and re-create the io_service (see this answer, in your case it might be better to allocate io_service dynamically though)

If your new "async_accept" call still fails, you might wanna reinit the acceptor (close then open/bind/listen) ... since you recreate the endpoint (which I guess you used to construct the acceptor ?)

Community
  • 1
  • 1
code7amza
  • 181
  • 1
  • 8