ACE之初体验

最近这一周在研究ACE,这学期的突然的机会让我接触到了ACE,仅仅两天,我不得不为他的精彩折服,对分布式的良好支持,对平台的适应性,用户线程的管理,主动对像,前台服务器……我真是无法用语言来表达对他的钟情,哈哈。

下面介绍一下我对ACE学习心得:ACE自适配通信环境(ADAPTIVE Communication Environment)是可以自由使用、开放源码的面向对象(OO)构架(Framework),在其中实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++ Wrapper Facade(包装外观)和构架组件,可跨越多种平台完成通用的通信软件任务。其中包括:事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、分布式服务动态(重)配置、并发执行和同步,等等。

ACE的目标用户是高性能和实时通信服务和应用的开发者。它简化了使用进程间通信、事件多路分离、显式动态链接和并发的OO网络应用和服务的开发。此外,通过服务在运行时与应用的动态链接,ACE还使系统的配置和重配置得以自动化。

还有很多我就不列举了,这里有我写的几个程序,有兴趣的话,大家一起研究:


1)ACE初体验:
客户端:
#include "ace/Log_Msg.h"
#include "ace/OS_main.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Stream.h"

int ACE_TMAIN(int argc, ACE_TCHAR* argv[])
{
ACE_DEBUG((LM_DEBUG,ACE_TEXT("freebird.\n")));
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peer_addr;
??
if(peer_addr.set(80,"192.168.22.26")==-1)
return 1;
else if(connector.connect(peer,peer_addr)==-1)
return 1;
}

用ACE开发网络通信程序

该程序将演示如何将一个简单结构序列化后发送到网络上,如何从网络上接收到数据后反序列化回结构。

ACE的C++ WRAPPER FACADE层将网络通信分成三种角色:连接者(ACE_SOCK_Connector)、等待者(ACE_SOCK_Acceptor)和传输者 

(ACE_SOCK_Stream)。

 

建立连接

首先使用ACE_SOCK_Connector::connect连接某个服务器(使用ip地址和端口号),该服务器上使用ACE_SOCK_Acceptor::accept等待 

外部的连接请求。

ACE_INET_Addr类进行管理SOCKET通信使用的IP地址和端口号。

当连接建立的时候,连接者和等待者都初始化一个传输者用于通信。

下面就是连接者如何连接本机的7777端口的服务程序代码:

#include <iostream>
using namespace std;
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Connector.h"
int main(void)
{
ACE_INET_Addr address("127.0.0.1:7777");
ACE_SOCK_Connector connector;
ACE_SOCK_Stream stream;
if(connector.connect(stream,address)==-1)
{
cout<<strerror(errno)<<endl;
}
}

如果连接成功,connect方法返回0,如果连接失败,返回-1,线程专有的errno变量将被设置对应的错误码,你可以通过strerror函 

数获取错误信息描述字符串。ACE不使用异常报错,原因之一是早些时候异常并不被所有的C++编译器支持,原因之二是异常对性能仍 

然有影响,作为高性能底层库ACE仍然采用了C风格进行错误处理。但是你仍然可以在自己的应用逻辑中使用异常,并不会和ACE发生 

冲突。

下面是服务器的示例:

#include <iostream>
using namespace std;
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Acceptor.h"
int main(void)
{
ACE_SOCK_Acceptor acceptor;
//本地端口7777的ACE_INET_Addr对象
ACE_INET_Addr address;
address.set(7777);
//绑定本地端口,并且设置为监听状态
if(acceptor.open(address)==-1)
{
cout<<strerror(errno)<<endl;
}
ACE_SOCK_Stream stream;
if(acceptor.accept(stream)==-1)
{
cout<<strerror(errno)<<endl;
}
}

注意,ACE_SOCK_Acceptor::accept和ACE_SOCK_Connector::connect方法都可以接收一个ACE_TIME_Value*参数。该参数缺省直为 

NULL,就像上面的两个示例,表示除非建立连接,否则不会返回;如果我们创建ACE_TIME_Value time(0,0)对象作为参数,则表示方法 

不会阻塞,如果不能立刻建立连接,就返回-1,并且errno为EWOULDBLOCK;如果我们创建ACE_TIME_Value time(5,0)对象作为参数, 

就表示方法会最多等待5秒钟,如果5秒钟内还没有建立连接,就返回-1,并且errno为ETIME.

一个完整的客户端、服务器的例子:

/******************************************************************************
*
* 一个简单的ACE客户端例程
* 功能:连接指定的IP,发送任意的一条消息,来触发服务端,然后接收数据并显示
* 开发平台:支持opensuse,ubuntu,fedora
*****************************************************************************/
#include "ace/INET_Addr.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Stream.h"
#include "ace/Log_Msg.h"
// FUZZ: disable check_for_streams_include
#include "ace/streams.h"
# include <stdio.h>
# include <string.h>
int main(int argc, char* argv[])
{
ACE_INET_Addr iaServer;
u_short nPort = 5001 ;
const char * pServerHost = "10.110.16.45" ;
int iResult ;
ACE_SOCK_Connector scConnector;
ACE_SOCK_Stream ssStream ;
char szBuffer[1024] ;
char* pText = "Hello World!" ;
size_t nLength = 0 ;
iResult = iaServer.set(nPort, pServerHost);
if (iResult == -1)
ACE_ERROR_RETURN ((LM_ERROR, "lookup %s, %p\n", pServerHost, nPort), 1);
if ( scConnector.connect(ssStream, iaServer) < 0 )
ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect()"), 1);
strcpy(szBuffer, pText) ;
ssStream.send_n(szBuffer, strlen(pText)) ;
memset(szBuffer, 0, sizeof(szBuffer)) ;
iResult = ssStream.recv_n(szBuffer, 1024) ;
nLength = strlen(szBuffer) ;
ACE::write_n(ACE_STDOUT, "Recv --> " , 9) ;
ACE::write_n(ACE_STDOUT, szBuffer, nLength) ;
ACE::write_n(ACE_STDOUT, "\n", 1) ;
return 0 ;
}

/******************************************************************************
*
* 一个简单的ACE服务端例程
* 功能:当客户端发送任意消息过来之后,服务端向客户端发送当前主机的日期字符串
*??开发平台:支持opensuse,ubuntu,fedora
*****************************************************************************/
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Acceptor.h>
#include <ctime>
#include "ace/streams.h"
int DisplayTime(char* pTime) ;
int main(int argc, char *argv[])
{
ACE_INET_Addr addr(5001);
ACE_SOCK_Acceptor server;
ACE_SOCK_Stream stream;
char szBuffer[1024] ;
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("bind failed")));
return 1;
}
while(server.accept(stream)!=-1)
{
ACE_INET_Addr raddr;
stream.get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) connect:%s %d\n"),raddr.get_host_addr(),raddr.
get_port_number()));
memset(szBuffer, 0, sizeof(szBuffer)) ;
DisplayTime(szBuffer) ;
stream.send_n(szBuffer,sizeof(szBuffer));
stream.close();
}
server.close();
return 0;
}
int DisplayTime(char* pTime)
{
time_t nTime=0;
time( &nTime ) ;
tm *tm1 = localtime( &nTime ) ;
sprintf(pTime,"%04d-%02d-%02d %02d:%02d:%02d",tm1->tm_year+1900,tm1->tm_mon+1,tm1->tm_mday,
tm1->tm_hour,tm1->tm_min,tm1->tm_sec);
ACE::write_n(ACE_STDOUT, "当前时间 --> " , 13) ;
ACE::write_n(ACE_STDOUT, pTime, strlen(pTime)) ;
ACE::write_n(ACE_STDOUT, "\n", 1) ;
return 0 ;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值