大概看看的ACE

这是最近在学习ACE所记下的一点笔记,ACE十分庞大,传闻学之者生,用之者死,也说明坑多且繁杂。听前辈说在设计思路上无论是重量级还是如libevent这种轻量级的网络库,都是大同小异的,初学ACE首先要知道这些API。目前后台框架是在ACE框架之上的封装。

 

ACE源码约10万行,是c++中非常大的一个网络编程代码库,包含了网络编程的边边角角。

 

ACE代码可以分三个层次:OS层、OO层和框架层:

 

  • OS层主要是为了兼容各个平台,将网络底层API统一化,这一层用户不关心。
  • OO层则是对一些常用的数据结构或方法进行OO封装,方便上层使用,包括socket方法,进程、线程和他们的同步机制等。
  • 框架层实现了一些优秀的网络框架。

 

 

1.1 ACE_INET_Addr

类名

ACE_INET_Addr

所在文件

INET_Addr.h

功能

处理和存储IP、端口、协议类型的数据类,提供了一组操作这些数据的方法。

关键数据

/// Creates an ACE_INET_Addr from a @a port_number and ACE_INET_Addr (u_short port_number,

               constchar host_name[],

               int address_family = AF_UNSPEC);

 

  union

  {

    sockaddr_in  in4_;

#if defined (ACE_HAS_IPV6)

    sockaddr_in6 in6_;

#endif /* ACE_HAS_IPV6 */

  } inet_addr_;

在构造时入参端口和IP地址完成赋值。

#define LISTEN_PORT    5010

#define SERVER_IP      ACE_LOCALHOST

ACE_INET_Addr Server_Info(LISTEN_PORT,(char*)SERVER_IP);

 

1.2 ACE_SOCK_Acceptor

类名

ACE_SOCK_Acceptor

所在文件

SOCK_Acceptor.h

功能

接受器,被动建立连接,用于Socket Server。

关键数据

/**

* Initialize a passive-mode BSD-style acceptor socket (no QoS).

*/

int open (const ACE_Addr &local_sap,

        int reuse_addr =0,

        int protocol_family = PF_UNSPEC,

        int backlog = ACE_DEFAULT_BACKLOG,

        int protocol =0);

 

/**

* Accept a new ACE_SOCK_Stream connection.  A @a timeout of 0

*/

int accept (ACE_SOCK_Stream &new_stream,

          ACE_Addr *remote_addr =0,

          ACE_Time_Value *timeout =0,

          bool restart =true,

          bool reset_new_handle =false)const;

 

Open:创建socket,打开监听端口,绑定socket。完成socket、listen、bind操作。

代码行:141 - 146

this->set_handle (ACE_OS::socket(protocol_family,

                                type,

                                protocol,

                                protocolinfo,

                                g,

                                flags));

        

文件:SOCK_Acceptor.cpp

代码行:279 - 282

elseif(ACE_OS::bind(this->get_handle (),

                     (sockaddr *) local_sap.get_addr (),

                     local_sap.get_size ())==-1)

error =1;

 

文件:SOCK_Acceptor.cpp

代码行:284 - 291

if(error !=0

  || ACE_OS::listen(this->get_handle (),

                     backlog)==-1)

{

  ACE_Errno_Guard g (errno);    // Preserve across close() below.

  error =1;

  this->close ();

}

 


Accept:创建数据通道。完成accept操作。

 

文件:SOCK_Acceptor.cpp

代码行:134 - 136

new_stream.set_handle (ACE_OS::accept(this->get_handle (),

                                       addr,

                                       len_ptr));

 

1.3ACE_SOCK_Stream

类名

ACE_SOCK_Stream

所在文件

SOCK_Stream.h

功能

传输数据的流,用于传输数据。

关键数据

/// Recv @a n bytes via Win32 @c ReadFile using overlapped I/O.

ssize_t recv (void*buf,

            size_t n,

            ACE_OVERLAPPED *overlapped)const;

 

/// Send an @a n byte buffer to the connected socket.

ssize_t send (constvoid*buf,

            size_t n,

            int flags,

            const ACE_Time_Value *timeout =0)const;

 ACE_SOCK_Stream在ACE_SOCK_Acceptor执行accept时作为参数传入,accept把返回的IOhandle赋值给ACE_SOCK_

Stream,ACE_SOCK_Stream利用IO进行recv和send数据收发。

Recv接收accept连接上来的IO数据。

文件:SOCK_IO.cpp

代码行:143 - 145

ssize_tconst result = ACE_OS::recvv(this->get_handle (),

                                    iovp,

                                    total_tuples);

 Send向IO发送数据。

 

文件:SOCK_IO.cpp

代码行:103 - 105

ssize_tconst result = ACE_OS::sendv(this->get_handle (),

                                    iovp,

                                    total_tuples);

 

1.4 ACE_Task

 

 

类名

ACE_Task

所在文件

Task_T.h

功能

提供线程实例,也可以创建一组线程。包含一个消息队列。

关键数据

/// Insert message into the message queue.  Note that @a timeout uses

int putq (ACE_Message_Block *, ACE_Time_Value *timeout =0);

 

/**

* Extract the first message from the queue (blocking). 

*/

int getq (ACE_Message_Block *&mb, ACE_Time_Value *timeout =0);

 

// = Active object activation method.

virtualint activate (long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,

                    int n_threads =1,

                    int force_active =0,

                    long priority = ACE_DEFAULT_THREAD_PRIORITY,

                    int grp_id =-1,

                    ACE_Task_Base *task =0,

                    ACE_hthread_t thread_handles[]=0,

                    void*stack[]=0,

                    size_t stack_size[]=0,

                    ACE_thread_t thread_ids[]=0,

                    constchar* thr_name[]=0);

 

/// Run by a daemon thread to handle deferred processing.

virtualint svc(void);

 

/// Queue of messages on the ACE_Task..

 

ACE_Message_Queue<ACE_SYNCH_USE>*msg_queue_;

 

Putq:将消息插入队列,ACE_Message_Queue<ACE_SYNCH_USE> *msg_queue_是ACE实现的一个消息队列。提供队列的存储和方法。

文件:Task_T.inl

代码行:29

this->msg_queue_->enqueue_tail(mb, tv);

  

Getq:从消息队列中取一条数据记录。

文件:Task_T.inl

代码行:22

returnthis->msg_queue_->dequeue_head(mb, tv);

 

Activate:创建并激活线程。

文件:Task.cpp

代码行:161 - 172

grp_spawned =

  this->thr_mgr_->spawn_n (n_threads,

                           &ACE_Task_Base::svc_run,

                           (void*)this,

                           flags,

                           priority,

                           grp_id,

                           task,

                           thread_handles,

                           stack,

                           stack_size,

                           thr_name);

 

Svc:线程函数,需要继承类重写,创建时调用svc_run,入参为this当前类,以面向对象形式封装线程。

文件:Task.cpp

代码行:270 - 271

// Call the Task's svc() hook method.

intconst svc_status = t->svc();

 

1.5  ACE_Event_Handler

 

 

类名

ACE_Event_Handler

所在文件

Event_Handler.h

功能

事件接收器,与I/O绑定,当I/O产生不同事件时,执行ACE_Event_Handler的不同方法。

关键数据

/// Get the I/O handle.

virtual ACE_HANDLE get_handle (void)const;

 

/// Set the I/O handle.

virtualvoid set_handle (ACE_HANDLE);

 

/// Called when input events occur (e.g., connection or data).

virtualint handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);

 

/// Called when output events are possible (e.g., when flow control

/// abates or non-blocking connection completes).

virtualint handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);

 

 

get_handle、set_handle:继承重写或调用它们去设置和获取I/O。

文件:Event_Handler.h

代码行:91 – 94

virtual ACE_HANDLE get_handle (void)const;

 

virtualvoid set_handle (ACE_HANDLE);

 

handle_input、handle_output:继承重写它们,当产生相应的I/O事件时将被执行。

文件:Event_Handler.h

代码行:91 – 94

virtualint handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);

 

virtualint handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);

 

 

 

1.6 ACE_Reactor

 

类名

ACE_Reactor

所在文件

Reactor.h

功能

Reactor框架,提供IO复用、消息循环和消息分发。

关键数据

int register_handler (ACE_Event_Handler *event_handler,

                          ACE_HANDLE event_handle = ACE_INVALID_HANDLE);

                   

int remove_handler (ACE_HANDLE handle,

                   ACE_Reactor_Mask masks);

                  

int run_reactor_event_loop (REACTOR_EVENT_HOOK =0);

Reactor是I/O多路复用模式的一种,ACE提供了Reactor框架。

主要参与Reactor的对象有:

l 事件I/O,ACE_SOCK_Acceptor、ACE_SOCK_Stream的get_handle均提供对应I/O。

l 注册事件,继承于ACE_Event_Handler的对象。对象绑定了I/O,当产生I/O事件后将调用对象相对应的方法。

 

ACE_Reactor内部调用复杂,以下提供最后执行的关键代码。

register_handler:注册事件到Reactor,需要传入ACE_Event_Handler的派生类,即指定触发事件后将执行的函数,以及传入将被复用监听的I/O,I/O可以与ACE_Event_Handler绑定,也可以单独传入。Reactor将这两个信息绑定在handler_rep_容器内,并且将I/O以ADD形式添加到select_reactor_.wait_set_

文件:Select_Reactor_T.cpp     Select_Reactor_Base.cpp    Select_Reactor_Base.cpp

代码行:993                         249                     265-268

returnthis->handler_rep_.bind(handle, event_handler, mask);

 

this->event_handlers_[handle]= event_handler;

 

this->select_reactor_.bit_ops (handle,

                                     mask,

                                     this->select_reactor_.wait_set_,

                                     ACE_Reactor::ADD_MASK);

run_reactor_event_loop消息循环主要进行两个操作,1.监听注册的I/O。2.当I/O产生事件后通知到绑定的ACE_Event_Handler具体执行函数。在监听部分使用select监听注册进去的I/O select_reactor_.wait_set_通知时发送到指定的handle_inputhandle_output等相应函数。

文件:Select_Reactor_T.cpp       Select_Reactor_T.cpp       Select_Reactor_Base.cpp

代码行:  1435 - 1441               1093 – 1100                 737 - 746

int number_of_active_handles =

this->wait_for_multiple_events(this->dispatch_set_,

                                max_wait_time);

 

result =

this->dispatch(number_of_active_handles,

                this->dispatch_set_);

 

dispatch_set.rd_mask_ =this->wait_set_.rd_mask_;

dispatch_set.wr_mask_ =this->wait_set_.wr_mask_;

dispatch_set.ex_mask_ =this->wait_set_.ex_mask_;

number_of_active_handles = ACE_OS::select(width,

                                         dispatch_set.rd_mask_,

                                         dispatch_set.wr_mask_,

                                         dispatch_set.ex_mask_,

                                         this_timeout);

 

ACE_HANDLE const read_handle =

this->notification_pipe_.read_handle ();

 

if(read_handle != ACE_INVALID_HANDLE

  && rd_mask.is_set (read_handle))

{

  --number_of_active_handles;

  rd_mask.clr_bit (read_handle);

  returnthis->handle_input(read_handle);

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值