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

原创 2013年12月05日 14:40:31

一、服务器端源代码

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());
    }
}

待续...

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

boost asio异步读写网络聊天程序客户端 实例详解

boost开发文档中实时聊天程序的客户端(加入了详细注释 方便理解)

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

二、客户端源代码 1. ChatClient.cpp (客户端main) #include #include #include #include #include #include ...

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

一、服务器端源代码 5. Server.cpp  (侦听端口,接收连接,创建新CCnection) #include "Server.h" #include "ConnectionManager....

Muduo 网络编程示例之二:Boost.Asio 的聊天服务器

这是《Muduo 网络编程示例》系列的第二篇文章。 本文讲介绍一个与 Boost.Asio 的示例代码中的聊天服务器功能类似的网络服务程序,包括客户端与服务端的 muduo 实现。这个例子的主要目的是...

boost::asio学习之[六]简单聊天程序

#pragma once #include #include #include namespace ChatTest { class chat_message { public: e...

boost asio异步读写网络聊天室【官方示例】

// // chat_message.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (ch...

C++並發 練習筆記(二)使用boost Asio的async I/O技術實作簡易網路聊天室 (上)

這次代碼閱讀主要來自boost asio開發團隊 的C++11 標準範例。 範例連結 我會對我自己閱讀的部份加上註釋,並從中學習函數的意義及使用方式。 希望能給一同在學習路上的大家一些幫助。 如果對...

Boost.Asio学习之简单的HTTP服务器

Boost.asio实现简单的HTTP服务器

简单的Boost::asio 高性能C/S服务器模型

Boost::Asio 在底层封装的了操作系统的高效I/O模型。实现了很高的并发量和吞吐量。其中操作系统主要实现了两种I/O模型Reactor和Proactor。 接下来探讨一下两种I/O多路复用模...

使用Boost.Asio写的多线程TCP转发代理服务器

http://www.cppblog.com/archiveman/archive/2010/03/05/108971.html 应用场景是这样的: 客户端和服务器在不同的网段内,它们之间...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)