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

一、服务器端源代码

5. Server.cpp  (侦听端口,接收连接,创建新CCnection)

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

using namespace std;

CServer * CServer::sm_instance=NULL;

CServer * CServer::Instance()
{
    if(sm_instance==NULL)
        sm_instance=new CServer;
    return sm_instance;
}

CServer::CServer()
	: m_acceptor(CIoServiceManager::Instance()->GetIoService())
	, m_timer(CIoServiceManager::Instance()->GetIoService())
{
}

void CServer::Start(unsigned port)
{
	cout<<"CServer::Start port="<<port<<endl;
	//boost::asio::ip::tcp::resolver resolver(m_acceptor.io_service());
	//boost::asio::ip::tcp::resolver::query query(address, port);
	//boost::asio::ip::tcp::endpoint endp = *resolver.resolve(query);
	boost::asio::ip::tcp::endpoint endp(boost::asio::ip::tcp::v4(), port);
	m_acceptor.open(endp.protocol());
	m_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
	m_acceptor.bind(endp);
	m_acceptor.listen();
	Connection_ptr  newConnection(new CConnection(CIoServiceManager::Instance()->GetIoService()));
	m_acceptor.async_accept(newConnection->Socket(),
		boost::bind(&CServer::handleAccept, this, newConnection, boost::asio::placeholders::error));
		
	m_timer.expires_from_now(boost::posix_time::seconds(15));
	m_timer.async_wait(boost::bind(&CServer::doHeartBeat, this));
}

void CServer::Stop()
{
	CIoServiceManager::Instance()->Stop();
}

void CServer::handleAccept(Connection_ptr pConn, const boost::system::error_code& er)
{
	cout<<"CServer::handleAccept()"<<endl;
	if (!er)
	{
		pConn->Start();
		Connection_ptr newConnection (new CConnection(CIoServiceManager::Instance()->GetIoService()));
		m_acceptor.async_accept(newConnection->Socket(),
			boost::bind(&CServer::handleAccept, this, newConnection, boost::asio::placeholders::error));
	}
	else
	{
		std::cout << "handleAccept Error: " << er.message() << "\n";
	}
}

void CServer::doHeartBeat()
{
	//cout<<"CServer::doHeartBeat()"<<endl;
	std::map<std::string,Connection_ptr> mapConns = CConnetionManager::Instance()->GetConnectionsMap();
	std::map<std::string,Connection_ptr>::iterator iter = mapConns.begin();
	for(; iter!=mapConns.end(); ++iter)
	{
		boost::asio::async_write(iter->second->Socket(), boost::asio::buffer("test"),
			boost::bind(&CServer::handleHeartBeat, this, boost::asio::placeholders::error, iter->first));
	}
	m_timer.expires_from_now(boost::posix_time::seconds(15));
	m_timer.async_wait(boost::bind(&CServer::doHeartBeat, this));
}

void CServer::handleHeartBeat(const boost::system::error_code& er, const string& userName)
{	
	//cout<<"CServer::handleHeartBeat()"<<endl;
	if(er)
	{
		std::cout << "handleHeartBeat Error: " << er.message() << "\n";
		CConnetionManager::Instance()->DelConnection(userName);
	}
}
6. RequestHandler.cpp (对消息内容处理)

#include "RequestHandler.h"
#include <iostream>

using namespace std;


MSG_TYPE CRequestHandler::ParseMsg(const char* data, int size)
{
	cout<<"CRequestHandler::ParseMsg()"<<endl;
	int i = 0;
	for(; i<size; i++)
	{
		if(' '==data[i])
			break;
	}
	string str(data, 0, i);
	if(str.substr(0,3)=="to:" || str.substr(0,3)=="TO:" || str.substr(0,3)=="To:")
	{
		return Send_Msg;
	}
	else if(str.substr(0,5)=="User:" || str.substr(0,5)=="user:" || str.substr(0,5)=="USER:")
	{
		return Register_Msg;
	}
	else
	{
		return Wrong_Msg;
	}
}

string CRequestHandler::GetRegisterName(const char* data, int size)
{
	cout<<"CRequestHandler::GetRegisterName()"<<endl;
	int i = 0;
	for(; i<size; i++)
	{
		if(data[i]==' ')
			break;
	}
	string str(data, 0, i);
	return str.substr(5);
}
	
string CRequestHandler::GetToUserName(const char* data, int size)
{
	cout<<"CRequestHandler::GetToUserName()"<<endl;
	int i = 0;
	for(; i<size; i++)
	{
		if(data[i]==' ')
			break;
	}
	string str(data, 0, i);
	return str.substr(3);
}

string CRequestHandler::GetMsgContent(const char* data, int size)
{
	cout<<"CRequestHandler::GetMsgContent()"<<endl;
	int i = 0;
	for(; i<size; i++)
	{
		if(data[i]==' ')
			break;
	}
	string temp(data, size);
	return temp.substr(i);
}
7. ChatServer.cpp(main函数)

#include "Server.h"
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void run()
{
	sigset_t new_mask;
	sigfillset(&new_mask);
	sigset_t old_mask;
	pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
	
	CIoServiceManager::Instance()->Start(2);
	CServer::Instance()->Start(9494);

	pthread_sigmask(SIG_SETMASK, &old_mask, 0);
	while (1)
	{
		sleep(1000);
	}
}

int main(int argc, char* argv[])
{
	pid_t chId, rebornId;
	chId = fork();

	if (chId == 0)
	{
		run();
		exit(0);
	}

	while (1)
	{
	    rebornId = wait(NULL);

        sleep(1);
        if(chId == rebornId)
        {
            chId = fork();
            if (chId == 0)
		    {
				run();
			    exit(0);
		    }
        }
		
	}
}

待续...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的使用 boost::asio 库编服务器示例: ```c++ #include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using namespace boost::asio::ip; class Session : public std::enable_shared_from_this<Session> { public: Session(tcp::socket socket) : socket_(std::move(socket)) {} void start() { do_read(); } private: void do_read() { auto self(shared_from_this()); socket_.async_read_some(buffer(data_, max_length), [this, self](boost::system::error_code ec, std::size_t length) { if (!ec) { do_write(length); } }); } void do_write(std::size_t length) { auto self(shared_from_this()); async_write(socket_, buffer(data_, length), [this, self](boost::system::error_code ec, std::size_t /*length*/) { if (!ec) { do_read(); } }); } tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length]; }; class Server { public: Server(io_service& ios, short port) : acceptor_(ios, tcp::endpoint(tcp::v4(), port)), socket_(ios) { do_accept(); } private: void do_accept() { acceptor_.async_accept(socket_, [this](boost::system::error_code ec) { if (!ec) { std::make_shared<Session>(std::move(socket_))->start(); } do_accept(); }); } tcp::acceptor acceptor_; tcp::socket socket_; }; int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: server <port>" << std::endl; return 1; } io_service ios; Server s(ios, std::atoi(argv[1])); ios.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` 这个服务器使用了 boost::asio 库提供的异步 I/O 操作实现,它只会在有客户端连接时才会创建一个新的 Session 对象处理该客户端的请求,这样可以避免阻塞主线程。在 Session 对象中,我们使用了 async_read_some 和 async_write 这两个异步操作来处理客户端的读请求,这样可以保证多个客户端之间互不干扰。最后,在 main 函数中,我们启动了一个 Server 对象,并调用了 io_service 的 run 方法来启动事件循环。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值