• C++之ACE实现通用服务器的C/S架构通信程序


    C++ACE实现通用的服务器C/S架构通信程序
    ACE自适配通信环境(ADAPTIVE Communication Environment)是可以自由使用、
    开放源码的面向对象(OO)框架(Framework),在其中实现了许多用于并发通信软件的核心模式。
    ACE提供了一组丰富的可复用C++ Wrapper Facade(包装外观)和框架组件,
    可跨越多种平台完成通用的通信软件任务,其中包括:
    事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、
    分布式服务动态(重)配置、并发执行和同步,等等。
    ACE的目标用户是高性能和实时通信服务和应用的开发者。
    它简化了使用进程间通信、事件多路分离、显式动态链接和并发的OO网络应用和服务的开发。
    此外,通过服务在运行时与应用的动态链接,ACE还使系统的配置和重配置得以自动化。

    我最近采用ACE实现了一个通用的C/S架构通信程序,具体实现简述如下:
    1. 服务器端:一个采用领导者/跟随者模型的线程池不断地接受从多个客户端发来的消息,
    并放入一个消息队列,然后又有一个采用半同步/半异步模型的线程池不断地从这个消息队列中取出消息进行处理。
    服务器端代码如下:(共10个文件)

      1 //ACE_Server.cpp
      2 #include "ace/SOCK_Acceptor.h"
      3 #include "ace/Acceptor.h"
      4 #include "ace/Thread_Manager.h"
      5 #include "ace/TP_Reactor.h"
      6 #include "ace/Reactor.h"
      7 #include "ace/INET_Addr.h"
      8 #include "ace/OS.h"
      9 #include "Request_Handler.h"
     10 #include "Server.h"
     11 #include "Constants.h"
     12 using namespace ACE_Server;
     13 int main(int argc, char *argv[])
     14 {
     15 ACE_TP_Reactor tp_reactor;
     16 ACE_Reactor reactor(&tp_reactor, 1);
     17 ACE_Reactor::instance(&reactor, 1);
     18 ACE_Acceptor<Request_Handler, ACE_SOCK_ACCEPTOR> acceptor;
     19 ACE_INET_Addr addr(SERVER_PORT_NUM);
     20 if(acceptor.open(addr) == -1)
     21 return -1;
     22 Server server_tp;
     23 server_tp.activate(THR_NEW_LWP | THR_JOINABLE, SERVER_THREAD_POOL_SIZE);
     24 ACE_Thread_Manager::instance()->wait();
     25 return 0;
     26 }
     27 Constants.h
     28 #ifndef __CONSTANTS_H_
     29 #define __CONSTANTS_H_
     30 namespace ACE_Server
     31 {
     32 static const size_t SERVER_THREAD_POOL_SIZE = 5; //进行数据接收的线程池大小
     33 static const size_t TASK_THREAD_POOL_SIZE = 5; //进行数据处理的线程池大小
     34 static const size_t BUFFER_SIZE = 4096; //数据缓冲区大小
     35 static const size_t SERVER_PORT_NUM = 10101; //服务器的通信端口号
     36 }
     37 #endif
     38 ------------------------------------------------------------------------
     39 Server.h
     40 #ifndef __SERVER_H_
     41 #define __SERVER_H_
     42 #include "ace/Task.h"
     43 namespace ACE_Server
     44 {
     45 class Server: public ACE_Task_Base
     46 {
     47 public:
     48 virtual int svc(void);
     49 };
     50 }
     51 #endif
     52 ------------------------------------------------------------------------
     53 Server.cpp
     54 #include "ace/Reactor.h"
     55 #include "Server.h"
     56 namespace ACE_Server
     57 {
     58 int Server::svc(void)
     59 {
     60 int result = ACE_Reactor::instance()->run_reactor_event_loop();
     61 if(result == -1)
     62 return -1;
     63 return 0;
     64 }
     65 }
     66 ------------------------------------------------------------------------
     67 Request_Handler.h
     68 #ifndef __REQUEST_HANDLER_H_
     69 #define __REQUEST_HANDLER_H_
     70 #include "ace/Svc_Handler.h"
     71 #include "ace/SOCK_Stream.h"
     72 #include "ace/Synch.h"
     73 #include "ace/Thread_Manager.h"
     74 #include "Task_Manager.h"
     75 namespace ACE_Server
     76 {
     77 class Request_Handler: public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
     78 {
     79 public:
     80 Request_Handler(ACE_Thread_Manager *thr_mgr = 0);
     81 protected:
     82 virtual int handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE);
     83 private:
     84 static Task_Manager task_mgr;
     85 };
     86 }
     87 #endif
     88 ------------------------------------------------------------------------
     89 Request_Handler.cpp
     90 #include "ace/OS.h"
     91 #include "ace/Message_Block.h"
     92 #include "ace/Thread_Manager.h"
     93 #include "ace/Svc_Handler.h"
     94 #include "ace/SOCK_Stream.h"
     95 #include "ace/Synch.h"
     96 #include "ace/Reactor.h"
     97 #include "Request_Handler.h"
     98 #include "Task_Manager.h"
     99 #include "Constants.h"
    100 namespace ACE_Server
    101 {
    102 Task_Manager Request_Handler::task_mgr;
    103 Request_Handler::Request_Handler(ACE_Thread_Manager *thr_mgr): ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> (thr_mgr)
    104 {
    105 this->reactor(ACE_Reactor::instance());
    106 task_mgr.activate();
    107 }
    108 int Request_Handler::handle_input(ACE_HANDLE fd)
    109 {
    110 char length[4] = {0};
    111 if(this->peer().recv_n(length, 4) == 4)
    112 {
    113 size_t msg_len = 0;
    114 for(int i = 0; i < 4; i++)
    115 {
    116 msg_len |= (size_t)length[i] << (8 * i);
    117 }
    118 char msg[BUFFER_SIZE] = {0};
    119 if(this->peer().recv_n(msg, msg_len) == msg_len)
    120 {
    121 ACE_Message_Block *mb = NULL;
    122 ACE_NEW_RETURN(mb, ACE_Message_Block(msg_len, ACE_Message_Block::MB_DATA, 0, msg), -1);
    123 mb->wr_ptr(msg_len);
    124 task_mgr.putq(mb);
    125 return 0;
    126 }
    127 }
    128 return -1;
    129 }
    130 }
    131 ------------------------------------------------------------------------
    132 Task_Manager.h
    133 #ifndef __TASK_MANAGER_H_
    134 #define __TASK_MANAGER_H_
    135 #include "ace/Task.h"
    136 #include "ace/Synch.h"
    137 namespace ACE_Server
    138 {
    139 class Task_Manager: public ACE_Task<ACE_MT_SYNCH>
    140 {
    141 public:
    142 virtual int svc(void);
    143 };
    144 }
    145 #endif
    146 ------------------------------------------------------------------------
    147 Task_Manager.cpp
    148 #include "ace/Message_Block.h"
    149 #include "Task_Manager.h"
    150 #include "Task_Worker.h"
    151 #include "Constants.h"
    152 namespace ACE_Server
    153 {
    154 int Task_Manager::svc(void)
    155 {
    156 Task_Worker task_tp;
    157 task_tp.activate(THR_NEW_LWP | THR_JOINABLE, TASK_THREAD_POOL_SIZE);
    158 while(1)
    159 {
    160 ACE_Message_Block *mb = NULL;
    161 if(this->getq(mb) < 0)
    162 {
    163 task_tp.msg_queue()->deactivate();
    164 task_tp.wait();
    165 }
    166 task_tp.putq(mb);
    167 }
    168 return 0;
    169 }
    170 }
    171 ------------------------------------------------------------------------
    172 Task_Worker.h
    173 #ifndef __TASK_WORKER_H_
    174 #define __TASK_WORKER_H_
    175 #include "ace/Task.h"
    176 #include "ace/Synch.h"
    177 #include "ace/Message_Block.h"
    178 namespace ACE_Server
    179 {
    180 class Task_Worker: public ACE_Task<ACE_MT_SYNCH>
    181 {
    182 public:
    183 virtual int svc(void);
    184 private:
    185 void process_task(ACE_Message_Block *mb);
    186 };
    187 }
    188 #endif
    189 ------------------------------------------------------------------------
    190 Task_Worker.cpp
    191 #include "ace/OS.h"
    192 #include "ace/Message_Block.h"
    193 #include "Task_Worker.h"
    194 namespace ACE_Server
    195 {
    196 int Task_Worker::svc(void)
    197 {
    198 while(1)
    199 {
    200 ACE_Message_Block *mb = NULL;
    201 if(this->getq(mb) == -1)
    202 {
    203 continue;
    204 }
    205 process_task(mb);
    206 }
    207 return 0;
    208 }
    209 void Task_Worker::process_task(ACE_Message_Block *mb)
    210 {
    211 //进行数据处理,数据的起始地址为mb->rd_ptr(),长度为mb->length()
    212 ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Processing task: %s length %d
    "), mb->rd_ptr(), mb->length()));
    213 ACE_OS::sleep(3); //模拟数据处理过程
    214 mb->release();
    215 }
    216 }
    View Code

    2. 客户端:应用程序将需要发送的若干消息放入一个消息队列,然后激活一个线程来发送所有消息到服务器端。

    客户端代码如下:(共4个文件)

      1 //ACE_Client.cpp
      2 #include "Client.h"
      3 using namespace ACE_Client;
      4 int main(int argc, char *argv[])
      5 {
      6 Client client("localhost"); //服务器的IP地址或者服务器名称
      7 for(int i = 0; i < 5; i++)
      8 {
      9 char *task1 = "Is it a good day?"; //第1个task的数据
     10 size_t task1_len = 18; //第1个task的数据长度
     11 char *task1_t; //无需修改
     12 ACE_NEW_RETURN(task1_t, char[task1_len + 4], -1); //无需修改
     13 client.put_task(task1_t, task1, task1_len); //无需修改
     14 char *task2 = "Yeah, it really is."; //第2个task的数据
     15 size_t task2_len = 20; //第2个task的数据长度
     16 char *task2_t; //无需修改
     17 ACE_NEW_RETURN(task2_t, char[task2_len + 4], -1); //无需修改
     18 client.put_task(task2_t, task2, task2_len); //无需修改
     19 client.send_tasks(); //将上面的task全部发到服务器
     20 delete [] task1_t; //释放task1的内存
     21 delete [] task2_t; //释放task2的内存
     22 }
     23 return 0;
     24 }
     25 ------------------------------------------------------------------------
     26 Constants.h
     27 #ifndef __CONSTANTS_H_
     28 #define __CONSTANTS_H_
     29 #include "ace/Time_Value.h"
     30 namespace ACE_Client
     31 {
     32 static const size_t BUFFER_SIZE = 4096; //数据缓冲区大小
     33 static const size_t SERVER_PORT_NUM = 10101; //服务器的通信端口号
     34 static const ACE_Time_Value TIME_INTERVAL(0, 1000000); //两次数据发送之间的时间间隔(0 s + 1000000 us = 1 s)
     35 }
     36 #endif
     37 ------------------------------------------------------------------------
     38 Client.h
     39 #ifndef __CLIENT_H_
     40 #define __CLIENT_H_
     41 #include "ace/Task.h"
     42 #include "ace/INET_Addr.h"
     43 #include "ace/Synch.h"
     44 namespace ACE_Client
     45 {
     46 class Client: public ACE_Task<ACE_NULL_SYNCH>
     47 {
     48 public:
     49 Client(char *server);
     50 virtual int svc(void);
     51 char *put_task(char *msg_t, char *msg_s, size_t msg_len);
     52 void send_tasks(void);
     53 private:
     54 ACE_INET_Addr addr;
     55 };
     56 }
     57 #endif
     58 ------------------------------------------------------------------------
     59 Client.cpp
     60 #include "ace/OS.h"
     61 #include "ace/SOCK_Stream.h"
     62 #include "ace/SOCK_Connector.h"
     63 #include "ace/Message_Block.h"
     64 #include "ace/Thread_Manager.h"
     65 #include "ace/INET_Addr.h"
     66 #include "Constants.h"
     67 #include "Client.h"
     68 namespace ACE_Client
     69 {
     70 Client::Client(char *server)
     71 {
     72 addr = ACE_INET_Addr(SERVER_PORT_NUM, server);
     73 }
     74 int Client::svc(void)
     75 {
     76 ACE_SOCK_Stream stream;
     77 ACE_SOCK_Connector connector;
     78 if(connector.connect(stream, addr) < 0)
     79 {
     80 return -1;
     81 }
     82 else
     83 {
     84 while(1)
     85 {
     86 ACE_Message_Block *mb = NULL;
     87 if(this->getq(mb) == -1)
     88 {
     89 break;
     90 }
     91 ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Sending %s
    "), &(mb->rd_ptr()[4])));
     92 stream.send_n(mb->rd_ptr(), mb->length());
     93 mb->release();
     94 ACE_OS::sleep(TIME_INTERVAL);
     95 }
     96 }
     97 stream.close();
     98 return 0;
     99 }
    100 char *Client::put_task(char *msg_t, char *msg_s, size_t msg_len)
    101 {
    102 for(int i = 0; i < 4; i++)
    103 {
    104 msg_t[i] = (char)((msg_len >> (8 * i)) & 0xff);
    105 }
    106 ACE_OS::memcpy(&msg_t[4], msg_s, msg_len);
    107 ACE_Message_Block *mb = NULL;
    108 ACE_NEW_RETURN(mb, ACE_Message_Block(msg_len + 4, ACE_Message_Block::MB_DATA, 0, msg_t), 0);
    109 mb->wr_ptr(msg_len + 4);
    110 this->putq(mb);
    111 return msg_t;
    112 }
    113 void Client::send_tasks(void)
    114 {
    115 this->activate();
    116 ACE_Thread_Manager::instance()->wait();
    117 }
    118 }   
    View Code
  • 相关阅读:
    visual studio 2013 生成依赖项关系图出错
    redHat 安装mono 错误
    redHat 安装mono 错误
    msdn帮助,离线下载
    w
    msdn帮助,离线下载
    vs2013 找不到帮助 help查看器
    vs2013 找不到帮助 help查看器
    c# wpf 加密文本
    c# wpf 加密文本
  • 原文地址:https://www.cnblogs.com/jeromesunny/p/3223948.html
Copyright © 2020-2023  润新知