前言:ACE Acceptor-Connector模式

首先这样的模式肯定是面向连接的TCP/IP协议。

无论是什么场景。差点儿面向连接的通信程序总是由一端主动发起连接,一端监听等待对方的连接。
这就是接收器-连接器模式(server-client)。

模式思想

(1)此模式仅仅负责连接的建立。无论有多少连接上来,这个模式都能应对。
(2)至于连接建立之后怎样通信,那是通信处理器的事情,与此模式不再有不论什么关系。

(3)资源的管理总是通过调用函数的返回值来做约定的处理。不用类型假设有特殊的资源管理需求。均能够覆盖父类的方法。

相关类

(1)ACE_Svc_Handler  : ACE_Task (服务处理器)连接服务的本地端,成员变量PEER_STREAM peer_由模板參数化。一般为ACE_SOCK_Stream,负责通信的详细运行。ACE_SOCK_Stream既能够读也能够写socket。

(2)ACE_Acceptor (接受器)该工厂被动的接受连接,并随即初始化一个ACE_Svc_Handler 对象来响应。接收器的handle_input方法截获连接信息,并创建服务处理类,最后运行服务处理类的open方法启动服务处理流程。
(3)ACE_Connector (连接器)该工厂主动的连接到对端接受器,并随即初始化一个ACE_Svc_Handler 对象来响应
(4)ACE_Reactor运行不依赖于应用的一般的消息分发策略

一、接收器的工作

接收器的工作流程:
(1)接收器的open函数会在指定port监听
(2)将自己与AACE_Event_Handler::ACCEPT_MASK事件一起注冊到反应器
(3)对端发起连接请求之后,反应器回调ACE_Acceptor ::handle_input方法
(4)handle_input方法就会创建连接处理器对象。并调用连接处理器的open方法
(5)handle_input方法返回-1的时候反应器就会回调接收器的handle_close方法,(參考ACE_Reactor的工作逻辑
(6)接收器的handle_close方法主要工作是关闭注冊事件,并关闭socket资源(运行peer_acceptor_.close())

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

二、接收器handle_input的工作

handle_input的工作主要包含三部分:
(1)依据模板參数创建服务处理对象new ACE_Svc_Handler
(2)调用成员ACE_SOCK_Acceptor peer_acceptor_的acceptor方法。指定当连接成功建立之后由服务处理对象ACE_Svc_Handler来处理连接
(3)调用服务处理对象的open方法
1)服务处理对象的open方法会注冊ACE_Event_Handler::READ_MASK事件到ACE_Reactor
2)服务处理对象的open方法会发起receive动作開始读,
3)服务处理对象的读取完毕会运行handle_input。至于服务处理对象的handle_input方法返回-1则是ACE_Reactor的处理逻辑了。
(4)服务处理对象的open方法假设返回-1。则调用服务处理对象的close方法(),ACE_Svc_Handler的close方法会调用handle_close。进而调用destroy,进而调用delete this
template <typename PEER_STREAM, typename SYNCH_TRAITS> int
ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close (ACE_HANDLE,
ACE_Reactor_Mask)
{
ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close"); if (this->reference_counting_policy ().value () ==
ACE_Event_Handler::Reference_Counting_Policy::DISABLED)
{
this->destroy ();
} return 0;
}
template <typename PEER_STREAM, typename SYNCH_TRAITS> void
ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy (void)
{
ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy"); // Only delete ourselves if we're not owned by a module and have
// been allocated dynamically.
if (this->mod_ == 0 && this->dynamic_ && this->closing_ == false)
// Will call the destructor, which automatically calls <shutdown>.
// Note that if we are *not* allocated dynamically then the
// destructor will call <shutdown> automatically when it gets run
// during cleanup.
delete this;
}

演示样例

以下的程序会在1500port持续监听,每当有对端发来连接。就创建本地连接处理对象,创建完之后就通过连接处理对象的open返回-1来告诉反应器来释放该对象。

Acceptor 服务端

#include <ace/Log_Msg.h>
#include "ace/Svc_Handler.h"
#include <ace/Acceptor.h>
#include "ace/SOCK_Acceptor.h"
#include "ace/INET_Addr.h"
#include "ace/Reactor.h" class My_Time_Server_Handler : public ACE_Svc_Handler<ACE_SOCK_Stream,ACE_NULL_SYNCH>
{
public:
~My_Time_Server_Handler();
//由接收器在接收到对端的连接请求之后调用此方法
virtual int open(void *)
{
ACE_DEBUG((LM_DEBUG,"one client connection established.\n"));
return -1;// ERROR
}
}; My_Time_Server_Handler::~My_Time_Server_Handler()
{
ACE_DEBUG((LM_DEBUG,"~My_Time_Server_Handler()\n"));
} int main(int argc, char *argv[])
{
ACE_INET_Addr local_addr(1500); ACE_Acceptor<My_Time_Server_Handler,ACE_SOCK_Acceptor> acceptor; acceptor.open(local_addr,ACE_Reactor::instance());
//截过连接信息
ACE_Reactor::instance()->run_reactor_event_loop(); return 0;
}

Connector客户端

#include <ace/Log_Msg.h>
#include <ace/SOCK_Connector.h>
#include "ace/INET_Addr.h" int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address
ACE_SOCK_Connector client_connetor; // connetor for socket client
ACE_SOCK_Stream sock_stream; // stream is for socket read/write if(client_connetor.connect(sock_stream,addr)==-1) //connect to remote address
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("connection failed!")));
return -1;
}
if (sock_stream.close () == -1) //close the connection
{
ACE_ERROR ((LM_ERROR,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("sock close")));
return -1;
}
return 0;
}

执行结果:每次执行client都会创建一个服务端的服务处理对象,并随即被释放(我们有益让open方法返回-1来释放服务处理对象,从而来说明整个事件的流程)

Acceptor-Connector模式一(Acceptor的工作)V2.0的更多相关文章

  1. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  2. Eureka 系列(06)消息广播(下):TaskDispacher 之 Acceptor - Worker 模式

    Eureka 系列(06)消息广播(下):TaskDispacher 之 Acceptor - Worker 模式 [TOC] Spring Cloud 系列目录 - Eureka 篇 Eureka ...

  3. 网关局域网通信协议V2.0

    http://docs.opencloud.aqara.cn/development/gateway-LAN-communication/ https://github.com/aqara/openc ...

  4. SteamVR Unity Plugin - v2.0.1中的InteractionSystem

    最近写VR项目的时候用到了SteamVR Unity Plugin - v2.0.1插件,感觉比之前用到的SteamVR plugin for Unity - v1.2.2版本改进了很多,就算不用VR ...

  5. 运维工程师打怪升级进阶之路 V2.0

    在此之前,发布过两个版本: 运维工程师打怪升级之路 V1.0 版本发布 运维工程师打怪升级必经之路 V1.0.1 很多读者伙伴们反应总结的很系统.很全面,无论是0基础初学者,还是有基础的入门者,或者是 ...

  6. BurpSuite pro v2.0 使用入门教程

    BurpSuite简介 BurpSuite是进行Web应用安全测试集成平台.它将各种安全工具无缝地融合在一起,以支持整个测试过程中,从最初的映射和应用程序的攻击面分析,到发现和利用安全漏洞.Burps ...

  7. POLARDB v2.0 技术解读

    点击观看“POLARDB 2.0 升级发布会”:https://yq.aliyun.com/live/1136 回顾POLARDB 1.0 POLARDB 1.0 主要的改进包括采用了计算存储分离的架 ...

  8. ChromePortable-Chrome便携化、绿化软件v2.0

    ChromePortable-Chrome便携化.绿化软件v2.0-用户手册 By:ybmj@vip.163.com ,http://bbs.kafan.cn/thread-1806385-1-1.h ...

  9. 怎样在IDEA中使用JUnit4和JUnitGenerator V2.0自动生成测试模块

     因为项目的需要,所以研究了一下自动生成测试代码.将经验记录下来,总会有用的.我个人认为,好记性不如多做笔记多反思总结. 1.    前提条件 开发环境已正确配置 工程已解决JUnit依赖关系(pom ...

  10. 微信快速开发框架(六)-- 微信快速开发框架(WXPP QuickFramework)V2.0版本上线--源码已更新至github

    4月28日,已增加多媒体上传及下载API,对应MediaUploadRequest和MediaGetRequest ------------------------------------------ ...

随机推荐

  1. Linux应用层的定时器Timer使用详解【转】

    转自:http://blog.csdn.net/wwwtovvv/article/details/8601528 版权声明:本文为博主原创文章,未经博主允许不得转载. linux下定时器的使用 -- ...

  2. undefined reference to XXX 问题原因

    原文地址:http://blog.csdn.net/cserchen/article/details/5503556 Linux下编译程序时,经常会遇到“undefined reference to ...

  3. 我们为什么需要 lock 文件

    前言 从 Yarn 横空出世推出 lock 文件以来,已经两年多时间了,npm 也在 5.0 版本加入了类似的功能,lock 文件越来越被开发者们接收和认可.本篇文章想从前端视角探讨一下我们为什么需要 ...

  4. mysql 事务、游标

    mysql 事务 在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务,所以很多情况下我们都使用innodb引擎. 事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行 ...

  5. 用RegisterHotKey注册系统热键

    函数功能:该函数定义一个系统范围的热键. 函数原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk): 参数: hWnd:接 ...

  6. centos7刚安装需要的一些基础优化

    基本操作一:更改主机名 centos7有一个新的修改主机名的命令hostnamectl # hostnamectl set-hostname --static benjamin # vim /etc/ ...

  7. poj 2546(两圆公共面积)

    Circular Area Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5682   Accepted: 2225 Des ...

  8. Mac下安装node.js , Ionic

    访问node.js官网(https://nodejs.org/en/download/),下载相应的版本. 下载完,点击安装  [默认目录] Node.js v8.9.3 to /usr/local/ ...

  9. iframe和response.sendRedirect()跳转到父页面的问题

    在项目中,因为为了给页面分层次,就使用了 内嵌iframe 的分了三个框.在子页面进行操作的时候,如果session超时,就要被拦截器拦截重新回到首页进行登录,但是在sub页 面 ,进行操作的时候,如 ...

  10. Implicit declaration of function 'ether_ntoa' is invalid in C99

    报错代码: strcpy(temp, (char *)ether_ntoa(LLADDR(sdl))); 解决方法: 导入这三个头文件即可, #include <sys/types.h> ...