从一个以ACE框架为基础项目所学和不足(一)

最近工作中做了一个以ACE框架为基础的项目。所要做的功能很简单,就是服务器接收http报文请求,添加一些业务记录到数据库,然后设计一个定时器来轮训判断之前的业务记录是否发生状态变化,然后同步http请求方提供的数据库中业务记录的状态。从开发到测试一直问题不断,其中遇到和解决的问题,以及所思所感,在此记录一下。因此我不会讲具体技术,只讲我实践中遇到的问题和如何解决的。

一、ACE框架的学习
之前工作一直没有使用过这个框架。可以说一点都不熟悉,但是怎么办呢,项目以交到你的手上,硬着头皮看文档。

#include "ace/Svc_Handler.h"
#include "ace/SOCK_Stream.h"
#include "ace/SSL/SSL_SOCK_Stream.h"

class XXXManager: public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
{
public:
	typedef ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> inherited;

	XXXManager(void);
	~XXXManager(void);

	void destroy (void);
	int open (void *acceptor);
	int close (u_long flags = 0);

	virtual int handle_close (ACE_HANDLE handle = ACE_INVALID_HANDLE,
		ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK);
public:
	/*注册过的*/
	int handle_input (ACE_HANDLE handle);

	int process (char *rdbuf, int rdbuf_len);

	/**
	 * 定时器回调函数.
	 * 使用外部定时器时,注册这个回调函数即可
	 * @param lTimerID 定时器ID
	 * @param pPara1 NULL
	 * @param pPara2 unused
	 */
	static void TimerCallBack(long lTimerID, void* pPara1, void* pPara2);
private:
	int timer_strategy(int last_timer,int current_timer);

	/**
	 * 返回报文字符串函数
	 */
	std::string ResponseStr(int state);

	DBAccess* 	db_object_;
};

通常ACE框架首先需要我们自己定义一个事件类继承于ACE_Svc_Handler,用于处理socket流,说白了就是有没有网络通信。这里留心一下handle_input函数即可。其他函数都是为了这个具体的工程准备的。
接下来,还需要定义一个接收器类,这个也是ACE框架范畴的。ACE_Acceptor类模板第一个参数我们填之前写的类即可,第二个参数表示接收器接收的类型是socket事件。

#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SSL/SSL_SOCK_Acceptor.h"

typedef ACE_Acceptor <XXXManager, ACE_SOCK_ACCEPTOR> Client_Acceptor_Base;
class Client_Acceptor : public Client_Acceptor_Base
{
	//to do...
};

我们在大main函数里调用open函数将端口告诉reactor(ACE框架的调度器)。

	ACE_UINT16 g_usAgentSrvPort = 88; //监听88端口
	ACE_Reactor reactor;
	Client_Acceptor peer_acceptor;
	
	if (peer_acceptor.open (ACE_INET_Addr (g_usAgentSrvPort),
	                        &reactor, ACE_NONBLOCK) == -1)
	    ACE_ERROR_RETURN ((LM_ERROR,
		                   "%p\n",
		                   "open"),
		                  -1);

在我们定义的事件类的open函数中我们做一件事:就是向ACE框架注册我们的事件类句柄。这样当监听的端口有socket请求时,ACE框架会将这个事件调度到我们定义的事件类,并调用handle_input函数。我们对请求的所有处理就可以在这个函数中展开。

int
XXXManager::open (void *void_acceptor)
{
	ACE_INET_Addr addr;
	ACE_INET_Addr local;

	if (this->peer().get_remote_addr(addr) == -1)
		return -1;
	if (this->peer().get_local_addr(local) == -1)
		return -1;

	// 防止回环
	if (addr.get_ip_address() == local.get_ip_address())
	{
		if (g_debug)
			printf("local to local\n");
		return -1;
	}

	//创建接收器
	Client_Acceptor *acceptor = (Client_Acceptor *) void_acceptor;

	/*通过ACE传统的方式,监听的端口有请求时,会调用handle_input()*/
	this->reactor(acceptor->reactor());

	/*向ACE框架注册接收器*/
	if (this->reactor()->register_handler(this,
		ACE_Event_Handler::READ_MASK) == -1)
		ACE_ERROR_RETURN ((LM_ERROR,
		"(%P|%t) can't register with reactor\n"),
		-1);

	return 0;
}

可以在handle_input函数中调用peer().recv()函数来接收报文,也可以通过peer().send()函数来返回报文。

#define BUFSIZE 1024;

char buf[BUFSIZE];
ACE_Time_Value timeout(0,100000);

//接收报文
this->peer().recv(buf, sizeof (buf), &timeout);

//处理报文...

//返回报文
this->peer().send(ResponseStr(1).c_str(),ResponseStr(1).length(),&timeout);

最后我们在大main函数里这样,不断处理一次次的socket请求事件。

	while (true)
	{
		std::cout << "========wait request========" << std::endl;
		reactor.handle_events();
	}

以上这些都是ACE框架最基本的内容,万变不离其宗。但是对于一个从未接触过的人,了解各个函数功能,及相互耦合关系,还是需要花一些功夫的。
最后一个问题是,每次接收到一个符合我们定义的事件类的事件,ACE框架都会生成一个事件类对象,在调用完handle_input函数如果成功的话,返回值通常我们都认为应该是0。如果是0返回给上层,ACE框架不会释放对这个事件的处理,事件类对象还存在;而如果返回的是-1,框架则会中断对这个事件的处理,会析构掉事件类,从而等待新的请求到来。所以这里我在实践中return的是-1,而我最开始都是return的0。
我接手时遇到的问题就是,完全对框架没什么概念。花了好多功夫去熟悉。查看文档,请教别人。不懂得时候是真的着急。但了解了之后,后边再遇到的话就熟悉了。希望我这篇粗浅的文章,可以帮助到大家。
未完待续…

ACE网络框架-文档资料.rar】压缩包中含有如下内容: ================================================== 【ACE源码】目录: ACE+TAO+CIAO-6.0.0.tar.bz2 --------------------------------------------------------------------- 【ACE自适配通信环境中文技术文档】目录: ACE自适配通信环境(代序).pdf ACE自适配通信环境中文技术文档 [2002年12月版].chm 上篇:ACE技术论文集.pdf 中篇:ACE程序员教程.pdf 下篇:ACE应用实例.pdf --------------------------------------------------------------------- 【C++网络编程全集】目录: C++ Network Programming, Volume 1:Mastering Complexity with ACE and Patterns.chm C++ Network Programming, Volume 1:Mastering Complexity with ACE and Patterns.pdf C++ Network Programming, Volume 2:Systematic Reuse with ACE and Frameworks.chm C++NP_v1-P193.ppt C++NP_v2-P298.ppt C++NP_v2-P383.ppt C++网络编程 卷1:运用ACE和模式消除复杂性-P328.pdf C++网络编程 卷2:基于ACE框架的系统化复用-P374.pdf --------------------------------------------------------------------- 【其它资料】目录: ACE-tutorial [英文版]-P306.pdf ACE-类继承关系.pdf ACE详细介绍-译文.pdf C++网络编程学习笔记(ACE).docx --------------------------------------------------------------------- ACE技术内幕:深入解析ACE架构设计与实现原理 [机械工业.2012年出版.带书签]-P333.pdf --------------------------------------------------------------------- ACE程序员指南:网络与系统编程的实用设计模式 [中国电力.2005年出版.带书签]-P374.pdf ================================================= 附送视频学习资料:[看雪论坛独家免费共享]の轩辕IT培训 Linux C++ 远程全科班 Boost ACE[无KEY 完整版] 该视频是很好的网络框架学习资源,关于ACE框架的视频在Module6中,还有Boost相关的讲解。 下载地址:https://pan.baidu.com/s/1kTDYnjD 【注:可能会失效,赶紧存入网盘】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值