ACE - 代码层次及Socket封装

原文出自http://www.cnblogs.com/binchen-china,禁止转载。

ACE源码约10万行,是c++中非常大的一个网络编程代码库,包含了网络编程的边边角角。在实际使用时,并不是所有代码都能用到你的项目中来,相反你只需要其中的一小部分就已经可以完成实际所需。

最近研究其源码最大的感受就是代码量大,资料少,逻辑跳跃大。网上搜了下ACE方面的书籍和资料,也是皮毛上打滚,概念满天飞,侧重讲解如何使用其框架,复杂的底层代码和实现都避而不谈,不如直接看源码来的直接。ACE代码目录结构并不是非常好,很多文件堆在一个路径下面,很阅读难归纳各个文件的功能,源码大量使用模板和导入导出,source insight看的实在汗颜。

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

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

OO层经常用到的就是Socket封装,这部分内容主要包括以下几个:

  • ACE_SOCK_Connector:连接器,主动建立连接,用于Socket Client。
  • ACE_SOCK_Acceptor:接受器,被动建立连接,用于Socket Server。
  • ACE_SOCK_Stream:传输数据的流,用于传输数据。
  • ACE_INET_Addr:用于表示通信端点的地址。

封装这四个结构简化了Socket编程代码,避免了代码细节上错误,也增强了移植性和面向对象思想的应用。

之前文章的服务器编程可以看做是纯C语言的面向过程编程,从bind到listen等,非常繁琐且参数复杂,调用易出错,异常处理容易遗漏等,ACE的这四个Socket封装把这些问题都解决了。所有细节代码都在ACE内部屏蔽了。

下面直接上服务器代码:

  1 #include <ace/INET_Addr.h>
  2 #include <ace/SOCK_Acceptor.h>
  3 #include <ace/SOCK_Stream.h>
  4 #include <ace/Log_Msg.h>
  5 
  6 #define MAX_BUFF_SIZE     1024
  7 #define LISTEN_PORT     5010
  8 #define SERVER_IP        ACE_LOCALHOST
  9 
 10 class Server
 11 {
 12 public:
 13     Server(int port,char* ip);
 14     ~Server();
 15     bool open();
 16     bool run();
 17     void close();
 18     ACE_SOCK_Stream& Getstream(){return Svr_stream;}
 19 private:
 20     ACE_INET_Addr Svr_addr,Cli_addr;
 21     ACE_SOCK_Acceptor Svr_aceept;
 22     ACE_SOCK_Stream Svr_stream;
 23 };
 24 
 25 Server::Server(int port,char* ip):Svr_addr(port,ip)
 26 {
 27     
 28 }
 29 
 30 Server::~Server()
 31 {
 32     
 33 }
 34 
 35 bool Server::open()
 36 {
 37     if (-1 == Svr_aceept.open(Svr_addr,1))
 38     {
 39         ACE_DEBUG((LM_ERROR,ACE_TEXT("failed to accept\n")));
 40         Svr_aceept.close();
 41         return false;
 42     }
 43     return true;
 44 }
 45 
 46 bool Server::run()
 47 {
 48     if (-1 == Svr_aceept.accept(Svr_stream,&Cli_addr))
 49     {
 50         ACE_DEBUG((LM_ERROR,ACE_TEXT("failed to accept\n")));
 51         Svr_aceept.close();
 52         return false;
 53     }
 54     return true;
 55 }
 56 
 57 void Server::close()
 58 {
 59     Svr_aceept.close();
 60 }
 61 
 62 int main()
 63 {
 64     Server Svr(LISTEN_PORT,(char*)SERVER_IP);
 65     char strBuffer[MAX_BUFF_SIZE];
 66     
 67     if (!Svr.open())
 68     {
 69         return 0;
 70     }
 71     ACE_DEBUG((LM_INFO, ACE_TEXT("open success!\n")));
 72     
 73     if (!Svr.run())
 74     {
 75         return 0;
 76     }
 77     ACE_DEBUG((LM_INFO, ACE_TEXT("run success!\n")));
 78     
 79     ACE_SOCK_Stream Svr_data = Svr.Getstream();    
 80 
 81     while(1)
 82     {    
 83         int byte = Svr_data.recv(strBuffer,MAX_BUFF_SIZE);
 84         if (-1 == byte)
 85         {
 86             ACE_DEBUG((LM_INFO, ACE_TEXT("receive data failed\n")));
 87             break;
 88         }
 89         else if(0 == byte)
 90         {
 91             ACE_DEBUG((LM_INFO, ACE_TEXT("client closed!\n")));
 92             break;
 93         }
 94         else
 95         {
 96             ACE_DEBUG((LM_INFO, ACE_TEXT("receive from client: %s\n"),strBuffer));
 97             ACE_OS::memset(strBuffer, 0, sizeof(strBuffer));
 98         }
 99     }
100     Svr_data.close();
101     Svr.close();
102     return 0;
103 }

运行结果:

至此,还并没有发现ACE完成的Server和之前用linux底层API完成的代码或功能上有何区别。这里还暂时只是单纯的利用OO层代码熟悉ACE,后续将利用ACE的Reactor框架进行Server开发。感受ACE的优势和便捷。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

使用 SQLNET.EXPIRE_TIME 清除僵死连接

    数据库连接的客户端异常断开后,其占有的相应并没有被释放,如从v$session视图中依旧可以看到对应的session处于inactive,且对应的服务器...

2172
来自专栏GIS讲堂

Highcharts导出图片

Highcharts是在做项目涉及到统计图的时候大家的首选,同时也会用到highcharts的export功能,将统计图导出为图片,刚好,最近也遇到了这样的事情...

4402
来自专栏Kotlin入门系列

win7基础 cmd 查看当前已经启动的服务列表

5106
来自专栏HansBug's Lab

算法模板——线性筛素数

实现功能:如题,筛出1——N内的所有素数 原理:如phile神犇所言,这次的才算是真正意义上的线性筛素数,其精髓在于if (i mod a[j])=0 then...

29312
来自专栏吴伟祥

Linux命令缩写英文对照记忆(〇) 转

1052
来自专栏linux驱动个人学习

基于input子系统的sensor驱动调试(二)

继上一篇:https://cloud.tencent.com/developer/article/1054078 一、驱动流程解析: 1、模块加载: 1 st...

5947
来自专栏白驹过隙

ACE - 代码层次及Socket封装

3157
来自专栏张善友的专栏

开源的虚拟机软件 VirtualBox v1.5.2

对于VMWare、Virtual PC这些虚拟机软件,可能大家都比较熟悉。VirtualBox是德国一家软件公司InnoTek所开发的虚拟系统软件,它不仅具有丰...

26210
来自专栏杨建荣的学习笔记

一条执行4秒的sql语句导致的系统问题(r3笔记第10天)

一般来说一条sql语句执行个4秒钟是可以接受的,没有什么问题,但是如果应该执行1秒,却执行了4秒,问题就挺大的了。 今天查看数据库负载,发现在中午12:00 ...

3718
来自专栏技术小讲堂

LINQ to SQL(2):生成对象模型

在LINQ to SQL中,可以使用自己的编程语言的对象模型映射到关系数据库,在上一节课,已经有一部分内容,简单的介绍了一下这种对象模型的结构,这一节,我们主要...

2854

扫码关注云+社区

领取腾讯云代金券