设为首页 加入收藏

TOP

C++ ASIO 实现异步套接字管理(五)
2023-09-09 10:25:48 】 浏览:385
Tags:ASIO 步套接 管理
// 设置异步接收数据 bind_hand_read(m_nextClient.get()); // 将客户端连接放到客户表中 m_clients.insert(make_pair(m_nextClient->m_clientId, m_nextClient)); // 重置下一个客户端连接 m_nextClient = make_shared<CTcpConnection>(m_ioservice, m_clientId); m_clientId++; } } // 异步等待下一个客户端连接 m_acceptor.async_accept(m_nextClient->m_socket, boost::bind(&CAsyncTcpServer::handle_accept, this, boost::asio::placeholders::error)); } void CAsyncTcpServer::bind_hand_read(CTcpConnection* client) { client->m_socket.async_read_some(boost::asio::buffer(client->m_buffer), boost::bind(&CAsyncTcpServer::handle_read, this, client, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); return; client->m_socket.async_receive(boost::asio::buffer(client->m_buffer), boost::bind(&CAsyncTcpServer::handle_read, this, client, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); boost::asio::async_read(client->m_socket, boost::asio::buffer(client->m_buffer), boost::bind(&CAsyncTcpServer::handle_read, this, client, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void CAsyncTcpServer::handle_read(CTcpConnection* client, const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { // 发送收到数据的信息 for (int i = 0; i < m_EventHandlers.size(); ++i) { m_EventHandlers[i]->ReceiveData(client->m_clientId, client->m_buffer.data(), bytes_transferred); } bind_hand_read(client); } else { // 发送客户端离线的消息 for (int i = 0; i < m_EventHandlers.size(); ++i) { m_EventHandlers[i]->ClientDisconnect(client->m_clientId); } m_clients.erase(client->m_clientId); } }

AsyncTcpServer 类调用

服务端首先定义CEventHandler类并继承自CAsyncTcpServer::IEventHandler接口,该类内需要我们实现三个方法,方法ClientConnected用于在客户端连接时触发,方法ClientDisconnect则是在登录客户端离开时触发,而当客户端有数据发送过来时则ReceiveData方法则会被触发。

方法ClientConnected当被触发时自动将clientId客户端Socket套接字放入到tcp_client_id全局容器内存储起来,而当ClientDisconnect客户端退出时,则直接遍历这个迭代容器,找到序列号并通过tcp_client_id.erase将其剔除;

// 客户端连接时触发
virtual void ClientConnected(int clientId)
{
	// 将登录客户端加入到容器中
	tcp_client_id.push_back(clientId);
}
  
// 客户端退出时触发
virtual void ClientDisconnect(int clientId)
{
	// 将登出的客户端从容器中移除
	vector<int>::iterator item = find(tcp_client_id.begin(), tcp_client_id.end(), clientId);
	if (item != tcp_client_id.cend())
		tcp_client_id.erase(item);
}

ReceiveData一旦收到数据,则直接将其打印输出到屏幕,即可实现客户端参数接收的目的;

// 客户端获取数据
virtual void ReceiveData(int clientId, const BYTE* data, size_t length)
{
	std::cout << std::endl;
	PrintLine(80);
	std::cout << data << std::endl;
	PrintLine(80);
	std::cout << "[Shell] # ";
}

相对于接收数据而言,发送数据则是通过同步的方式进行,当我们需要发送数据时,只需要将数据字符串放入到一个BYTE*字节数组中,并在调用tcpServer.Send时将所需参数,套接字ID,缓冲区Buf数据,以及长度传递即可实现将数据发送给指定的客户端;

// 同步发送数据到指定的线程中
void send_message(CAsyncTcpServer& tcpServer, int clientId, std::string message, int message_size)
{
	// 获取长度
	BYTE* buf = new BYTE(message_size + 1);
	memset(buf, 0, message_size + 1);

	for (int i = 0; i < message_size; i++)
	{
		buf[i] = message.at(i
首页 上一页 2 3 4 5 6 下一页 尾页 5/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Pybind11绑定C++抽象类(DLL接口) 下一篇AC 自动机学习笔记

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目