为什么 boost::asio 似乎什么也没做

发布于 2024-09-07 23:37:16 字数 3389 浏览 1 评论 0原文

我正在尝试以非常基本的方式实现 irc 协议。我的第一次尝试是使用 boost::asio 并连接到服务器并读取 motd。据我所知,当每个客户端连接时,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 地址,然后程序不会终止。

我需要做什么才能得到我的缩进行为?

I'm trying to implement the irc protocol in a very basic manner. My first attempt is to use boost::asio and connect to a server and read the motd. AFAIK the motd is sent to every client when they connect. I have made the following test program and it seems to not do anything. It's not a very good piece of code but this is all I have after several frustrating hours.

#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(¤tData);
         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;

}

The program attempts to connect to irc.efnet.org and read until a space is sent and then spits that data out to the terminal. However I run this and all that is printed is the ip address of what I connected to and then the program does not terminate.

What do I need to do to get my indented behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

西瓜 2024-09-14 23:37:16

如果您正在进行异步调用,则必须向 io_service 发送请求。在您的情况下,在 "x.connect();" 之后,您应该调用 "ios.run();"

请记住,如果您在之后没有发表任何进一步的帖子异步回调返回,运行将退出/返回。

顺便说一句, "ios.dispatch(boost::bind(onM, data));" 中的 onM 意味着 onMe 吗?

If you're making asychronous calls, you have to post requests to the io_service. In your case after the "x.connect();" you should call "ios.run();"

Just remember if you don't make any further posts after the async callback returns, run will exit/return.

btw in "ios.dispatch(boost::bind(onM, data));" is onM meant to be onMe ?

一场春暖 2024-09-14 23:37:16

您正在混合异步(io_service::postasync_read_until)和同步(ip::tcp::socket::connectip::tcp::endpoint::resolve)操作。这可行,但我真的不建议这种方法。坚持异步操作,使用 ip::tcp::socket::async_connect 而不是 ip::tcp::socket::connectip::tcp ::socket::async_resolve 而不是 ip::tcp::socket::resolve。您需要调用 io_service::run 或等效函数,这就是为什么您的代码在 connect 之后不执行任何操作。 Boost.Asio 文档有 许多例子展示了如何实现这一目标。

You are mixing asynchronous (io_service::post, async_read_until) and synchronous (ip::tcp::socket::connect, ip::tcp::endpoint::resolve) operations. This can work but I really do not suggest this approach. Stick to asynchronous operations, use ip::tcp::socket::async_connect instead of ip::tcp::socket::connect and ip::tcp::socket::async_resolve instead of ip::tcp::socket::resolve. You'll need to invoke io_service::run or equivalent, this is why your code does nothing after the connect. The Boost.Asio documentation has numerous examples showing how to achieve this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文