Acceptor-Connector模式一(Acceptor的工作)V2.0

ACE Acceptor-Connector 模式解析
本文详细介绍了ACE框架中的Acceptor-Connector模式,包括其工作原理、相关类的功能及其实现流程。该模式适用于面向连接的TCP/IP协议通信场景,能够高效地处理连接的建立与管理。

 前言:ACE Acceptor-Connector模式

首先这种模式肯定是面向连接的TCP/IP协议。
不管是什么场景,几乎面向连接的通信程序总是由一端主动发起连接,一端监听等待对方的连接。
这就是接收器-连接器模式(服务器-客户端)。

模式思想

(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函数会在指定端口监听
(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())

二、接收器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;
}

示例

下面的程序会在1500端口持续监听,每当有对端发来连接,就创建本地连接处理对象,创建完之后就通过连接处理对象的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;
}

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





<think>我们正在处理个关于下载Apache MINA特定版本(2.0.27)及相关jar包的问题。根据用户提供的引用信息,我们注意到在Maven依赖管理中,有时需要指定类型(type)为bundle,否则可能会出现Missing artifact的错误。 用户需求:下载mina-core-2.0.27及其他相关的jar包。 解决方案: 1. 直接通过Maven仓库下载:用户可以直接访问Maven中央仓库(https://mvnrepository.com/)搜索对应的jar包,然后下载。 2. 使用Maven依赖配置:如果用户使用Maven,可以在pom.xml中正确配置依赖项,然后Maven会自动下载。 根据引用[2]和[3]的信息,配置mina-core依赖时,需要指定type为bundle,否则会出错。因此,对于2.0.27版本,我们同样需要这样配置。 下面给出使用Maven依赖配置的方式: ```xml <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>2.0.27</version> <type>bundle</type> <scope>compile</scope> </dependency> ``` 其他相关jar包(如mina-integration-jmx, mina-integration-beans等)的配置类似,但注意并不是所有jar包都需要指定type为bundle,通常只有mina-core需要这样处理。其他jar包可以按照常规方式引入。 例如: ```xml <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-integration-jmx</artifactId> <version>2.0.27</version> </dependency> ``` 如果用户不想使用Maven,而是希望手动下载,可以访问Maven中央仓库的相应页面: - mina-core: https://repo1.maven.org/maven2/org/apache/mina/mina-core/2.0.27/ 在该页面中,可以下载文件:`mina-core-2.0.27.jar` 以及 `mina-core-2.0.27-bundle.jar`(注意:根据引用[2]的提示,可能需要的是bundle类型的jar,所以应该下载`mina-core-2.0.27-bundle.jar`) 但实际上,在Maven仓库中,同个版本通常会有多个文件,包括: - mina-core-2.0.27.jar - mina-core-2.0.27-bundle.jar - 以及其他文件(如源码包、javadoc包等) 根据引用[2]中的错误信息和解决方法,我们需要的是bundle类型的包。所以应该下载`mina-core-2.0.27-bundle.jar`。但是,请注意,在Maven依赖中配置了type为bundle后,Maven会自动下载这个bundle包。手动下载时,我们同样需要下载这个bundle包。 其他相关jar包(如mina-integration-jmx等)通常只需下载常规的jar包(即不带bundle后缀的)。 但是,请注意:在引用[1]中列出的jar包列表,例如: - mina-core-2.0.4.jar - mina-example-2.0.4.jar - ... 这些jar包并没有bundle后缀。因此,这里可能存在版本差异或使用场景差异。用户需要根据实际需求选择。 总结手动下载步骤: 1. 访问Maven中央仓库:https://repo1.maven.org/maven2/ 2. 进入org/apache/mina/ 3. 找到对应的artifactId(如mina-core)和版本(2.0.27)的目录 4. 下载所需的文件(如果是mina-core,则下载`mina-core-2.0.27-bundle.jar`;其他依赖则下载对应的`artifactId-version.jar`) 另外,根据引用[1],用户可能还需要其他相关jar包,如: - mina-example-2.0.27.jar (示例) - mina-filter-compression-2.0.27.jar - mina-integration-beans-2.0.27.jar - mina-integration-jmx-2.0.27.jar - mina-integration-ognl-2.0.27.jar - mina-integration-xbean-2.0.27.jar - mina-statemachine-2.0.27.jar - mina-transport-apr-2.0.27.jar 以及日志相关的jar包(如slf4j-api和slf4j-nop),但注意日志包版本可能需要匹配。 因此,用户需要明确自己需要哪些jar包。如果只是核心功能,可能只需要mina-core即可。如果还需要其他模块,则按需下载。 建议:如果用户的项目使用Maven或Gradle管理依赖,最好使用依赖管理工具,避免手动下载和管理jar包。 最后,我们提供个示例pom.xml片段,用于下载mina-core(bundle)和其他相关模块(不需要bundle类型): ```xml <dependencies> <!-- MINA Core with bundle type --> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>2.0.27</version> <type>bundle</type> <scope>compile</scope> </dependency> <!-- Other MINA modules (without bundle type) --> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-integration-jmx</artifactId> <version>2.0.27</version> </dependency> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-integration-beans</artifactId> <version>2.0.27</version> </dependency> <!-- 其他模块类似添加 --> </dependencies> ``` 这样,Maven会自动从中央仓库下载这些jar包。 如果用户坚持手动下载,那么按照上述步骤去Maven中央仓库逐个下载即可。注意,每个jar包可能有多个文件,选择正确的文件(通常主jar包就是`artifactId-version.jar`,但mina-core需要`artifactId-version-bundle.jar`)。 另外,关于日志依赖:MINA使用SLF4J作为日志门面,因此用户还需要引入SLF4J的实现(如logback、log4j等)或绑定(如slf4j-nop,表示不输出日志)。例如: ```xml <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.10</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.10</version> </dependency> ``` 注意:版本1.7.10可能与MINA 2.0.27兼容,但用户也可以使用更新的版本(如1.7.36),只要API兼容即可。 §§相关问题§§ 1. 如何解决下载Apache MINA依赖时出现的“Missing artifact”错误? 2. 除了Maven中央仓库,还有哪些途径可以下载Apache MINA的jar包? 3. 如何在非Maven项目中管理Apache MINA的依赖? </think>### Apache MINA 2.0.27 及相关 JAR 包下载指南 根据您的需求和引用内容,以下是完整的解决方案: #### 1. **Maven 依赖配置(推荐方式)** 在 `pom.xml` 中添加以下依赖配置(**必须包含 `<type>bundle</type>`**,否则会出现 *Missing artifact* 错误): ```xml <properties> <mina.version>2.0.27</mina.version> </properties> <dependencies> <!-- 核心依赖(必须指定 bundle 类型) --> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>${mina.version}</version> <type>bundle</type> <!-- 关键配置 --> <scope>compile</scope> </dependency> <!-- 其他常用组件 --> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-integration-jmx</artifactId> <version>${mina.version}</version> </dependency> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-filter-compression</artifactId> <version>${mina.version}</version> </dependency> <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-transport-apr</artifactId> <version>${mina.version}</version> </dependency> <!-- SLF4J 日志依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.36</version> <!-- 更新至稳定版 --> </dependency> </dependencies> ``` #### 2. **手动下载地址** 直接从 Maven 中央仓库下载(替换链接中的版本号): | **JAR 包名称** | **下载链接** | |----------------|--------------| | mina-core-2.0.27-bundle.jar | [https://repo1.maven.org/maven2/org/apache/mina/mina-core/2.0.27/mina-core-2.0.27-bundle.jar](https://repo1.maven.org/maven2/org/apache/mina/mina-core/2.0.27/mina-core-2.0.27-bundle.jar) | | mina-integration-jmx-2.0.27.jar | [https://repo1.maven.org/maven2/org/apache/mina/mina-integration-jmx/2.0.27/](https://repo1.maven.org/maven2/org/apache/mina/mina-integration-jmx/2.0.27/) | | mina-integration-beans-2.0.27.jar | [https://repo1.maven.org/maven2/org/apache/mina/mina-integration-beans/2.0.27/](https://repo1.maven.org/maven2/org/apache/mina/mina-integration-beans/2.0.27/) | | **全量组件列表** | [https://repo1.maven.org/maven2/org/apache/mina/](https://repo1.maven.org/maven2/org/apache/mina/) | #### 3. **关键注意事项 - **类型问题**:`mina-core` 必须下载 **`-bundle.jar`** 后缀文件(普通 `.jar` 会导致依赖错误)[^2][^3]。 - **日志依赖**:需配套下载 `slf4j-api` + 日志实现(如 `slf4j-simple`),否则运行时可能报错。 - **版本致性**:所有 MINA 组件版本需保持统(如均为 2.0.27)。 #### 4. **验证步骤 1. 创建简单的 Socket 服务器: ```java import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaServer { public static void main(String[] args) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.bind(new InetSocketAddress(9123)); System.out.println("MINA 2.0.27 服务端已启动"); } } ``` 2. 若运行无 `ClassNotFoundException`,则依赖配置成功。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值