相关疑难解决方法(0)

shared_from_this导致bad_weak_ptr

我想在asio中保留一个连接客户端列表.我已经调整了文档中的聊天服务器示例(http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/example/cpp03/chat/chat_server.cpp),这里是重要的部分我结束了:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <set>

using boost::asio::ip::tcp;

class tcp_connection;

std::set<boost::shared_ptr<tcp_connection>> clients;

void add_client(boost::shared_ptr<tcp_connection> client)
{
    clients.insert(client);
}

class tcp_connection : public boost::enable_shared_from_this<tcp_connection>
{
public:
    tcp_connection(boost::asio::io_service& io_service) : socket_(io_service)
    {
    }

    tcp::socket socket_;

    void start()
    {
        add_client(shared_from_this());
    }

    tcp::socket& socket()
    {
        return socket_;
    }
};

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service)
        : io_service_(io_service),
        acceptor_(io_service, tcp::endpoint(tcp::v4(), 6767))
    {
        tcp_connection* new_connection = new tcp_connection(io_service_);
        acceptor_.async_accept(new_connection->socket(),
                             boost::bind(&tcp_server::start_accept, this, new_connection,
                                         boost::asio::placeholders::error));
    }

private:
    void start_accept(tcp_connection* …
Run Code Online (Sandbox Code Playgroud)

c++ boost shared-ptr

42
推荐指数
3
解决办法
2万
查看次数

为什么Boost.Asio不支持基于事件的界面?

我试图了解Boost.Asio,意图使用条件变量和Boost.Asio来实现信号系统.

我已经看到其他StackOverflow问题提升asio异步等待条件变量,boost :: asio异步条件boost条件变量问题,但这些问题/答案都没有令人满意地触及我的一个基本问题:是真的吗那和/或是否存在一个根本原因,Boost.Asio不适用于条件变量,或者与条件变量自然吻合?

我的想法是条件变量是使用操作系统级同步对象在内部实现的(例如,Windows上的boost :: thread :: condition_variable使用Windows操作系统信号量).因为,根据我目前的理解,boost :: asio :: io_service旨在封装操作系统级别的同步对象,因此条件变量似乎很自然.

确实,与文件操作和套接字操作不同,在操作系统级别通常从不存在与信号条件相关联的回调函数(我认为 - 我不确定这一点).但是,在Boost.Asio中实现这样的回调处理程序似乎很简单,只需要用户提供一个回调函数,该函数在条件变量发出信号时被调用 - 正如用户必须为其他函数提供完成处理程序例程一样. boost :: asio :: io_service服务.

例如(这只是一个快速思考,而不是一个完整的原型 - 它没有包含足够的参数来处理notify_one()与notify_all(),也没有说明服务如何知道何时退出,并且可能有其他明显的遗漏或缺陷):

void condition_handler_function() {}
boost::asio::io_service service;
boost::mutex mut;
boost::condition_variable cond;

// The following class is **made up by me** - would such a class be a good idea?
boost::asio::io_service::condition_service
             condserv(service, cond, mut, condition_handler_function); 

condserv.async_wait_on_signal();

service.run(); // when condition variable is signaled by notify_one(),
               // …
Run Code Online (Sandbox Code Playgroud)

c++ boost event-handling boost-asio

7
推荐指数
2
解决办法
5367
查看次数

如何设计boost :: asio套接字或其包装的正确释放

我几次尝试使用boost :: asio创建自己的简单异步TCP服务器几年后没有触及它.

我能找到的最新示例列表是:http: //www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html

我在这个示例列表中遇到的问题是(我觉得)它欺骗并且通过使tcp_connection成为shared_ptr来欺骗它,这样它就不用担心每个连接的生命周期管理了.(我认为)他们这样做是为了简洁,因为它是一个小教程,但这个解决方案不是现实世界.

如果您想在计时器或类似的东西上向每个客户端发送消息怎么办?在任何真实世界的非平凡服务器中都需要一组客户端连接.

我担心每个连接的生命周期管理.我认为自然要做的就是在tcp_server中保留一些tcp_connection对象或指向它们的指针.从OnConnect回调添加到该集合并从该集合中删除OnDisconnect.

请注意,OnDisconnect很可能是从实际的Disconnect方法调用的,在发生错误的情况下,该方法将从OnReceive回调或OnSend回调调用.

嗯,这就是问题所在.

考虑一下我们有一个看起来像这样的callstack:

tcp_connection::~tcp_connection
tcp_server::OnDisconnect
tcp_connection::OnDisconnect
tcp_connection::Disconnect
tcp_connection::OnReceive
Run Code Online (Sandbox Code Playgroud)

这会在调用堆栈展开时导致错误,并且我们正在一个已经调用了析构函数的对象中执行代码......我想,对吧?

我想每个做服务器编程的人都会以某种方式遇到这种情况.处理它的策略是什么?

我希望这个解释足够好.如果不让我知道,我将创建自己的源列表,但它将非常大.


编辑:相关

)异步C++代码中的内存管理

IMO不是一个可以接受的答案,依赖于在接收电话上使用shared_ptr作弊,仅此而已,并不是现实世界.如果服务器想要每5分钟对所有客户说"嗨"怎么办?某种集合是必要的.如果你在多个线程上调用io_service.run怎么办?

我也在提升邮件列表:http: //boost.2283326.n4.nabble.com/How-to-design-proper-release-of-a-boost-asio-socket-or-wrapper-thereof- td4693442.html

c++ tcp boost-asio

5
推荐指数
1
解决办法
1096
查看次数

标签 统计

c++ ×3

boost ×2

boost-asio ×2

event-handling ×1

shared-ptr ×1

tcp ×1