asio编写echo服务器(C++asio网络库相关)

echo服务器:服务器接收客户端消息再原封不动回传给客户端,可以保证服务器完整收到客户端消息包再回传完整信息
比如写gameserver的时候首先就需要一个echo知道两端通信是没问题的,还可以改造成一个时间戳的包

特点:
收到客户端消息长度是不确定的

以下是BOOST库中的例子:

有以下几点是需要注意的地方:
1、通过io_service.run()驱动异步事件
2、tcp::v4() = 0.0.0.0,程序本身不要做客户端连接限制,最好由运维在linux系统下进行设置
3、server类下通过自定义start()方法可以控制服务器启动时机
4、newSession表示对客户端socket的构造出了作用域会析构,session的内部调用了shared_from_this()引用计数会加1,所以newsession析构没有关系
5、asio中的socket支持move,move本身资源相当于恢复初始化,还保存了数据结构
6、使用move应该有构造函数的良好行为
在这里插入图片描述
7、[this, self]的目的是为了让智能指针不析构,其中的self是自身类的拷贝,生命周期和lambda函数一样长,引用计数又会加1,此时引用计数为3当self析构时减1,出了newsession作用域减1此时资源并未被析构,保存到lambda函数中去了
8、同理在do_write中auto self(shared_from_this());首先让自己的引用计数加1,因为在do_read()中处理完do_write()函数自身会被析构
就这样这个类的智能指针反复在do_read()和do_write()之间传递以防止被析构直到出错调用析构,出错就意味着客户端退出
9、在构造函数中不能使用enable_shared_from_this,因为自身类的构造都还没有完成,在析构函数中也不能使用enable_shared_from_this

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

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

class session : public std::enable_shared_from_this<session> {
public:
  session(tcp::socket socket) : socket_(std::move(socket)) {
		//start();
	}

  void start() { do_read(); }

private:
  void do_read() {
    auto self(shared_from_this());
    socket_.async_read_some(
        boost::asio::buffer(data_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length) {
          if (!ec) {
            do_write(length);
          }
        });
  }

  void do_write(std::size_t length) {
    auto self(shared_from_this());
    boost::asio::async_write(
        socket_, boost::asio::buffer(data_, length),
        [this, self](boost::system::error_code ec, std::size_t /*length*/) {
          if (!ec) {
            do_read();
          }
        });
  }

  tcp::socket socket_;
  enum { max_length = 1024 };
  char data_[max_length];
};

class server {
public:
  server(boost::asio::io_service &io_service, short port)
      : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
        socket_(io_service) {
   // do_accept();
  }
	void start() {
		do_accept();
	}

private:
  void do_accept() {
    acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
      if (!ec) {
        auto newSession = std::make_shared<session>(std::move(socket_));
        newSession->start();
      }

      do_accept();
    });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
};

int main(int argc, char *argv[]) {
  try {
    if (argc != 2) {
      std::cerr << "Usage: async_tcp_echo_server <port>\n";
      return 1;
    }

    boost::asio::io_service io_service;

    server s(io_service, std::atoi(argv[1]));
		s.start();

    io_service.run();
  } catch (std::exception &e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值