Id, const BYTE* data, size_t length);
string GetRemoteAddress(int clientId);
string GetRemotePort(int clientId);
private:
void bind_hand_read(CTcpConnection* client);
void handle_accept(const boost::system::error_code& error);
void handle_read(CTcpConnection* client, const boost::system::error_code& error, size_t bytes_transferred);
private:
thread m_thread;
io_service m_ioservice;
io_service::work m_work;
tcp::acceptor m_acceptor;
int m_maxClientNumber;
int m_clientId;
TcpConnectionPtr m_nextClient;
map<int, TcpConnectionPtr> m_clients;
vector<IEventHandler*> m_EventHandlers;
};
接着来实现AsyncTcpServer
头文件中的功能函数,此功能函数的实现如果读者不明白原理可自行将其提交给ChatGPT解析,这里就不再解释功能了。
// By: 朱迎春 (基础改进版)
#include "AsyncTcpServer.h"
// CAsyncTcpServer的实现
CAsyncTcpServer::CAsyncTcpServer(int maxClientNumber, int port)
: m_ioservice()
, m_work(m_ioservice)
, m_acceptor(m_ioservice)
, m_maxClientNumber(maxClientNumber)
, m_clientId(0)
{
m_thread = thread((size_t(io_service::*)())&io_service::run, &m_ioservice);
m_nextClient = make_shared<CTcpConnection>(m_ioservice, m_clientId);
m_clientId++;
tcp::endpoint endpoint(tcp::v4(), port);
m_acceptor.open(endpoint.protocol());
m_acceptor.set_option(tcp::acceptor::reuse_address(true));
m_acceptor.bind(endpoint);
m_acceptor.listen();
// 异步等待客户端连接
m_acceptor.async_accept(m_nextClient->m_socket, boost::bind(&CAsyncTcpServer::handle_accept, this, boost::asio::placeholders::error));
}
CAsyncTcpServer::~CAsyncTcpServer()
{
for (map<int, TcpConnectionPtr>::iterator it = m_clients.begin(); it != m_clients.end(); ++it)
{
it->second->m_socket.close();
}
m_ioservice.stop();
m_thread.join();
}
// 根据ID号同步给特定客户端发送数据包
void CAsyncTcpServer::Send(int clientId, const BYTE* data, size_t length)
{
map<int, TcpConnectionPtr>::iterator it = m_clients.find(clientId);
if (it == m_clients.end())
{
return;
}
it->second->m_socket.write_some(boost::asio::buffer(data, length));
}
// 根据ID号返回客户端IP地址
string CAsyncTcpServer::GetRemoteAddress(int clientId)
{
map<int, TcpConnectionPtr>::iterator it = m_clients.find(clientId);
if (it == m_clients.end())
{
return "0.0.0.0";
}
std::string remote_address = it->second->m_socket.remote_endpoint().address().to_string();
return remote_address;
}
// 根据ID号返回端口号
string CAsyncTcpServer::GetRemotePort(int clientId)
{
map<int, TcpConnectionPtr>::iterator it = m_clients.find(clientId);
char ref[32] = { 0 };
if (it == m_clients.end())
{
return "*";
}
unsigned short remote_port = it->second->m_socket.remote_endpoint().port();
std::string str = _itoa(remote_port, ref, 10);
return str;
}
void CAsyncTcpServer::handle_accept(const boost::system::error_code& error)
{
if (!error)
{
// 判断连接数目是否达到最大限度
if (m_maxClientNumber > 0 && m_clients.size() >= m_maxClientNumber)
{
m_nextClient->m_socket.close();
}
else
{
// 发送客户端连接的消息
for (int i = 0; i < m_EventHandlers.size(); ++i)
{
m_EventHandlers[i]->ClientConnected(m_nextClient->m_clientId);
}