tags:

views:

184

answers:

1

I wrote this:

#include <vector>
#include <iostream>
#include <sstream>
#include <boost/asio.hpp>
#include <tr1/memory>
#include <boost/bind.hpp>
#include <stdint.h>

    using namespace boost::asio;
    using namespace boost::asio::ip;

class tcpServer{
public:

    class connection{

     tcp::socket socketConnection;

     enum {CONNECTED, CLOSED, CREATED}STATUS;

    public:

     uint32_t addr;
     uint16_t port;

     connection(boost::asio::io_service &ioServ): socketConnection(ioServ){
      STATUS = CREATED;
     }

     void setConnected(bool is) {
      if (is) {
       STATUS = CONNECTED;
       port = socketConnection.remote_endpoint().port();
       addr
         = socketConnection.remote_endpoint().address().to_v4().to_ulong();
       std::cout << "Connected to "
         << socketConnection.remote_endpoint().address().to_v4().to_string()
         << " : " << socketConnection.remote_endpoint().port()
         << "\n";
      }
     }

     tcp::socket& getSocket(){
      return socketConnection;
     }
    };

    typedef std::tr1::shared_ptr<tcpServer::connection> CONNSHPTR;

private:
    boost::asio::io_service io_service;
    tcp::acceptor tcpAcceptor;
    int localPort;

    void accept(CONNSHPTR connection, const boost::system::error_code& error){
     connection->setConnected(true);
     std::cout.flush();
    }

    void startAccept(){
     CONNSHPTR newConn(new connection(tcpAcceptor.io_service()));

     tcpAcceptor.async_accept(newConn->getSocket(), boost::bind(
         &tcpServer::accept, this, newConn,
         boost::asio::placeholders::error));
    }

public:



    tcpServer(int localPort) :
     io_service(), tcpAcceptor(io_service, tcp::endpoint(tcp::v4(),
       localPort)) {
     this->localPort = localPort;

    }

    void start(){
     io_service.run();
     startAccept();
    }
};

int main(int argc, char** argv) {
try{
    tcpServer tp(1033);
    tp.start();
}catch(std::exception &e){
    std::cout << e.what();
}
    sleep(5000);
    return 0;
}

Then I went on the terminal and I wrote telnet localhost 1033. Telnet says I'm connected but the handler doesn't get called (gdb doesn't hit breakpoint and the coutS have no effect). If I kill the program telnet will say that the connection has been closed. So seems the connection is estabilished, but why the handler doesn't get called?

EDIT:

weirdly it works if in start() I put ioservice.run() after the startAccept(). Now I wonder why this works... in fact later I call start accept again and it still works, and it is after the ioservice.run() call....

+4  A: 

From the asio docs:

The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.

when run() is called before startAccept(), it returns immediately, as it has nothing to do yet. startAccept() is then called, which puts the socket in accept mode (so, when you telnet on your server, the networking subsystem accepts it), but run() is not called after, so your accept handler is never called.

Éric Malenfant
god I gotta use another thread...
gotch4
Not necessarily. You could simply call run() after, once all setup is done or, if you want to interleave other work, schedule timers or callpoll() or run_one() on the io_service
Éric Malenfant