/*---------------------------------------------------------------------------
文件 : 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 \r\n", __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\r\n", 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\r\n", e.what());
throw std::string("Construct tcp::acceptor error");
}
printf("CSockServer::Init() success! \r\n");
return true;
}
//------------------------------------------------------------------------
// 函数名称: Start
// 返 回 值: bool -- true成功, false 失败
// 说 明: 多线程异步调用socket事件
//------------------------------------------------------------------------
bool CSockServer::Start()
{
if (!m_vtxThreads.empty())
{
printf("Attempt to start socket server while it's running!!\r\n");
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! \r\n");
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!\r\n");
}
}
//------------------------------------------------------------------------
// 函数名称: Stop
// 返 回 值: void
// 说 明: 服务停止
//------------------------------------------------------------------------
void CSockServer::Stop()
{
m_ios.stop();
}