频道栏目
读书频道 > 其他 > ACE技术内幕:深入解析ACE架构设计与实现原理
2.3.2 Accept事件处理器的实现
2012-08-16 20:39:30     我来说两句
收藏   我要投稿
本书从构架模式、编程示例和源代码3个维度系统地对经典网络框架ACE(Adaptive Communication Environment)的架构设计和实现原理进行了深入分析,它能解决4个方面的问题:第一,帮助框架设计者领略软件框架设...  立即去当当网订购
示例中服务端的Accept事件由Acceptor类来完成。Acceptor类也是一个事件处理器,用于处理客户端的连接事件,同时它还是一个工厂,一旦客户端连接成功,就创建Handle_data对象,由该对象来处理客户端的数据。Acceptor类如代码清单2-5所示。 
代码清单2-5   Acceptor类 
-----------------------------------------------------acceptor.h 
class Acceptor: public ACE_Event_Handler 

  public: 
    Acceptor( ACE_Reactor *r=ACE_Reactor::instance() ):ACE_Event_Handler(r){} 
 
    ACE_INT32 open( const ACE_UINT16 port );    
    ACE_INT32 handle_input( ACE_HANDLE = ACE_INVALID_HANDLE ); 
    ACE_INT32 handle_close( ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = 0 ); 
    ACE_HANDLE get_handle() const 
    { 
      return acceptor_.get_handle(); 
    } 
    ACE_SOCK_Acceptor &get_acceptor(){ return acceptor_; } 
  private: 
    ~Acceptor(){}; 
  private: 
    ACE_SOCK_Acceptor  acceptor_;   
}; 
---------------------------------------------------  acceptor.h 
Acceptor类的成员函数和Handle_data类的成员函数相似,其中handle_input函数用于处理客户端的连接事件,handle_close函数用于隐式关闭。ACE_SOCK_Acceptor对象用于接收客户端的连接,读者可以参考第1章的分析。 
1. open函数 
open函数是Acceptor对象的初始化函数,它负责创建Socket,以及将Socket的连接事件注册到框架中,如代码清单2-6所示。 
代码清单2-6   Acceptor对象的open函数 
-------------------------------------------------  acceptor.cpp 
ACE_INT32 Acceptor::open( ACE_UINT16 port ) 

 
ACE_INET_Addr  addr; 
//初始化addr,侦听的端口由port设定,IP地址任意 
addr.set( port, (ACE_UINT32)INADDR_ANY ); 
//调用ACE_SOCK_Acceptor对象的open函数,建立侦听Socket 
//如果操作失败,返回-1。关于open函数,读者可以参考第1章的分析 
 if (acceptor_.open( addr ) == -1) 
 { 
  ACE_DEBUG( (LM_DEBUG, "accept open error\n") ); 
  return -1; 

//调用Reactor管理器的register_handler函数,将自身注册到Reactor框架中 
return reactor()->register_handler( this, ACE_Event_Handler::ACCEPT_MASK );  

-------------------------------------------------  acceptor.cpp 
open函数使用ACE_SOCK_Acceptor对象完成Socket的建立,调用register_handler函数将事件处理器注册到框架中。Acceptor事件处理器与Handle_data事件处理器的区别在于:Acceptor事件处理器注册的事件的类型是ACE_Event_Handler::ACCEPT_MASK,原因很明显,Acceptor事件处理器接收的事件是Socket连接事件。 
2. handle_input函数 
如果客户端连接事件到来,Reactor管理器将会调度该事件。调用handle_input函数处理该事件,处理过程如代码清单2-7所示。 
代码清单2-7   Acceptor事件处理器的handle_input函数 
-------------------------------------------------  acceptor.cpp 
ACE_INT32 Acceptor::handle_input( ACE_HANDLE handle ) 

/*调用ACE_NEW_RETURN宏创建Handle_data对象。一个新的连接已经建立,需要创建一个事件处理器来 
处理该连接上的I/O操作*/ 
  Handle_data  *handle_data = 0; 
  ACE_NEW_RETURN( handle_data, Handle_data( reactor() ),-1); 
  // ACE_NEW_RETURN是ACE使用的内存申请宏。通过ACE_SOCK_Acceptor的accept调用接收客户端 
  连接,accept函数会将新的Socket描述符保存在handle_data对象的peer_数据成员中,参见代码清 
  单2-1。如果调用失败,那么释放handle_data,然后返回-1*/ 
  if (acceptor_.accept( handle_data->get_peer() ) == -1) 
  { 
  ACE_DEBUG( (LM_DEBUG, "accept handle input accept error!\n") ); 
  handle_data->handle_close(); 
  return -1; 

/*调用open函数初始化handle_data,参见代码清单2-2。如果初始化失败,那么调用handle_close函 
数执行关闭操作,返回-1*/ 
else if (handle_data->open() == -1) 

  ACE_DEBUG( (LM_DEBUG, "accept handle input open error!\n") ); 
  handle_data->handle_close(); 
  return -1; 

else 

  ACE_DEBUG( (LM_DEBUG, "accept handle input ok!\n") ); 
    return 0; 
  }  

-------------------------------------------------  acceptor.cpp 
我们先来分析handle_input函数在框架中被调用的场景。在代码清单2-6所示的open函数中,我们建立了一个侦听的Socket,同时将Acceptor事件处理器注册到了框架中,让其接受框架的调度。如果系统接收到一个客户端的连接请求,框架会先调用分离函数(本书使用select函数作为分析对象)分离该事件,然后根据事件的描述符找到Acceptor事件处理器,最后进入handle_input处理函数。 
接下来我们来看handle_input函数的处理过程。既然已经接收到新的客户端的连接,就需要创建一个新的Handle_data事件处理器,这就是我们称Acceptor事件处理器是一个工厂的原因。Handle_data事件处理器必须要有自己的描述符,所以调用ACE_SOCK_Acceptor对象的accept函数来获取新的Socket描述符。最后调用Handle_data事件处理器的open函数,将新的Handle_data事件处理器注册到框架中。自此,Handle_data事件处理器和Acceptor事件处理器将分道扬镳,它们有自己的描述符、事件处理器,都可作为独立的对象接受框架的调度。 
3. handle_close函数 
handle_close函数用于事件处理器的关闭操作。先是关闭ACE_SOCK_Acceptor对象,然后释放事件处理器,如代码清单2-8所示。 
代码清单2-8   Acceptor事件处理器的handle_close函数 
-------------------------------------------------  acceptor.cpp 
ACE_INT32 Acceptor::handle_close( ACE_HANDLE handle, 
  ACE_Reactor_Mask mask ) 

  acceptor_.close();   //关闭侦听的Socket 
  delete this;         //释放事件处理器对象 
  ACE_DEBUG( (LM_DEBUG, "accept handle close ok!\n") ); 
  return 0;   

-------------------------------------------------  acceptor.cpp 
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:2.3.1 I/O事件处理器的实现
下一篇:2.3.3 main函数
相关文章
图文推荐
排行
热门
最新书评
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站