一、服务器端源代码
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);
}
}
}
}
待续...