ACE Reactor框架使用实例-大量代码

本文档介绍了使用ACE Reactor框架实现的服务端功能,包括保存客户端信息、分配端口、处理客户端掉线以及数据收发等。通过CServerService类的各个成员函数展示了如何处理UDP数据、定时器操作、客户端状态管理和端口分配等关键步骤。此外,还涉及到心跳检测、客户端连接申请、心跳消息处理和消息群发等细节。
摘要由CSDN通过智能技术生成

服务端:
功能:保存所有客户端信息和在线状态,统一分配端口.对掉线的客户端信息通知到进程控制模块
ServerService.h

 

#ifndef _SERVERSERVICE_H_
#define _SERVERSERVICE_H_
#include <map>
#include <string>
#include <sstream>
#include <fstream>
#include "ace/TP_Reactor.h"
#include "ace/SOCK_Dgram.h"
#include "ace/Task.h"
namespace YB
{
const static ACE_UINT32 iLocalHostPort = 8001;
typedef unsigned  char BYTE;
static ACE_Thread_Mutex slock;
typedef struct STAPPID_
{
std::string  sIp;               // 客户端IP
int    iPort;               // 客户端连接到服务端的端口
int    ClientAcceptPort;            // 服务端分配的客户端监听端口
BYTE   byAppid;              // 模块标识
BYTE         byGroup;              // 组号
int          iTime;               // 时计器,维护客户端在线状态
bool   bOnline;              // 在线状态
}STAppid;
/*
服务端UDP数据收发
*/
class CMain;
class CServerService: public ACE_Event_Handler
{
public:
// 构造、析构函数
CServerService();
~CServerService();
virtual ACE_HANDLE get_handle(void) const;         // 继承基类
virtual int  handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE);    // 有网络数据到达
virtual int  handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask); // 关闭网络监听

bool Open(CMain* cm);
void SendToAll(char* buf, int nSize);         // 消息群发
int  DeleteAppid(BYTE byappid, std::string sip);       // 删除指定客户端信息
bool ReadServerIP();              // 读配置IP
private:
void UpdateClientAllSatte(STAppid stAppid, ACE_INET_Addr taddr);   // 更新客户端状态
void UpdateState(YB::BYTE byappid);          // 客户端在线
void MsgData(YB::BYTE byappid);           // 消息报文
void ChackProtocol(const char* buf, const int nSize);     // 解析报文
void ApplyConn(const char *buf, const int nSize);      // 应答客户申请连接
void AllotPort(unsigned short &uiPort);         // 检查分配客户端端口是否重复,并分配新的
BYTE checkFrame(unsigned char* uc_buf, unsigned short uc_length);  // 帧校验
void fixFrame(unsigned char* uc_buf, unsigned char& uc_Length,   // 组帧
      unsigned char flag, unsigned char dest_addr, unsigned char src_addr);
    void    CheckAppid(BYTE byappid,std::string sIp);
public:
std::map<BYTE, STAppid> mpInfo;            // 注册客户端信息表
private:
ACE_INET_Addr addr;
ACE_SOCK_Dgram udp;
std::string  sServerIP;
unsigned short usiPort;             // 分配客户端端口值
STAppid   stAppid;
int    iPortCount;
CMain*   cmn;
};

// 定时器类,监视在线客户端,
class CTaskTimer : public ACE_Task_Base
{
public:
// 构造、析构函数
CTaskTimer(){timeid = 0;};
virtual ~CTaskTimer(){};
virtual int  handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask); // 关闭网络监听
public:
bool Open(CServerService *udp);
int  handle_timeout(const ACE_Time_Value &current_time, const void *act = 0);// 定时器,清理掉线客户端

private:
CServerService *sudp;
long   timeid;
};
// 主调类,负责启动定时器和网络监听
class CMain : public ACE_Task_Base
{
public:
// 构造、析构函数
CMain(){};
~CMain(){};
public:
bool Open();
int  Close();
private:
CServerService *serudp;
CTaskTimer  *taskTimer;
};
}
#endif  // end of _SERVERSERVICE_H_

 

 

ServerService.cpp
#include "./ServerService.h"
using namespace YB;
bool CMain::Open()
{
ACE_NEW_RETURN(serudp, CServerService, false);
ACE_NEW_RETURN(taskTimer, CTaskTimer, false);
serudp->reactor(ACE_Reactor::instance());
if (!serudp->Open(this)) return false;
taskTimer->reactor(ACE_Reactor::instance());
if (!taskTimer->Open(serudp)) return false;
ACE_OS::sleep(ACE_Time_Value(0, 10000));   // 等待10毫秒   
ACE_Reactor::instance()->run_reactor_event_loop(); // 启动线程
return true;
}
int CMain::Close()
{
taskTimer->handle_close(ACE_INVALID_HANDLE, 0);
serudp->handle_close(ACE_INVALID_HANDLE, 0);
if (ACE_Reactor::instance()->reactor_event_loop_done() != 1)
{
  ACE_Reactor::instance()->end_reactor_event_loop();
}
return 0;
}  
///
CServerService::CServerService()
{
usiPort = 20000;   // 初使分配客户端端口值
iPortCount = 0;
}
CServerService::~CServerService()
{
}
bool CServerService::ReadServerIP()
{
std::ifstream fle("ServerIp.txt", std::ios::in);
if (!fle) return false;

std::ostringstream seamServerIP;
seamServerIP<<fle.rdbuf();
sServerIP = seamServerIP.str();
fle.close();
return true;
}
bool CServerService::Open(CMain* cm)
{
if (!ReadServerIP()) return false;
this->addr.set(iLocalHostPort, sServerIP.c_str());//, ACE_LOCALHOST
this->udp.open(addr);
this->reactor()->register_handler(this, ACE_Event_Handler::READ_MASK);
cmn = cm;
return true;
}
ACE_HANDLE CServerService::get_handle() const
{
return this->udp.get_handle();
}
int  CServerService::handle_input(ACE_HANDLE)
{
ACE_INET_Addr taddr;
char   buf[255] = {0};
int    isize = 0;
isize = this->udp.recv(buf, 255, taddr);
stAppid.iPort = taddr.get_port_number();
stAppid.sIp = taddr.get_host_addr();

if (isize > 0 && isize < 255) ChackProtocol(buf, isize);
return 0;
}
int  CServerService::handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
{
if (this->udp.get_handle() != ACE_INVALID_HANDLE)
{
  ACE_Reactor_Mask m = ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL;
  this->reactor()->remove_handler(this, m);
  this->udp.close();  
}
delete this;
return 0;
}
unsigned char CServerService::checkFrame(unsigned char* uc_buf, unsigned short uc_length)            
{
//检查报文
return 1;
}
void CServerService::fixFrame( unsigned char* uc_buf,
        unsigned char& uc_Length,
        unsigned char flag,
        unsigned char dest_addr,
        unsigned char src_addr)
{
//组装报文
return ;
}
void CServerService::ChackProtocol(const char* buf, const int nSize)
{
YB::BYTE *p = (YB::BYTE*)buf;

if (checkFrame(p, nSize)) return;
switch (*(p + 11))
{
  case 0x00:  // 心跳
  {
   
   UpdateState(*(p + 6));
   if (*(p + 2) == 0x02) MsgData(*(p + 6));
   break;
   
  }   
  case 0x01:  // 我要处理的类型
  {
   switch (*(p + 15))
   {
    case 0x00:  // 正常退出,离线状态
    {
     DeleteAppid(*(p + 23), stAppid.sIp);
     break;
    }
    case 0x02: // 申请连接
    {
     ApplyConn(buf, nSize);
     break;
    }
    default:
     break;
   }
   break;
  }
  case 0x02: // 退出
  {
   if (*(p + 15) == 0x04 && *(p + 6) == 0x01) cmn->Close();
   break;
  }
  default:
   break;  
}
}
void CServerService::ApplyConn(const char *buf, const int nSize)
{

ACE_INET_Addr taddr;
YB::BYTE isize = 0x0C;
char  puf[255] = {0};
char *p = (char*)buf;  
AllotPort(usiPort);
stAppid.ClientAcceptPort = usiPort;
stAppid.byAppid = *(p + 6);
stAppid.byGroup = *(p + 16);
CheckAppid( stAppid.byAppid,stAppid.sIp.c_str() );
taddr.set(usiPort, stAppid.sIp.c_str());
ACE_UINT32 ip = taddr.get_ip_address();
u_short  iprt = taddr.get_port_number();
/*组帧
strcpy(puf, "/x01/x01/x01/x0C/x03");
puf[5] = stAppid.byGroup;
memcpy(puf + 6, &ip, sizeof(ACE_UINT32));
memcpy(puf + 6 + sizeof(ACE_UINT32), &iprt, sizeof(u_short));
fixFrame((unsigned char*)puf, isize, 0x01, stAppid.byAppid, 0x04);
taddr.set(stAppid.iPort, stAppid.sIp.c_str());
*/
this->udp.send(puf, isize, taddr);
/*
// 向其他客户端更新信息
isize = 0x0D;
memset(puf, 0x00, 255);
strcpy(puf, "/x01/x01/x01/x0D/x01");
puf[5] = stAppid.byGroup;
memcpy(puf + 6, &ip, sizeof(ACE_UINT32));
memcpy(puf + 6 + sizeof(ACE_UINT32), &iprt, sizeof(u_short));
memcpy(puf + 6 + sizeof(ACE_UINT32) + sizeof(u_

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值