Почему boost :: asio ничего не делает - PullRequest
0 голосов
/ 04 июля 2010

Я пытаюсь реализовать протокол irc очень простым способом.Моя первая попытка - использовать boost :: asio, подключиться к серверу и прочитать motd.AFAIK MOTD отправляется каждому клиенту при подключении.Я сделал следующую тестовую программу, и она, кажется, ничего не делает.Это не очень хороший кусок кода, но это все, что у меня есть после нескольких разочаровывающих часов.

#define _WIN32_WINNT 0x0501
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <queue>



class IrcConnection
{
public:
    IrcConnection(const std::string& server, int port, boost::function<void (const std::string&)> onMessage, boost::asio::io_service& io_service): s(server), p(port), onM(onMessage), ios(io_service), socket(io_service)
    {
    }
    void connect() 
    {
        somethingHappened = false;
        //DNS stuff
        boost::asio::ip::tcp::resolver resolver(ios);
        boost::asio::ip::tcp::resolver::query query(s , "0");
        boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query);
        boost::asio::ip::tcp::resolver::iterator end;

        boost::system::error_code error;

        while(iter != end)
        {
            boost::asio::ip::tcp::endpoint endpoint = iter->endpoint();
            endpoint.port(p);
            socket.close();
            socket.connect(endpoint, error);
            iter++;
        }
        if(error)
        {
            std::cout << "ERROR" << std::endl;
            std::cout << error << std::endl;
        }

        std::cout << "Connected to: " << socket.remote_endpoint().address().to_string() << std::endl; 

        //read from the socket until a space is found
        boost::asio::async_read_until(socket, currentData, ' ', boost::bind(&IrcConnection::onReceiveFinished, this, boost::asio::placeholders::error));
    }
    void disconnect() 
    {
        socket.close();
    }
    void send(int priority, const std::string& message) 
    {
    }
bool somethingHappened;

private:
    std::string s;
    int p;
    boost::function<void (const std::string&)> onM;
    boost::asio::io_service& ios;
    boost::asio::ip::tcp::socket socket;
    std::priority_queue<std::string> outQueue;
    boost::asio::streambuf currentData;


    void onReceiveFinished(const boost::system::error_code& error)
    {
        if(error)
        {
            disconnect();
            std::cout << "ERRORRRR" << std::endl;
            std::cout << error << std::endl;
        }

        std::cout << "STUFF IS OCCURING" << std::endl;
        somethingHappened = true;

         std::istream stream(&currentData);
         std::string data;
         std::getline(stream, data);

         boost::asio::async_read_until(socket, currentData, ' ', boost::bind(&IrcConnection::onReceiveFinished, this, boost::asio::placeholders::error));
         ios.dispatch(boost::bind(onM, data));
    }


};


void onMe(const std::string& x)
{
    std::cout << "MESSAGE" << std::endl;
    std::cout << x << std::endl;
}

int main()
{
    boost::asio::io_service ios;
    std::string server = "irc.efnet.org";
    int port = 6667;

    IrcConnection x(server, port, onMe, ios);

    x.connect();

    while(!x.somethingHappened)
    {
        //
    }

    return 0;

}

Программа пытается подключиться к irc.efnet.org и читать до отправки пробела, а затем выплевываетданные в терминал.Однако я запускаю это, и все, что напечатано, это ip-адрес того, к чему я подключился, и затем программа не завершает работу.

Что мне нужно сделать, чтобы получить поведение с отступами?

Ответы [ 2 ]

2 голосов
/ 04 июля 2010

Если вы делаете асинхронные вызовы, вы должны отправлять запросы в io_service. В вашем случае после "x.connect();" вы должны позвонить "ios.run();"

Просто помните, что если вы не сделаете дальнейших постов после возврата асинхронного обратного вызова, run завершится / вернется.

Кстати, в "ios.dispatch(boost::bind(onM, data));" onM должно быть на мне?

0 голосов
/ 04 июля 2010

Вы смешиваете асинхронные (io_service::post, async_read_until) и синхронные (ip::tcp::socket::connect, ip::tcp::endpoint::resolve) операции. Это может сработать, но я действительно не предлагаю такой подход. Придерживайтесь асинхронных операций, используйте ip::tcp::socket::async_connect вместо ip::tcp::socket::connect и ip::tcp::socket::async_resolve вместо ip::tcp::socket::resolve. Вам нужно будет вызвать io_service::run или его эквивалент, поэтому ваш код ничего не делает после connect. Документация Boost.Asio содержит многочисленных примеров , показывающих, как этого добиться.

...