利用boost:asio写的简单聊天服务器二

一、服务器端源代码

3. Connection.cpp  (每个客户端连接分别对应一个CConnection对象)

#include "Connection.h"
#include "ConnectionManager.h"
#include <iostream>
#include <vector>
#include <boost/bind.hpp>

using namespace std; 

CConnection::CConnection(boost::asio::io_service& io_service)
	: m_socket(io_service)
{
}

boost::asio::ip::tcp::socket& CConnection::Socket()
{
	return m_socket;
}

void CConnection::Start()
{
	cout<<"CConnection::Start() user:"<<m_registerName<<endl;
	m_socket.async_read_some(boost::asio::buffer(m_buffer),
		boost::bind(&CConnection::handleRead, shared_from_this(),
			boost::asio::placeholders::error,
			boost::asio::placeholders::bytes_transferred));
}

void CConnection::handleRead(const boost::system::error_code& e, size_t bytes_transferred)
{
	cout<<"CConnection::handleRead() user:"<<m_registerName<<endl;
	if (!e)
	{
		MSG_TYPE type = m_reqHandler.ParseMsg(m_buffer.data(), bytes_transferred);
		if(Register_Msg == type)
		{
			string strName = m_reqHandler.GetRegisterName(m_buffer.data(), bytes_transferred);
			bool b = addConnetion(strName, shared_from_this());
			if(b)
			{	
				m_registerName = strName;
				handleRegisterSuccess();
			}
			else
			{
				handleRegisterError();
			}			
		}
		else if(Send_Msg == type)
		{
			string toName = m_reqHandler.GetToUserName(m_buffer.data(), bytes_transferred);
			handleSendMsg(m_registerName, toName, bytes_transferred);
		}
		else
		{
			handleWrongMsg();
		}
	}
	else
	{
		cout << "handleRead Error: " << e.message() << "\n";
	}
}

bool CConnection::addConnetion(const string& strUserName, Connection_ptr ptrConn)
{
	cout<<"CConnection::addConnetion() user:"<<m_registerName<<endl;
	return CConnetionManager::Instance()->AddConnection(strUserName, ptrConn);
}

void CConnection::handleRegisterSuccess()
{
	cout<<"CConnection::handleRegisterSuccess() user:"<<m_registerName<<endl;
	string strData("Register Success! \nAll users are: ");
	set<string> mUsers;
	CConnetionManager::Instance()->GetClientList(mUsers);
	set<string>::iterator iter = mUsers.begin();
	for(; iter!=mUsers.end(); ++iter)
	{
		strData.append(*iter);
		strData.append(" ");
	}
	cout<<"handleRegisterSuccess::strData="<<strData<<endl;
	boost::asio::async_write(m_socket, boost::asio::buffer(strData),
        boost::bind(&CConnection::handleWrite, shared_from_this(), boost::asio::placeholders::error));
}

void CConnection::handleRegisterError()
{
	cout<<"CConnection::handleRegisterError() user:"<<m_registerName<<endl;
	string strData("Register Error! Maybe there is a same username,input new one pls.\n ");
	boost::asio::async_write(m_socket,boost::asio::buffer(strData), 
		boost::bind(&CConnection::handleWrite, shared_from_this(), boost::asio::placeholders::error));
}

void CConnection::handleSendMsg(const string& strFromUser, const string& strToUser, size_t dataSize)
{
	cout<<"CConnection::handleSendMsg() user:"<<m_registerName<<endl;
	string strData("From:");
	strData.append(strFromUser);
	strData.append(m_reqHandler.GetMsgContent(m_buffer.data(), dataSize));
	cout<<"handleSendMsg::strData="<<strData<<endl;
	if(strcmp(strToUser.c_str(),"all"))
	{
		CConnetionManager::Instance()->GetConnection(strToUser)->sendMsg(strData);
	}
	else
	{
		std::map<std::string,Connection_ptr>& mapConn = CConnetionManager::Instance()->GetConnectionsMap();
		std::map<std::string,Connection_ptr>::iterator iter = mapConn.begin();
		for(; iter!=mapConn.end(); ++iter)
		{
			if(iter->first == strFromUser)
				continue;
			iter->second->sendMsg(strData);
		}
	}
	boost::system::error_code err;
	handleWrite(err);
}

void CConnection::handleWrongMsg()
{
	cout<<"CConnection::handleWrongMsg() user:"<<m_registerName<<endl;
	string strData("The input format error! Again pls.\n ");

	boost::asio::async_write(m_socket,boost::asio::buffer(strData), 
		boost::bind(&CConnection::handleWrite, shared_from_this(), boost::asio::placeholders::error));
}

void CConnection::handleWrite(const boost::system::error_code& e)
{
	cout<<"CConnection::handleWrite() user:"<<m_registerName<<endl;
	bufferClear();
	if (!e)
	{		
		m_socket.async_read_some(boost::asio::buffer(m_buffer),
			boost::bind(&CConnection::handleRead, shared_from_this(),
				boost::asio::placeholders::error,
				boost::asio::placeholders::bytes_transferred));
	}
	else
	{
		cout << "handleWrite Error: " << e.message() << "\n";
		m_socket.close();
	}
}

void CConnection::bufferClear()
{
	cout<<"CConnection::bufferClear() user:"<<m_registerName<<endl;
	int size = m_buffer.size();
	if(size != 0)
	{
		for(int i=0; i<size; i++)
		{
			m_buffer[i] = '\0';
		}
	}
}

void CConnection::sendMsg(const string &strData)
{
	cout<<"CConnection::sendMsg() user:"<<m_registerName<<endl;

	boost::asio::async_write(m_socket,boost::asio::buffer(strData), 
		boost::bind(&CConnection::handleWrite, shared_from_this(), boost::asio::placeholders::error));
}
4. ConnectionManager.cpp (对每个连接的管理)
#include "ConnectionManager.h"
#include <iostream>

using namespace std;

CConnetionManager * CConnetionManager::sm_pInstance=NULL;

CConnetionManager * CConnetionManager::Instance()
{
    if(sm_pInstance==NULL)
    {
        sm_pInstance=new CConnetionManager;
    }
    return sm_pInstance;
}

CConnetionManager::CConnetionManager()
{
}

bool CConnetionManager::AddConnection(const std::string& strUserName, Connection_ptr ptrConn)
{
	cout<<"CConnetionManager::AddConnection() , strUserName="<<strUserName<<endl;
    boost::lock_guard<boost::mutex> guard(m_mut);
	if(m_mapConns.find(strUserName)==m_mapConns.end())
	{
		m_mapConns[strUserName]=ptrConn;
		return true;
	}
	return false;
}

Connection_ptr CConnetionManager::GetConnection(const std::string& strUserName)
{
	cout<<"CConnetionManager::GetConnection() , strUserName="<<strUserName<<endl;
    Connection_ptr ptrConn;
    boost::lock_guard<boost::mutex> guard(m_mut);
    map<string,Connection_ptr>::iterator itr=m_mapConns.find(strUserName);
    if(itr!=m_mapConns.end())
    {
        ptrConn=itr->second;
    }
    return ptrConn;
}

void CConnetionManager::GetClientList(std::set<string>& userNames)
{
	cout<<"CConnetionManager::GetClientList()"<<endl;
	boost::lock_guard<boost::mutex> guard(m_mut);
	map<string,Connection_ptr>::iterator iter = m_mapConns.begin();
	for(; iter!=m_mapConns.end(); ++iter)
	{
		userNames.insert(iter->first);
	}
}

std::map<std::string,Connection_ptr>& CConnetionManager::GetConnectionsMap()
{
	boost::lock_guard<boost::mutex> guard(m_mut);
	return m_mapConns;
}

void CConnetionManager::DelConnection(const std::string& strUserName)
{   
	cout<<"CConnetionManager::DelConnection()"<<endl;
    boost::lock_guard<boost::mutex> guard(m_mut);
	map<string,Connection_ptr>::iterator itr=m_mapConns.find(strUserName);
    if(itr!=m_mapConns.end())
    {
        m_mapConns.erase(itr);
    }
}

CConnetionManager::~CConnetionManager()
{
    while(!m_mapConns.empty())
    {
        m_mapConns.erase(m_mapConns.begin());
    }
}

待续...

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值