最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

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

2023-08-29 17:32 作者:bili_42682284418  | 我要投稿

Boost ASIO(Asynchronous I/O)是一個(gè)用于異步I/O操作的C++庫(kù),該框架提供了一種方便的方式來(lái)處理網(wǎng)絡(luò)通信、多線(xiàn)程編程和異步操作。特別適用于網(wǎng)絡(luò)應(yīng)用程序的開(kāi)發(fā),從基本的網(wǎng)絡(luò)通信到復(fù)雜的異步操作,如遠(yuǎn)程控制程序、高并發(fā)服務(wù)器等都可以使用該框架。該框架的優(yōu)勢(shì)在于其允許處理多個(gè)并發(fā)連接,而不必創(chuàng)建一個(gè)線(xiàn)程來(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)通信,客戶(hù)端下線(xiàn)時(shí)則自動(dòng)從Map容器內(nèi)移除,通過(guò)對(duì)本章知識(shí)的學(xué)習(xí)讀者可以很容易的構(gòu)建一個(gè)跨平臺(tái)的簡(jiǎn)單遠(yuǎn)控功能。

AsyncTcpClient 異步客戶(hù)端

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

首先我們封裝實(shí)現(xiàn)AsyncConnect類(lèi),該類(lèi)內(nèi)主要實(shí)現(xiàn)兩個(gè)功能,其中aysnc_connect()方法用于實(shí)現(xiàn)異步連接到服務(wù)端,而port_is_open()方法則用于驗(yàn)證服務(wù)器特定端口是否開(kāi)放,如果開(kāi)放則說(shuō)明服務(wù)端還在線(xiàn),不開(kāi)放則說(shuō)明服務(wù)端離線(xiàn)此處嘗試等待一段時(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)證特定端口是否開(kāi)放,這主要是為了保證服務(wù)端斷開(kāi)后客戶(hù)端依然能夠跳轉(zhuǎn)到外部循環(huán)繼續(xù)等待服務(wù)端上線(xiàn)。而當(dāng)客戶(hù)端與服務(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ù)器端口是否開(kāi)放
????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)證是否在線(xià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)證地址端口是否開(kāi)放,默認(rèn)等待5秒
????????????????bool?is_open?=?hander.port_is_open("127.0.0.1",?10000,?5000);

????????????????//?客戶(hù)端接收數(shù)據(jù)包
????????????????boost::array<char,?4096>?buffer?=?{?0?};

????????????????//?如果在線(xiàn)則繼續(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?<<?"終止客戶(hù)端."?<<?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),該類(lèi)使用了多線(xiàn)程來(lái)支持異步通信,每個(gè)客戶(hù)端連接都會(huì)創(chuàng)建一個(gè)CTcpConnection類(lèi)的實(shí)例來(lái)處理具體的通信操作,該服務(wù)器類(lèi)在連接建立、數(shù)據(jù)傳輸和連接斷開(kāi)時(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客戶(hù)端連接
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();

????//?異步等待客戶(hù)端連接
????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)同步給特定客戶(hù)端發(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)返回客戶(hù)端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ā)送客戶(hù)端連接的消息
????????????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());

????????????//?將客戶(hù)端連接放到客戶(hù)表中
????????????m_clients.insert(make_pair(m_nextClient->m_clientId,?m_nextClient));

????????????//?重置下一個(gè)客戶(hù)端連接
????????????m_nextClient?=?make_shared<CTcpConnection>(m_ioservice,?m_clientId);
????????????m_clientId++;
????????}
????}

????//?異步等待下一個(gè)客戶(hù)端連接
????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ā)送客戶(hù)端離線(xiàn)的消息
????????for?(int?i?=?0;?i?<?m_EventHandlers.size();?++i)
????????{
????????????m_EventHandlers[i]->ClientDisconnect(client->m_clientId);
????????}
????????m_clients.erase(client->m_clientId);
????}
}

AsyncTcpServer 類(lèi)調(diào)用

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

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

//?客戶(hù)端連接時(shí)觸發(fā)
virtual?void?ClientConnected(int?clientId)
{
????//?將登錄客戶(hù)端加入到容器中
????tcp_client_id.push_back(clientId);
}
??
//?客戶(hù)端退出時(shí)觸發(fā)
virtual?void?ClientDisconnect(int?clientId)
{
????//?將登出的客戶(hù)端從容器中移除
????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)客戶(hù)端參數(shù)接收的目的;

//?客戶(hù)端獲取數(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ā)送給指定的客戶(hù)端;

//?同步發(fā)送數(shù)據(jù)到指定的線(xiàn)程中
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);
}

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

#include?"AsyncTcpServer.h"
#include?<string>
#include?<vector>
#include?<iostream>
#include?<boost/tokenizer.hpp>

using?namespace?std;

//?存儲(chǔ)當(dāng)前客戶(hù)端的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:
????//?客戶(hù)端連接時(shí)觸發(fā)
????virtual?void?ClientConnected(int?clientId)
????{
????????//?將登錄客戶(hù)端加入到容器中
????????tcp_client_id.push_back(clientId);
????}

????//?客戶(hù)端退出時(shí)觸發(fā)
????virtual?void?ClientDisconnect(int?clientId)
????{
????????//?將登出的客戶(hù)端從容器中移除
????????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);
????}

????//?客戶(hù)端獲取數(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ù)到指定的線(xiàn)程中
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??????????????退出客戶(hù)端?\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("客戶(hù)ID?\t?客戶(hù)IP地址?\t?客戶(hù)端口?\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è)客戶(hù)端,即可實(shí)現(xiàn)自動(dòng)上線(xiàn);

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

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/d0805aed.html 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!


C++ ASIO 實(shí)現(xiàn)異步套接字管理的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
双辽市| 平昌县| 太仓市| 祁东县| 南陵县| 阿拉善盟| 上高县| 东台市| 西乌珠穆沁旗| 南城县| 丹棱县| 延吉市| 五寨县| 达拉特旗| 三门峡市| 南昌县| 佳木斯市| 正镶白旗| 柏乡县| 巫溪县| 天全县| 汾阳市| 普宁市| 长子县| 礼泉县| 新竹县| 藁城市| 内乡县| 曲松县| 德庆县| 大埔县| 故城县| 和硕县| 上杭县| 柳林县| 汉中市| 北辰区| 丹棱县| 郓城县| 乌鲁木齐市| 南康市|