asio编写异步时间服务器(C++asio网络库相关)

以下关于asio异步服务器完整代码例子:

有以下几点是需要注意的地方:
1、enable_shared_from_this:表示在类方法里把自己包装成智能指针,一个要用于延长类的生命周期防止调用回调的时候类失效
2、using pointer = boost::shared_ptr 等价于 typedef boost::shared_ptr pointer,C++11后推荐用前一种方法定义
3、以下两种return生成智能指针的写法,第一种return内存分配了两次,第二种有些地方是不能用的,如构造函数定义成了私有类型,无特殊情况推荐第二种方式

 static pointer create(boost::asio::io_service &io_service) {
		// std::make_shared
    return pointer(new tcp_connection(io_service));
	return std::make_shared<tcp_connection>(io_service);
  }

3、通过async_write写入数据,handle_write回调函数,用shard_from_this防止类失效
4、在lambda函数中调用自身指针可以用move提高效率,也可以直接用值的拷贝传入值
5、handle_accept:连接成功后的回调
6、start_accept()连接新的客户端

#include 

#include 
#include 
#include 
#include 

#include 

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

std::string make_daytime_string() {
  using namespace std; // For time_t, time and ctime;
  auto now = time(nullptr);
  return ctime(&now);
}

class tcp_connection : public std::enable_shared_from_this<tcp_connection> {
public:
  using pointer = std::shared_ptr<tcp_connection>;

  static pointer create(boost::asio::io_service &io_service) {
		// std::make_shared
    return pointer(new tcp_connection(io_service));
		//return std::make_shared(io_service);
  }

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

  void start() {
    message_ = make_daytime_string();

    auto self = shared_from_this();
    boost::asio::async_write(
        socket_, boost::asio::buffer(message_),
        [self = std::move(self)](auto error, auto bytes_transferred) {
          self->handle_write(error, bytes_transferred);
        });
//    boost::asio::async_write(
//        socket_, boost::asio::buffer(message_),
//        boost::bind(&tcp_connection::handle_write, shared_from_this(),
//                    boost::asio::placeholders::error,
//                    boost::asio::placeholders::bytes_transferred));
  }

private:
  tcp_connection(boost::asio::io_service &io_service) : socket_(io_service) {}

  void handle_write(const boost::system::error_code & /*error*/,
                    size_t /*bytes_transferred*/) {}

  tcp::socket socket_;
  std::string message_;
};

class tcp_server {
public:
  tcp_server(boost::asio::io_service &io_service)
      : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13)) {
    start_accept();
  }

private:
  void start_accept() {
    auto new_connection =
        tcp_connection::create(acceptor_.get_io_service());

    acceptor_.async_accept(new_connection->socket(),
				[this, new_connection](auto error) {
				this->handle_accept(new_connection, error);
				});
//                           boost::bind(&tcp_server::handle_accept, this,
//                                       new_connection,
//                                       boost::asio::placeholders::error));
  }

  void handle_accept(tcp_connection::pointer new_connection,
                     const boost::system::error_code &error) {
    if (!error) {
      new_connection->start();
    }

    start_accept();
  }

  tcp::acceptor acceptor_;
};

int main() {
  try {
    boost::asio::io_service io_service;
    tcp_server server(io_service);
    io_service.run();
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

你可能感兴趣的:(C++asio服务器开发)