欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?ASIO實(shí)現(xiàn)異步套接字管理詳解

 更新時(shí)間:2023年08月30日 14:23:16   作者:lyshark  
Boost?ASIO(Asynchronous?I/O)是一個(gè)用于異步I/O操作的C++庫(kù),該框架提供了一種方便的方式來(lái)處理網(wǎng)絡(luò)通信、多線程編程和異步操作,本文介紹了如何通過(guò)ASIO框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的異步網(wǎng)絡(luò)套接字應(yīng)用程序,需要的可以參考下

Boost ASIO(Asynchronous I/O)是一個(gè)用于異步I/O操作的C++庫(kù),該框架提供了一種方便的方式來(lái)處理網(wǎng)絡(luò)通信、多線程編程和異步操作。特別適用于網(wǎng)絡(luò)應(yīng)用程序的開發(fā),從基本的網(wǎng)絡(luò)通信到復(fù)雜的異步操作,如遠(yuǎn)程控制程序、高并發(fā)服務(wù)器等都可以使用該框架。該框架的優(yōu)勢(shì)在于其允許處理多個(gè)并發(fā)連接,而不必創(chuàng)建一個(gè)線程來(lái)管理每個(gè)連接。最重要的是ASIO是一個(gè)跨平臺(tái)庫(kù),可以運(yùn)行在任何支持C++的平臺(tái)下。

本章筆者將介紹如何通過(guò)ASIO框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的異步網(wǎng)絡(luò)套接字應(yīng)用程序,該程序支持對(duì)Socket套接字的存儲(chǔ),默認(rèn)將套接字放入到一個(gè)Map容器內(nèi),當(dāng)需要使用時(shí)只需要將套接字在容器內(nèi)取出并實(shí)現(xiàn)通信,客戶端下線時(shí)則自動(dòng)從Map容器內(nèi)移除,通過(guò)對(duì)本章知識(shí)的學(xué)習(xí)讀者可以很容易的構(gòu)建一個(gè)跨平臺(tái)的簡(jiǎn)單遠(yuǎn)控功能。

AsyncTcpClient 異步客戶端

如下這段代碼實(shí)現(xiàn)了一個(gè)基本的帶有自動(dòng)心跳檢測(cè)的客戶端,它可以通過(guò)異步連接與服務(wù)器進(jìn)行通信,并根據(jù)不同的命令返回不同的數(shù)據(jù)。代碼邏輯較為簡(jiǎn)單,但為了保證可靠性和穩(wěn)定性,實(shí)際應(yīng)用中需要進(jìn)一步優(yōu)化、處理錯(cuò)誤和異常情況,以及增加更多的功能和安全性措施。

首先我們封裝實(shí)現(xiàn)AsyncConnect類,該類內(nèi)主要實(shí)現(xiàn)兩個(gè)功能,其中aysnc_connect()方法用于實(shí)現(xiàn)異步連接到服務(wù)端,而port_is_open()方法則用于驗(yàn)證服務(wù)器特定端口是否開放,如果開放則說(shuō)明服務(wù)端還在線,不開放則說(shuō)明服務(wù)端離線此處嘗試等待一段時(shí)間后再次驗(yàn)證,在調(diào)用boost::bind()函數(shù)綁定套接字時(shí)通過(guò)&AsyncConnect::timer_handle()函數(shù)來(lái)設(shè)置一個(gè)超時(shí)等待時(shí)間。

進(jìn)入到主函數(shù)中,首先程序通過(guò)while循環(huán)讓程序保持持續(xù)運(yùn)行,并通過(guò)hander.aysnc_connect(ep, 5000) 每隔5秒驗(yàn)證是否與服務(wù)端連接成功,如果連接了則進(jìn)入內(nèi)循環(huán),在內(nèi)循環(huán)中通過(guò)hander.port_is_open("127.0.0.1", 10000, 5000)驗(yàn)證特定端口是否開放,這主要是為了保證服務(wù)端斷開后客戶端依然能夠跳轉(zhuǎn)到外部循環(huán)繼續(xù)等待服務(wù)端上線。而當(dāng)客戶端與服務(wù)端建立連接后則會(huì)持續(xù)在內(nèi)循環(huán)中socket.read_some()接收服務(wù)端傳來(lái)的特定命令,以此來(lái)執(zhí)行不同的操作。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/array.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>  
#include <boost/noncopyable.hpp>
using namespace std;
using boost::asio::ip::tcp;
// 異步連接地址與端口
class AsyncConnect
{
public:
	AsyncConnect(boost::asio::io_service& ios, tcp::socket &s)
		:io_service_(ios), timer_(ios), socket_(s) {}
	// 異步連接
	bool aysnc_connect(const tcp::endpoint &ep, int million_seconds)
	{
		bool connect_success = false;
		// 異步連接,當(dāng)連接成功后將觸發(fā) connect_handle 函數(shù)
		socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success)));
		// 設(shè)置一個(gè)定時(shí)器  million_seconds 
		timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds));
		bool timeout = false;
		// 異步等待 如果超時(shí)則執(zhí)行 timer_handle
		timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout)));
		do
		{
			// 等待異步操作完成
			io_service_.run_one();
			// 判斷如果timeout沒(méi)超時(shí),或者是連接建立了,則不再等待
		} while (!timeout && !connect_success);
		timer_.cancel();
		return connect_success;
	}
	// 驗(yàn)證服務(wù)器端口是否開放
	bool port_is_open(std::string address, int port, int timeout)
	{
		try
		{
			boost::asio::io_service io;
			tcp::socket socket(io);
			AsyncConnect hander(io, socket);
			tcp::endpoint ep(boost::asio::ip::address::from_string(address), port);
			if (hander.aysnc_connect(ep, timeout))
			{
				io.run();
				io.reset();
				return true;
			}
			else
			{
				return false;
			}
		}
		catch (...)
		{
			return false;
		}
	}
private:
	// 如果連接成功了,則 connect_success = true
	void connect_handle(boost::system::error_code ec, bool &connect_success)
	{
		if (!ec)
		{
			connect_success = true;
		}
	}
	// 定時(shí)器超時(shí)timeout = true
	void timer_handle(boost::system::error_code ec, bool &timeout)
	{
		if (!ec)
		{
			socket_.close();
			timeout = true;
		}
	}
	boost::asio::io_service &io_service_;
	boost::asio::deadline_timer timer_;
	tcp::socket &socket_;
};
int main(int argc, char * argv[])
{
	try
	{
		boost::asio::io_service io;
		tcp::socket socket(io);
		AsyncConnect hander(io, socket);
		boost::system::error_code error;
		tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 10000);
		// 循環(huán)驗(yàn)證是否在線
	go_:  while (1)
	{
		// 驗(yàn)證是否連接成功,并定義超時(shí)時(shí)間為5秒
		if (hander.aysnc_connect(ep, 5000))
		{
			io.run();
			std::cout << "已連接到服務(wù)端." << std::endl;
			// 循環(huán)接收命令
			while (1)
			{
				// 驗(yàn)證地址端口是否開放,默認(rèn)等待5秒
				bool is_open = hander.port_is_open("127.0.0.1", 10000, 5000);
				// 客戶端接收數(shù)據(jù)包
				boost::array<char, 4096> buffer = { 0 };
				// 如果在線則繼續(xù)執(zhí)行
				if (is_open == true)
				{
					socket.read_some(boost::asio::buffer(buffer), error);
					// 判斷收到的命令是否為GetCPU
					if (strncmp(buffer.data(), "GetCPU", strlen("GetCPU")) == 0)
					{
						std::cout << "獲取CPU參數(shù)并返回給服務(wù)端." << std::endl;
						socket.write_some(boost::asio::buffer("CPU: 15 %"));
					}
					// 判斷收到的命令是否為GetMEM
					if (strncmp(buffer.data(), "GetMEM", strlen("GetMEM")) == 0)
					{
						std::cout << "獲取MEM參數(shù)并返回給服務(wù)端." << std::endl;
						socket.write_some(boost::asio::buffer("MEM: 78 %"));
					}
					// 判斷收到的命令是否為終止程序
					if (strncmp(buffer.data(), "Exit", strlen("Exit")) == 0)
					{
						std::cout << "終止客戶端." << std::endl;
						return 0;
					}
				}
				else
				{
					// 如果連接失敗,則跳轉(zhuǎn)到等待環(huán)節(jié)
					goto go_;
				}
			}
		}
		else
		{
			std::cout << "連接失敗,正在重新連接." << std::endl;
		}
	}
	}
	catch (...)
	{
		return false;
	}
	std::system("pause");
	return 0;
}

AsyncTcpServer 異步服務(wù)端

接著我們來(lái)實(shí)現(xiàn)異步TCP服務(wù)器,首先我們需要封裝實(shí)現(xiàn)CAsyncTcpServer類,該類使用了多線程來(lái)支持異步通信,每個(gè)客戶端連接都會(huì)創(chuàng)建一個(gè)CTcpConnection類的實(shí)例來(lái)處理具體的通信操作,該服務(wù)器類在連接建立、數(shù)據(jù)傳輸和連接斷開時(shí),都會(huì)通過(guò)事件處理器來(lái)通知相關(guān)操作,以支持服務(wù)器端的業(yè)務(wù)邏輯。其頭文件聲明如下所示;

#ifdef _MSC_VER
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#define _WIN32_WINNT 0x0601
#define _CRT_SECURE_NO_WARNINGS
#endif
#pragma once
#include <thread>
#include <array>
#include <boost\bind.hpp>
#include <boost\noncopyable.hpp>
#include <boost\asio.hpp>
#include <boost\asio\placeholders.hpp>
using namespace boost::asio;
using namespace boost::asio::ip;
using namespace boost::placeholders;
using namespace std;
// 每一個(gè)套接字連接,都自動(dòng)對(duì)應(yīng)一個(gè)Tcp客戶端連接
class CTcpConnection
{
public:
	CTcpConnection(io_service& ios, int clientId) : m_socket(ios), m_clientId(clientId){}
	~CTcpConnection(){}
	int                        m_clientId;
	tcp::socket                m_socket;
	array<BYTE, 16 * 1024>     m_buffer;
};
typedef shared_ptr<CTcpConnection> TcpConnectionPtr;
class CAsyncTcpServer
{
public:
	class IEventHandler
	{
	public:
		IEventHandler(){}
		virtual ~IEventHandler(){}
		virtual void ClientConnected(int clientId) = 0;
		virtual void ClientDisconnect(int clientId) = 0;
		virtual void ReceiveData(int clientId, const BYTE* data, size_t length) = 0;
	};
public:
	CAsyncTcpServer(int maxClientNumber, int port);
	~CAsyncTcpServer();
	void AddEventHandler(IEventHandler* pHandler){ m_EventHandlers.push_back(pHandler); }
	void Send(int clientId, 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;
};

接著來(lái)實(shí)現(xiàn)AsyncTcpServer頭文件中的功能函數(shù),此功能函數(shù)的實(shí)現(xiàn)如果讀者不明白原理可自行將其提交給ChatGPT解析,這里就不再解釋功能了。

// By: 朱迎春 (基礎(chǔ)改進(jìn)版)
#include "AsyncTcpServer.h"
// CAsyncTcpServer的實(shí)現(xiàn)
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();
}
// 根據(jù)ID號(hào)同步給特定客戶端發(fā)送數(shù)據(jù)包
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));
}
// 根據(jù)ID號(hào)返回客戶端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;
}
// 根據(jù)ID號(hào)返回端口號(hào)
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)
	{
		// 判斷連接數(shù)目是否達(dá)到最大限度
		if (m_maxClientNumber > 0 && m_clients.size() >= m_maxClientNumber)
		{
			m_nextClient->m_socket.close();
		}
		else
		{
			// 發(fā)送客戶端連接的消息
			for (int i = 0; i < m_EventHandlers.size(); ++i)
			{
				m_EventHandlers[i]->ClientConnected(m_nextClient->m_clientId);
			}
			// 設(shè)置異步接收數(shù)據(jù)
			bind_hand_read(m_nextClient.get());
			// 將客戶端連接放到客戶表中
			m_clients.insert(make_pair(m_nextClient->m_clientId, m_nextClient));
			// 重置下一個(gè)客戶端連接
			m_nextClient = make_shared<CTcpConnection>(m_ioservice, m_clientId);
			m_clientId++;
		}
	}
	// 異步等待下一個(gè)客戶端連接
	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)
	{
		// 發(fā)送收到數(shù)據(jù)的信息
		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
	{
		// 發(fā)送客戶端離線的消息
		for (int i = 0; i < m_EventHandlers.size(); ++i)
		{
			m_EventHandlers[i]->ClientDisconnect(client->m_clientId);
		}
		m_clients.erase(client->m_clientId);
	}
}

AsyncTcpServer 類調(diào)用

服務(wù)端首先定義CEventHandler類并繼承自CAsyncTcpServer::IEventHandler接口,該類內(nèi)需要我們實(shí)現(xiàn)三個(gè)方法,方法ClientConnected用于在客戶端連接時(shí)觸發(fā),方法ClientDisconnect則是在登錄客戶端離開時(shí)觸發(fā),而當(dāng)客戶端有數(shù)據(jù)發(fā)送過(guò)來(lái)時(shí)則ReceiveData方法則會(huì)被觸發(fā)。

方法ClientConnected當(dāng)被觸發(fā)時(shí)自動(dòng)將clientId客戶端Socket套接字放入到tcp_client_id全局容器內(nèi)存儲(chǔ)起來(lái),而當(dāng)ClientDisconnect客戶端退出時(shí),則直接遍歷這個(gè)迭代容器,找到序列號(hào)并通過(guò)tcp_client_id.erase將其剔除;

// 客戶端連接時(shí)觸發(fā)
virtual void ClientConnected(int clientId)
{
	// 將登錄客戶端加入到容器中
	tcp_client_id.push_back(clientId);
}
// 客戶端退出時(shí)觸發(fā)
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一旦收到數(shù)據(jù),則直接將其打印輸出到屏幕,即可實(shí)現(xiàn)客戶端參數(shù)接收的目的;

// 客戶端獲取數(shù)據(jù)
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] # ";
}

相對(duì)于接收數(shù)據(jù)而言,發(fā)送數(shù)據(jù)則是通過(guò)同步的方式進(jìn)行,當(dāng)我們需要發(fā)送數(shù)據(jù)時(shí),只需要將數(shù)據(jù)字符串放入到一個(gè)BYTE*字節(jié)數(shù)組中,并在調(diào)用tcpServer.Send時(shí)將所需參數(shù),套接字ID,緩沖區(qū)Buf數(shù)據(jù),以及長(zhǎng)度傳遞即可實(shí)現(xiàn)將數(shù)據(jù)發(fā)送給指定的客戶端;

// 同步發(fā)送數(shù)據(jù)到指定的線程中
void send_message(CAsyncTcpServer& tcpServer, int clientId, std::string message, int message_size)
{
	// 獲取長(zhǎng)度
	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);
	}
	tcpServer.Send(clientId, buf, message_size);
}

客戶端完整代碼如下所示,運(yùn)行客戶端后讀者可自行使用不同的命令來(lái)接收參數(shù)返回值;

#include "AsyncTcpServer.h"
#include <string>
#include <vector>
#include <iostream>
#include <boost/tokenizer.hpp>
using namespace std;
// 存儲(chǔ)當(dāng)前客戶端的ID號(hào)
std::vector<int> tcp_client_id;
// 輸出特定長(zhǎng)度的行
void PrintLine(int line)
{
	for (int x = 0; x < line; x++)
	{
		printf("-");
	}
	printf("\n");
}
class CEventHandler : public CAsyncTcpServer::IEventHandler
{
public:
	// 客戶端連接時(shí)觸發(fā)
	virtual void ClientConnected(int clientId)
	{
		// 將登錄客戶端加入到容器中
		tcp_client_id.push_back(clientId);
	}
	// 客戶端退出時(shí)觸發(fā)
	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);
	}
	// 客戶端獲取數(shù)據(jù)
	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] # ";
	}
};
// 同步發(fā)送數(shù)據(jù)到指定的線程中
void send_message(CAsyncTcpServer& tcpServer, int clientId, std::string message, int message_size)
{
	// 獲取長(zhǎng)度
	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);
	}
	tcpServer.Send(clientId, buf, message_size);
}
int main(int argc, char* argv[])
{
	CAsyncTcpServer tcpServer(10, 10000);
	CEventHandler eventHandler;
	tcpServer.AddEventHandler(&eventHandler);
	std::string command;
	while (1)
	{
		std::cout << "[Shell] # ";
		std::getline(std::cin, command);
		if (command.length() == 0)
		{
			continue;
		}
		else if (command == "help")
		{
			printf(" _            ____             _        _   \n");
			printf("| |   _   _  / ___|  ___   ___| | _____| |_  \n");
			printf("| |  | | | | \\___ \\ / _ \\ / __| |/ / _ \\ __| \n");
			printf("| |__| |_| |  ___) | (_) | (__|   <  __/ |_  \n");
			printf("|_____\\__, | |____/ \\___/ \\___|_|\\_\\___|\\__| \n");
			printf("      |___/                                 \n\n");
			printf("Usage: LySocket \t PowerBy: LyShark.com \n");
			printf("Optional: \n\n");
			printf("\t ShowSocket        輸出所有Socket容器 \n");
			printf("\t GetCPU            獲取CPU數(shù)據(jù) \n");
			printf("\t GetMemory         獲取內(nèi)存數(shù)據(jù) \n");
			printf("\t Exit              退出客戶端 \n\n");
		}
		else
		{
			// 定義分詞器: 定義分割符號(hào)為[逗號(hào),空格]
			boost::char_separator<char> sep(", --");
			typedef boost::tokenizer<boost::char_separator<char>> CustonTokenizer;
			CustonTokenizer tok(command, sep);
			// 將分詞結(jié)果放入vector鏈表
			std::vector<std::string> vecSegTag;
			for (CustonTokenizer::iterator beg = tok.begin(); beg != tok.end(); ++beg)
			{
				vecSegTag.push_back(*beg);
			}
			// 解析 [shell] # ShowSocket
			if (vecSegTag.size() == 1 && vecSegTag[0] == "ShowSocket")
			{
				PrintLine(80);
				printf("客戶ID \t 客戶IP地址 \t 客戶端口 \n");
				PrintLine(80);
				for (int x = 0; x < tcp_client_id.size(); x++)
				{
					std::cout << tcp_client_id[x] << " \t "
						<< tcpServer.GetRemoteAddress(tcp_client_id[x]) << " \t "
						<< tcpServer.GetRemotePort(tcp_client_id[x]) << std::endl;
				}
				PrintLine(80);
			}
			// 解析 [shell] # GetCPU --id 100
			if (vecSegTag.size() == 3 && vecSegTag[0] == "GetCPU")
			{
				char *id = (char *)vecSegTag[2].c_str();
				send_message(tcpServer, atoi(id), "GetCPU", strlen("GetCPU"));
			}
			// 解析 [shell] # GetMemory --id 100
			if (vecSegTag.size() == 3 && vecSegTag[0] == "GetMemory")
			{
				char* id = (char*)vecSegTag[2].c_str();
				send_message(tcpServer, atoi(id), "GetMEM", strlen("GetMEM"));
			}
			// 解析 [shell] # Exit --id 100
			if (vecSegTag.size() == 3 && vecSegTag[0] == "Exit")
			{
				char* id = (char*)vecSegTag[2].c_str();
				send_message(tcpServer, atoi(id), "Exit", strlen("Exit"));
			}
		}
	}
	return 0;
}

案例演示

首先運(yùn)行服務(wù)端程序,接著運(yùn)行多個(gè)客戶端,即可實(shí)現(xiàn)自動(dòng)上線;

當(dāng)用戶需要通信時(shí),只需要指定id序號(hào)到指定的Socket套接字編號(hào)即可;

以上就是C++ ASIO實(shí)現(xiàn)異步套接字管理詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ ASIO異步套接字管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C 語(yǔ)言基礎(chǔ)之C 語(yǔ)言三大語(yǔ)句注意事項(xiàng)

    C 語(yǔ)言基礎(chǔ)之C 語(yǔ)言三大語(yǔ)句注意事項(xiàng)

    今天講解的內(nèi)容,則是自己對(duì)于這三種語(yǔ)句一些細(xì)節(jié)的簡(jiǎn)單介紹,分支語(yǔ)句:if,switch、循環(huán)語(yǔ)句:while,for,do while、goto語(yǔ)句,感興趣的小伙伴可以參考下面具體的文章內(nèi)容
    2021-09-09
  • Qt Design Studio安裝圖文教程

    Qt Design Studio安裝圖文教程

    本文主要介紹了Qt Design Studio安裝圖文教程,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)代碼

    C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)代碼

    本篇文章是對(duì)C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++虛函數(shù)和多態(tài)超詳細(xì)分析

    C++虛函數(shù)和多態(tài)超詳細(xì)分析

    這篇文章主要介紹了C++多態(tài)的特性派生與虛函數(shù)與模板,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • C/C++中指針和引用之相關(guān)問(wèn)題深入研究

    C/C++中指針和引用之相關(guān)問(wèn)題深入研究

    從內(nèi)存分配上看,程序?yàn)橹羔樧兞糠峙鋬?nèi)存區(qū)域,而不為引用分配內(nèi)存區(qū)域,因?yàn)橐寐暶鲿r(shí)必須初始化,從而指向一個(gè)已經(jīng)存在的對(duì)象。引用不能指向空值
    2013-10-10
  • C++高級(jí)數(shù)據(jù)結(jié)構(gòu)之并查集

    C++高級(jí)數(shù)據(jù)結(jié)構(gòu)之并查集

    這篇文章主要介紹了C高級(jí)數(shù)據(jù)結(jié)構(gòu)之并查集,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • C++深入淺出探索數(shù)據(jù)結(jié)構(gòu)的原理

    C++深入淺出探索數(shù)據(jù)結(jié)構(gòu)的原理

    C++的數(shù)據(jù)結(jié)構(gòu)很多,很復(fù)雜,所以本文將通過(guò)示例帶大家深入了解一下C++中的數(shù)據(jù)結(jié)構(gòu)與算法。文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-05-05
  • C++中指針和引用的區(qū)別分析

    C++中指針和引用的區(qū)別分析

    這篇文章主要介紹了C++中指針和引用的區(qū)別,有需要的朋友可以參考一下
    2014-01-01
  • C++實(shí)現(xiàn)正態(tài)隨機(jī)分布的方法

    C++實(shí)現(xiàn)正態(tài)隨機(jī)分布的方法

    本篇介紹了,使用c++實(shí)現(xiàn)正態(tài)隨機(jī)分布的實(shí)現(xiàn)方法。需要的朋友參考下
    2013-05-05
  • C++實(shí)現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索)

    C++實(shí)現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(33.在旋轉(zhuǎn)有序數(shù)組中搜索),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評(píng)論