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. [Linux] VIM 常用快捷键2

    如何使用MacVim 1.在插入模式之外 基本上来说,你应该尽可能少的呆在插入模式里面,因为在插入模式里面 VIM 就像一个“哑巴”编辑器一样.很多新手都会一直呆在插入模式里面,因为这样易于使用.但 ...

  2. LuaStudio 9.27 去10分钟退出暗桩板

    http://bbs.pediy.com/showthread.php?p=1428203#post1428203

  3. Maven学习(三) -- 仓库

    标签(空格分隔): 学习笔记 坐标和依赖时任何一个构件在Maven世界中的逻辑表示方式:而构件的物理表示方式是文件,Maven通过仓库来同意管理这些文件. 任何一个构件都有其唯一的坐标,根据这个坐标可 ...

  4. ural1057 Amount of Degrees

    链接 这题有一点小坑点 就是AX^B  A只能为0或者1  ,剩下的就比较好做的了. #include <iostream> #include<cstdio> #include ...

  5. 页面加载后resize页面布局

    在我们写web的时候,有的时候页面加载完以后,布局位置有一些问题,手动改变窗口大小后则正常显示位置. 其实,我们手动改变窗口大小,是执行了resize方法. share一下兼容方法: coffee c ...

  6. nodejs的第一天学习笔记

    一. js的模块化 什么是模块化: 模块化的概念最早是后台,随着ajax技术的兴起,js在编程中所占的地位越来越高,同时js的文件也相应的越来越多.为了方便文件的管理和更新,提出了js文件的模块 化, ...

  7. The import javax.servlet.http.HttpServletRequest cannot be resolved

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  8. 0040 Linux 系统管理命令

    1. 主机名称 hostname hostnamectl 2.开机启动 chkconfig systemctl 3.服务管理 service 服务名  start service 服务名  stop ...

  9. 你真的会写单例模式吗-------Java实现

    转载: 你真的会写单例模式吗--Java实现 单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好.用对单例模式,还真得费一番脑筋.本文对Java中常见的单例模式写法做了一个总结,如有错漏 ...

  10. Clojure学习笔记(二)——函数式编程

    定义 “函数式编程”是一种编程范式(programming paradigm),即如何编写程序的方法论.主要思想是把运算过程尽量写成一系列嵌套的函数调用. 举例来说,现在有这样一个数学表达式: (1 ...