gpt4 book ai didi

c++ - boost asio有状态服务器设计

转载 作者:可可西里 更新时间:2023-11-01 02:34:04 25 4
gpt4 key购买 nike

我正在 boost::asio 上编写服务器应用程序

  1. 在这里,我实例化了一个拥有 io_service
  2. Server
  3. 服务器由 server.start() 方法启动,该方法调用 Server::accept() 并创建一个新的 Session 甚至在它获得新连接之前
  4. 调用 _acceptor.async_accept 设置回调,调用 Session::handler() 方法进行握手。

现在可以在获得新客户端之前创建套接字了吗?在此代码中, session 在写入 "Hello " 消息后自动销毁,这在 HTTP 的情况下是可以的,但我想进行状态通信。所以 socket 必须 async_wait 在它刚写完这个 "Hallo " 之后才能读取。我也想知道这样的设计好不好?或者它有任何设计缺陷。

这是我的可编译代码

~

class Session: public boost::enable_shared_from_this<Session>, private boost::noncopyable{
private:
size_t _id;
boost::asio::ip::tcp::socket _socket;
public:
typedef boost::shared_ptr<Session> pointer;
static pointer create(boost::asio::io_service& ios){
return pointer(new Session(ios));
}
private:
explicit Session(boost::asio::io_service& ios): _socket(ios){
static size_t counter = 0;
_id = counter++;
std::cout << ">> Session " << id() << " constructing" << std::endl;
}
public:
void handler(const boost::system::error_code &ec){
const std::string message = (boost::format("HTTP/1.1 200 OK\r\nContent-Length: %2%\r\n\r\nHello, %1%!") % id() % (7+boost::lexical_cast<std::string>(id()).length())).str();
if(!ec){
boost::asio::async_write(_socket, boost::asio::buffer(message), boost::bind(&Session::write_handler, this));
}else{
std::cout << ec.message() << std::endl;
}
}
void write_handler(){

}
size_t id() const{
return _id;
}
boost::asio::ip::tcp::socket& socket(){
return _socket;
}
virtual ~Session(){
std::cout << ">> Session " << id() << " destructing" << std::endl;
}
};

class Server: public boost::enable_shared_from_this<Server>, private boost::noncopyable{
private:
boost::asio::io_service _ios;
boost::asio::ip::tcp::acceptor _acceptor;
public:
explicit Server(boost::asio::ip::tcp::endpoint& endpoint):_acceptor(_ios, endpoint){

}
void start(){
accept();
_ios.run();
}
void accept(){
std::cout << "accepting " << std::endl;;
Session::pointer session = Session::create(_ios);
_acceptor.async_accept(session->socket(), boost::bind(&Server::handler, this, session, boost::asio::placeholders::error));
}
void handler(Session::pointer session, const boost::system::error_code &ec){
if(!ec){
session->handler(ec);
}else{
//possible destroy session ? but how to destroy a shared pointer ?
}
accept();
}
};


int main(){
const unsigned int port = 5050;
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);

Server server(endpoint);
server.start();

return 0;
}

最佳答案

整体设计看起来不错,但有一些实现错误:

  • Session::handler():message,底层缓冲区提供async_write() ,可能会在调用 async_write() 之前超出范围。这违反了 API 要求的保证。考虑使 message 成为 Session 的成员变量,或者在成员函数内将其设为 static。这是文档的相关摘录:

    Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called. Here is the relevant excerpt from the documentation:

  • 对于继承自 boost::enable_shared_from_this 的对象,在传递实例句柄时使用 shared_from_this() 而不是 this 指针到 boost::bind。否则,this 指向的对象实例可能会在处理程序运行之前被删除。

此外,为了解决 Server::handler() 中代码注释中的问题,如果发生错误,一旦处理程序返回,Session 将被删除因为它是通过 boost::shared_ptr 管理的。

关于c++ - boost asio有状态服务器设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11021735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com