boost库在工作(36)网络服务端之六

在上面介绍了管理所有连接的类,这个类主要就是添加新的连接,或者删除不需要的连接。但是管理的类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<char, MAX_BUFSIZE> m_chBuffer;

	std::string m_strHit;

	std::deque< std::string > m_QueueMsg;

	//保存所有连接集合。

	CAllConnect& m_rAllConnect;

};



//服务器,主要接收新连接,并启动新连接接收数据。

//软件开发人员: 蔡军生  2013-07-28

class 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调用删除的函数,这样就达到连接在管理类里添加和删除的响应。通过这样一个集合,就可以管理所有连接,跟所有连接进行通讯,或者删除某一个连接。


你可能感兴趣的:(boost)