原文出自http://www.cnblogs.com/binchen-china,禁止转载。
ACE源码约10万行,是c++中非常大的一个网络编程代码库,包含了网络编程的边边角角。在实际使用时,并不是所有代码都能用到你的项目中来,相反你只需要其中的一小部分就已经可以完成实际所需。
最近研究其源码最大的感受就是代码量大,资料少,逻辑跳跃大。网上搜了下ACE方面的书籍和资料,也是皮毛上打滚,概念满天飞,侧重讲解如何使用其框架,复杂的底层代码和实现都避而不谈,不如直接看源码来的直接。ACE代码目录结构并不是非常好,很多文件堆在一个路径下面,很阅读难归纳各个文件的功能,源码大量使用模板和导入导出,source insight看的实在汗颜。
ACE代码可以分三个层次:OS层、OO层和框架层:
OO层经常用到的就是Socket封装,这部分内容主要包括以下几个:
封装这四个结构简化了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的优势和便捷。