Почему эта простая программа Boost :: asio не работает должным образом? - PullRequest
1 голос
/ 15 декабря 2009

Я написал это:

#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;
}

Затем я пошел на терминал и написал telnet localhost 1033. Telnet говорит, что я подключен, но обработчик не вызывается (gdb не достигает точки останова, а coutS не действуют). Если я убью программу, телнет скажет, что соединение было закрыто. Кажется, соединение установлено, но почему не вызывается обработчик?

EDIT:

странно работает, если в start () я поставил ioservice.run () после startAccept (). Теперь мне интересно, почему это работает ... на самом деле позже я снова вызываю start accept, и он все еще работает, и это после вызова ioservice.run () ....

1 Ответ

5 голосов
/ 15 декабря 2009

Из документов asio :

Функциональные блоки run () до тех пор, пока не завершится вся работа и не останется больше обработчиков для отправки, или пока служба io_service не будет остановлена.

когда run () вызывается до startAccept (), он немедленно возвращается, так как ему пока нечего делать. Затем вызывается startAccept (), который переводит сокет в режим принятия (поэтому, когда вы подключаетесь к серверу через telnet, его принимает сетевая подсистема), но run () не вызывается после, поэтому ваш обработчик принятия никогда не вызывается. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...