/*--------------------------------------------------------------------------- 文件 : SockServer.h 版本 : V1.0 描述 : asio socket server ---------------------------------------------------------------------------*/ #pragma once #include <list> #include <thread> #include <boost/asio.hpp> #include <boost/serialization/singleton.hpp> using namespace std; using boost::asio::ip::tcp; #define tcpServer CSockServer::get_mutable_instance() class CSockServer : public boost::serialization::singleton<CSockServer> { public: CSockServer(); ~CSockServer(); bool Init(); bool Start(); void Stop(); protected: void Run(); //Accept 模板 template <class S> void Accept(std::shared_ptr<tcp::acceptor> accept) { //异步等待一个客户端来连接 accept->async_accept( [this, accept](const boost::system::error_code& ec, tcp::socket socket) { printf("%s %d ", __FUNCTION__, __LINE__); if (!ec) { //实例化连接对象(自定义一个类,实现业务操作 StartWork) std::make_shared<S>(std::move(socket))->StartWork(); } else { std::string xx = ec.message(); printf("Accept fsu session error:%s ", ec.message().c_str()); exit(-1); } //创建完一个新的连接后, 需要再次异步等待下一个连接。不然Accept函数会退出。 Accept<S>(accept); }); } protected: //asio程序必须的io_service对象,使用io_service与系统的输入输出进行交互 boost::asio::io_service m_ios; //守护io_service boost::asio::io_service::work m_work; //保存线程句柄 std::vector<std::shared_ptr<std::thread>> m_vtxThreads; };
/*--------------------------------------------------------------------------- 文件 : SockServer.cpp 版本 : V1.0 描述 : asio socket server,终端数据接收tcp端口,创建连接session ---------------------------------------------------------------------------*/ #include <algorithm> #include <string> #include <thread> #include "com_def.h" #include "ClientSession.h" #include "SockServer.h" using namespace std; CSockServer::CSockServer() : m_work(m_ios) { } CSockServer::~CSockServer() { } //------------------------------------------------------------------------ // 函数名称: Init // 返 回 值: bool -- true 成功,false失败,一般是端口被占用 // 说 明: 初始化,监听端口并开始异步accept //------------------------------------------------------------------------ bool CSockServer::Init() { boost::system::error_code ec; try { std::shared_ptr<tcp::acceptor> accept1(new tcp::acceptor(m_ios, tcp::endpoint(tcp::v4(), 7200), false)); Accept<ClientSession>(accept1); } catch (boost::system::system_error& e) { printf("Construct tcp::acceptor error:%s ", e.what()); throw std::string("Construct tcp::acceptor error"); } printf("CSockServer::Init() success! "); return true; } //------------------------------------------------------------------------ // 函数名称: Start // 返 回 值: bool -- true成功, false 失败 // 说 明: 多线程异步调用socket事件 //------------------------------------------------------------------------ bool CSockServer::Start() { if (!m_vtxThreads.empty()) { printf("Attempt to start socket server while it's running!! "); return false; } unsigned int uCount = MAX_T((unsigned int)4, std::thread::hardware_concurrency()); try { for (unsigned int i = 0; i < uCount; ++i) { //多线程异步调用socket事件 std::shared_ptr<std::thread> t(new std::thread(&CSockServer::Run, this)); m_vtxThreads.emplace_back(t); } } catch (const std::string&) { throw ("CSockServer::Start() error"); } printf("CSockServer::Start() success! "); return true; } //------------------------------------------------------------------------ // 函数名称: Run // 返 回 值: void // 说 明: socket 事件循环 //------------------------------------------------------------------------ void CSockServer::Run() { boost::system::error_code ec; m_ios.run(ec); if (ec) { printf("Exit one socket server running thread with error msg:%s!", ec.message().c_str()); } else { printf("Exit one socket server running thread with normal code! "); } } //------------------------------------------------------------------------ // 函数名称: Stop // 返 回 值: void // 说 明: 服务停止 //------------------------------------------------------------------------ void CSockServer::Stop() { m_ios.stop(); }