博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
boost库在工作(36)网络服务端之六
阅读量:6944 次
发布时间:2019-06-27

本文共 4377 字,大约阅读时间需要 14 分钟。

在上面介绍了管理所有连接的类,这个类主要就是添加新的连接,或者删除不需要的连接。但是管理的类CAllConnect是没有办法知道什么时候添加,什么时候删除的,它需要从接收到连接类里获取得到新的连接,从连接类里获得删除的事件。如下面的代码:

//封装一个服务端类来处理网络。//软件开发人员: 蔡军生  2013-07-28//class CConnect : 	public boost::enable_shared_from_this< CConnect >{	static const int MAX_BUFSIZE = 1024;public:	CConnect(boost::asio::io_service& ioService, CAllConnect& allConnect)		:m_Socket(ioService),		m_rAllConnect(allConnect),		m_strHit("\r\nResp: ")	{	}	boost::asio::ip::tcp::socket& GetSocket(void)	{		return m_Socket;	}	//发送的消息。	void PushMsg(const std::string& strMsg)	{		m_QueueMsg.push_back(strMsg);		//		std::vector< boost::asio::const_buffer > vSendBuf;		vSendBuf.push_back(boost::asio::buffer(m_strHit));		if (!m_QueueMsg.empty())		{			vSendBuf.push_back(boost::asio::buffer(m_QueueMsg.front()));		}		boost::asio::async_write(m_Socket,			vSendBuf,			boost::bind(&CConnect::HandleWrite, shared_from_this(),			boost::asio::placeholders::error));	}	void Start(void)	{		//添加管理连接集合。		m_rAllConnect.Add(shared_from_this());		m_Socket.async_read_some(boost::asio::buffer(m_chBuffer, MAX_BUFSIZE),			boost::bind(&CConnect::HandleRead, shared_from_this(),			boost::asio::placeholders::error,			boost::asio::placeholders::bytes_transferred));	}	void HandleRead(const boost::system::error_code& error,		size_t bytes_transferred)	{		if (!error)		{			std::vector< boost::asio::const_buffer > vSendBuf;			vSendBuf.push_back(boost::asio::buffer(m_strHit));									if (!m_QueueMsg.empty())			{				vSendBuf.push_back(boost::asio::buffer(m_QueueMsg.front()));			}			vSendBuf.push_back(boost::asio::buffer(m_chBuffer, bytes_transferred));			boost::asio::async_write(m_Socket,				vSendBuf,				boost::bind(&CConnect::HandleWrite, shared_from_this(),				boost::asio::placeholders::error));		}		else		{			//从连接集合里删除自己的连接。			m_rAllConnect.Delete(shared_from_this());		}	}	void HandleWrite(const boost::system::error_code& error)	{		if (!error)		{			if (!m_QueueMsg.empty())			{				m_QueueMsg.pop_front();			}			m_Socket.async_read_some(boost::asio::buffer(m_chBuffer, MAX_BUFSIZE),				boost::bind(&CConnect::HandleRead, shared_from_this(),				boost::asio::placeholders::error,				boost::asio::placeholders::bytes_transferred));		}		else		{			//从连接集合里删除自己的连接。			m_rAllConnect.Delete(shared_from_this());		}	}private:	//	boost::asio::ip::tcp::socket m_Socket;	//	boost::array
m_chBuffer; std::string m_strHit; std::deque< std::string > m_QueueMsg; //保存所有连接集合。 CAllConnect& m_rAllConnect;};//服务器,主要接收新连接,并启动新连接接收数据。//软件开发人员: 蔡军生 2013-07-28class CServer{public: //构造函数,主要提供IO服务和端口。 CServer(boost::asio::io_service& ioService, short sPort) :m_ioService(ioService), m_acceptor(ioService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), sPort)) { //创建一个新连接,用来接收连接进来的客户端表示。 boost::shared_ptr< CConnect > pConnect(new CConnect(m_ioService, m_allConnect)); //做连接准备。 m_acceptor.async_accept(pConnect->GetSocket(), boost::bind(&CServer::HandleAccept, this, pConnect, boost::asio::placeholders::error)); } //收到客户端连接进来事件响应。 void HandleAccept(boost::shared_ptr< CConnect > pNewConnect, const boost::system::error_code& error) { if (!error) { //在这里可以通知别的连接有新连接进来。 std::set< boost::shared_ptr< CConnect > >& rAll = m_allConnect.GetAllConnect(); std::for_each(rAll.begin(), rAll.end(), [&](boost::shared_ptr< CConnect > pOther) { pOther->PushMsg("Hello!"); }); //如果没有错误,对连接进来的连接收发数据。 pNewConnect->Start(); //创建新的连接,以备下一个客户端连接进来。 pNewConnect.reset(new CConnect(m_ioService, m_allConnect)); //做连接准备。 m_acceptor.async_accept(pNewConnect->GetSocket(), boost::bind(&CServer::HandleAccept, this, pNewConnect, boost::asio::placeholders::error)); } }private: //IO服务 boost::asio::io_service& m_ioService; //接收器,用来接收新连接进来。 boost::asio::ip::tcp::acceptor m_acceptor; //管理所有连接。 CAllConnect m_allConnect;};//int _tmain(int argc, _TCHAR* argv[]){ //创建一个IO服务 boost::asio::io_service ioService; //创建服务器,端口为9001。 CServer server(ioService, 9001); //响应IO服务 ioService.run(); return 0;}

 

在类CServer里的函数HandleAccept通知所有其它连接一个消息,如下代码:

std::set< boost::shared_ptr< CConnect > >& rAll =m_allConnect.GetAllConnect();

         std::for_each(rAll.begin(),rAll.end(),

             [&](boost::shared_ptr<CConnect > pOther)

             {

                 pOther->PushMsg("Hello!");

         });

这里使用了一个C11的特性lambda表达式,达到最清楚化的表示。

然后在类CConnect里函数Start里调用管理类添加的函数,在函数HandleRead和HandleWrite调用删除的函数,这样就达到连接在管理类里添加和删除的响应。通过这样一个集合,就可以管理所有连接,跟所有连接进行通讯,或者删除某一个连接。

转载地址:http://naanl.baihongyu.com/

你可能感兴趣的文章
JS闭包导致循环给按钮添加事件时总是执行最后一个
查看>>
ECharts - 图表
查看>>
Java学习lesson 04
查看>>
解决“无法解析的外部符号 __imp___CrtDbgReportW”
查看>>
国内BIM案例VS国外BIM案例
查看>>
nmap
查看>>
JAVA的内存模型及结构
查看>>
外行人都能看得懂的Spring Cloud服务注册与发现,错过了血亏!
查看>>
浅析修理厂的5s管理内容及效用
查看>>
第12课《停电》
查看>>
HTML5开发从入门到精通学习路线图
查看>>
Python人工智能开发容易学吗
查看>>
讲解变频电源的工作原理图
查看>>
Git 少用 Pull 多用 Fetch 和 Merge
查看>>
我体验过的可以用的XCode插件
查看>>
android studio2 安装乱码,error
查看>>
Spring源码-IOC容器(七)-ApplicationContext
查看>>
Java网络编程基础(六)— 基于TCP的NIO简单聊天系统
查看>>
ThinkPHP模板中使用<volist>嵌套超过三层时出错-解决方法
查看>>
网络技术温故知新(二)
查看>>