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

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

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

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,

 const char 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);

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 = ,

 int protocol_family = PF_UNSPEC,

 int backlog = ACE_DEFAULT_BACKLOG,

 int protocol = );

 /**

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

 */

 int accept (ACE_SOCK_Stream &new_stream,

 ACE_Addr *remote_addr = ,

 ACE_Time_Value *timeout = ,

 bool restart = true,

 bool reset_new_handle = false) const;

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

文件:SOCK.cpp

代码行:141 - 146

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

 type,

 protocol,

 protocolinfo,

 g,

 flags));

文件:SOCK_Acceptor.cpp

代码行:279 - 282

  else if (ACE_OS::bind (this->get_handle (),

  (sockaddr *) local_sap.get_addr (),

  local_sap.get_size ()) == -)

  error = ;

文件:SOCK_Acceptor.cpp

代码行:284 - 291

 if (error != 

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

 backlog) == -)

 {

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

 error = ;

 this->close ();

 }

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

文件:SOCK_Acceptor.cpp

代码行:134 - 136

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

 addr,

 len_ptr));

3 ACE_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 (const void *buf,

 size_t n,

 int flags,

 const ACE_Time_Value *timeout = ) 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_t const result = ACE_OS::recvv (this->get_handle (),

 iovp,

 total_tuples);

Send:向IO发送数据。

文件:SOCK_IO.cpp

代码行:103 - 105

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

 iovp,

 total_tuples);

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 = );

 /**

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

 */

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

 // = Active object activation method.

 virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,

 int n_threads = ,

 int force_active = ,

 long priority = ACE_DEFAULT_THREAD_PRIORITY,

 int grp_id = -,

 ACE_Task_Base *task = ,

 ACE_hthread_t thread_handles[] = ,

 void *stack[] = ,

 size_t stack_size[] = ,

 ACE_thread_t thread_ids[] = ,

 const char* thr_name[] = );

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

 virtual int 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

 return this->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.

 int const svc_status = t->svc ();

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.

 virtual void set_handle (ACE_HANDLE);

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

 virtual int 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).

 virtual int 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;

 virtual void set_handle (ACE_HANDLE);

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

文件:Event_Handler.h

代码行:91 – 94

 virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);

 virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);

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 = );

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

 return this->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);

 return this->handle_input (read_handle);

 }

ACE - Reactor源码总结整理的更多相关文章

  1. ACE Reactor 源码解析

    http://blogs.readthedocs.org/   ACE的学习笔记,根据源码分析了Reactor模型的实现. 因为笔记编写技术限制,这里仅列出主要目录,如有可能可以抽空复制到该Blog中 ...

  2. ACE的源码划分

    前几篇文章也提到过,ACE的所有源文件和头文件都杂乱堆在了ACE_wrappers/ace目录下.这样的代码组织方式给学习ACE带来了很大的困难,很多朋友在看到ace目录下庞大的代码的时候,几乎就失去 ...

  3. element-ui 组件源码分析整理笔记目录

    element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...

  4. element-ui Carousel 走马灯源码分析整理笔记(十一)

    Carousel 走马灯源码分析整理笔记,这篇写的不详细,后面有空补充 main.vue <template> <!--走马灯的最外层包裹div--> <div clas ...

  5. ACE - ACE_Task源码剖析及线程池实现

    原文出自http://www.cnblogs.com/binchen-china,禁止转载. 上篇提到用Reactor模式,利用I/O复用,获得Socket数据并且实现I/O层单线程并发,和dispa ...

  6. 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生

    [转].NET(C#):浅谈程序集清单资源和RESX资源   目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...

  7. laravel5源码讲解整理

    来源:http://yuez.me/laravel-yuan-ma-jie-du/?utm_source=tuicool&utm_medium=referral 目录 入口文件 index.p ...

  8. Windows平台下载Android源码(整理)

    Google官方下载源码使用的系统Ubuntu系统,不过现在我们需要在Windows系统中下载Android源码文件. 网站的地址是:https://android.googlesource.com/ ...

  9. element-ui button组件 radio组件源码分析整理笔记(一)

    Button组件 button.vue <template> <button class="el-button" @click="handleClick ...

随机推荐

  1. 浙江理工2015.12校赛-F Landlocked

    Landlocked Time Limit: 5 Sec Memory Limit: 128 MB Submit: 288 Solved: 39 Description Canada is not a ...

  2. ContentProvider总结

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给 ...

  3. ASP.NET多个Button的页面,回车执行按钮事件(转)

    主要有两种实现方法分别是:JavaScript的方法与Panel的方法 一.JavaScript的方法 ①单输入框(文本框)单按钮的实现方法 以下功能实现:在输入框中输入内容之后,按回车键就执行按钮事 ...

  4. C语言细节——献给初学者(二)

    C语言细节——献给初学者(二) 主题  循环运用+选择判断 C语言循环有for和while/do...while: 选择判断有:if...else和switch...case 在循环中需要注意搭配br ...

  5. Deep Learning 2_深度学习UFLDL教程:矢量化编程(斯坦福大学深度学习教程)

    1前言 本节主要是让人用矢量化编程代替效率比较低的for循环. 在前一节的Sparse Autoencoder练习中已经实现了矢量化编程,所以与前一节的区别只在于本节训练集是用MINIST数据集,而上 ...

  6. css 浮动

    1. 浮动 浮动是css的布局功能,在CSS中,包括div在内的任何元素都可以浮动的方式显示.它能够改变页面中对象的前后流动顺序.浮动元素会脱离文档流,不占据空间.浮动元素可以左右移动,直到碰到包含它 ...

  7. UNION并集运算

    在集合论中,两个集合(集合A和集合B)的并集是一个包含集合A和B中所有元素的集合.换句话说,如果一个元素属于任何一个输入集合,那么它也属于结果集.如图所示.

  8. 上下文菜单项(contextMenu)----长按按钮弹出菜单项

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  9. 关于 php mysql pdo cannot find driver 解决方案

    1.下载 文件 或者 进入 在PHP源码包中进入ext/pdo_mysql http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz 2.解压文件tar zxvf PDO ...

  10. PB中用oracle的存储过程返回记录集做数据源来生成数据窗口,PB会找不到此存储过程及不能正常识别存储过程的参数问题(转)

    (转)在PB中用oracle的存储过程返回记录集做数据源来生成数据窗口 首先oracle的存储过程写法与MSSQL不一样,差别比较大. 如果是返回数据集的存储过程则需要利用oracle的包来定义游标. ...