首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >持久ASIO连接

持久ASIO连接
EN

Stack Overflow用户
提问于 2013-04-17 21:30:14
回答 1查看 2K关注 0票数 1

我在一个项目中工作,我需要能够使用几个持久化,以在很长一段时间内与不同的服务器交谈。这台服务器将有相当高的吞吐量。我想不出一种正确设置持久连接的方法。我能想到的最好的方法就是创建一个持久连接类。理想情况下,我会一次连接到服务器,并在信息进入我时执行async_writes。并在信息传回给我的时候阅读它。我不认为我的类结构是正确的。

以下是我现在构建的内容:

代码语言:javascript
复制
persistent_connection::persistent_connection(std::string ip, std::string port):
    io_service_(), socket_(io_service_), strand_(io_service_), is_setup_(false), outbox_()
{
    boost::asio::ip::tcp::resolver resolver(io_service_);
    boost::asio::ip::tcp::resolver::query query(ip,port);
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
    boost::asio::ip::tcp::endpoint endpoint = *iterator;
    socket_.async_connect(endpoint, boost::bind(&persistent_connection::handler_connect, this, boost::asio::placeholders::error, iterator));
    io_service_.poll();
}

void persistent_connection::handler_connect(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
    if(ec)
    {
        std::cout << "Couldn't connect" << ec << std::endl;
        return;
    }
    else
    {
        boost::asio::socket_base::keep_alive option(true);
        socket_.set_option(option);
        boost::asio::async_read_until(socket_, buf_ ,"\r\n\r\n", boost::bind(&persistent_connection::handle_read_headers, this, boost::asio::placeholders::error));
    }
}

void persistent_connection::write(const std::string &message)
{
    write_impl(message);
    //strand_.post(boost::bind(&persistent_connection::write_impl, this, message));
}

void persistent_connection::write_impl(const std::string &message)
{
    outbox_.push_back(message);
    if(outbox_.size() > 1)
    {
        return;
    }
    this->write_to_socket();
}

void persistent_connection::write_to_socket()
{
    std::string message = "GET /"+ outbox_[0] +" HTTP/1.0\r\n";
    message += "Host: 10.1.10.120\r\n";
    message += "Accept: */*\r\n";
    boost::asio::async_write(socket_, boost::asio::buffer(message.c_str(), message.size()), strand_.wrap(
                             boost::bind(&persistent_connection::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));

}

void persistent_connection::handle_write(const boost::system::error_code& ec, std::size_t bytes_transfered)
{
    outbox_.pop_front();
    if(ec)
    {
        std::cout << "Send error" << boost::system::system_error(ec).what() << std::endl;
    }
    if(!outbox_.empty())
    {
        this->write_to_socket();
    }
    boost::asio::async_read_until(socket_, buf_ ,"\r\n\r\n",boost::bind(&persistent_connection::handle_read_headers, this, boost::asio::placeholders::error));
}

我将从这里发送的第一条消息似乎发送得很好,服务器得到了它,并用有效的响应进行了响应。不幸的是,我看到了两个问题:

1)在执行async_write命令后,我的handle_write从未被调用过,我不知道为什么。2)程序从不读取响应,我猜这与#1有关,因为直到该函数发生时才会调用asyn_read_until。3)我还想知道是否有人能告诉我为什么我注释掉的strand_.post调用不能工作。

我猜这大部分都是由于我不知道如何使用我的io_service,所以如果有人能给我任何指针,我将非常感激。如果你需要更多的信息,我很乐意提供更多。

谢谢

编辑调用以编写:

代码语言:javascript
复制
int main()
{
    persistent_connection p("10.1.10.220", "80");
    p.write("100");
    p.write("200");
    barrier b(1,30000); //Timed mutex, waits for 300 seconds.
    b.wait();
}

代码语言:javascript
复制
void persistent_connection::handle_read_headers(const boost::system::error_code &ec)
{
    std::istream is(&buf_);
    std::string read_stuff;
    std::getline(is,read_stuff);
    std::cout << read_stuff << std::endl;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-17 23:48:12

所描述的行为是io_service_的事件循环不再被处理的结果。

构造函数调用io_service::poll(),它将运行准备运行的处理程序,并且不会阻塞等待工作完成,其中as io_service::run()将阻塞,直到所有工作完成。因此,在轮询时,如果连接的另一端没有写入任何数据,则可能没有处理程序准备好运行,并且将从poll()返回执行。

关于线程,如果每个连接都有自己的线程,并且通信是半双工协议,比如HTTP,那么如果同步编写应用程序代码可能会更简单。另一方面,如果每个连接都有自己的线程,但是代码是异步编写的,那么可以考虑处理从事件循环中抛出的异常。这可能值得一读Boost.ASIO的effect of exceptions thrown from handlers

此外,persistent_connection::write_to_socket()还引入了未定义的行为。在调用boost::asio::async_write()时,文档记录了调用者保留对缓冲区的所有权,并且必须保证缓冲区在调用处理程序之前保持有效。在这种情况下,message缓冲区是一个自动变量,它的生命周期可能会在persistent_connection::handle_write处理程序被调用之前结束。一种解决方案是更改message的生命周期,使其成为成员变量,从而与persistent_connection的生命周期相匹配。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16061420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档