前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ACE - 代码层次及Socket封装

ACE - 代码层次及Socket封装

作者头像
Aichen
发布2018-05-18 11:24:20
1.5K0
发布2018-05-18 11:24:20
举报
文章被收录于专栏:白驹过隙白驹过隙

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的优势和便捷。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-06-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档