ACE通用客户端框架

 
http://blog.csdn.net/ishow99/article/details/4266050
上一篇《ACE通用服务端框架》为我们展示了ACE接受器(Acceptor)和连接器(Connector)设计模式的高度集成度,本篇延续上一篇的思路,完成通用客户端的设计和编码。

       由于ACE充分发挥了C++模板技术的优势,是的Connector模式与Acceptor模式在编码上是如此接近。

       好了,开始我们的编码旅程吧。同样的,本框架部分代码来自《The ACE Programmers Guide》7.6 Using the Acceptor-Connector Framework章节和《ACE自适配通信环境中文技术文档-中篇:ACE程序员教程》第七章的思路。

1、main.cpp

              
              
  1. // Base_Client.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include <ace/OS.h>  
  5. #include <ace/Log_Msg.h>  
  6. #include <ace/streams.h>  
  7.   
  8. #include <ace/Reactor.h>  
  9. #include <ace/TP_Reactor.h>  
  10. #include <ace/Select_Reactor.h>  
  11. #include <ace/INET_Addr.h>  
  12. #include <ace/Signal.h>  
  13.   
  14. #include "Global_Define.h"  
  15.   
  16. int ACE_TMAIN (intACE_TCHAR *[])  
  17. {  
  18.     ACE_TP_Reactor *tp_reactor = new ACE_TP_Reactor;  
  19.     ACE_Reactor *reactor = new ACE_Reactor(tp_reactor1);  
  20.     ACE_Reactor::instance(reactor1);  
  21.   
  22.     //ACE_TP_Reactor tp_reactor;  
  23.     //ACE_Reactor reactor(&tp_reactor, 0);  
  24.     //ACE_Reactor::instance(&reactor, 0);  
  25.   
  26.     //ACE_Select_Reactor select_reactor;  
  27.     //ACE_Reactor reactor(&select_reactor, 0);  
  28.     //ACE_Reactor::instance(&reactor, 0);  
  29.   
  30.     GlobalValue g_val;  
  31.     if (g_val.load_config(CONFIG_FILE) == -1)  
  32.         ACE_ERROR_RETURN((LM_ERRORACE_TEXT ("(%P|%t) Load config file fail!")), 1);  
  33.   
  34.     /**************************************************************** 
  35.     * TODO 如果需要,在此处注册信号 
  36.     *****************************************************************/  
  37.   
  38.     ScheduleHandler sh;  
  39.     // 注册信号,处理方法:ScheduleHandler::handle_signal()  
  40.     ACE_Sig_Set sig_set;  
  41.     sig_set.sig_add (SIGINT);  
  42.     sig_set.sig_add (SIGQUIT);  
  43.     sig_set.sig_add (SIGTERM);  
  44.     sig_set.sig_add (SIGSEGV);  
  45.     ACE_Reactor::instance()->register_handler(sig_set, &sh);  
  46.   
  47.     // 注册读取配置文件定时器,处理方法:ScheduleHandler::handle_timeout()  
  48.     ACE_Reactor::instance()->schedule_timer(&sh, (const void *)&g_valACE_Time_Value(10), ACE_Time_Value(10));  
  49.   
  50.     //ACE_INET_Addr port_to_connect(50001, ACE_LOCALHOST);  
  51.     ACE_INET_Addr port_to_connect(g_val.client_portg_val.client_host.c_str());  
  52.     ClientConnector connector;  
  53.   
  54.     do {  
  55.         Client21 client;  
  56.         Client21 *pc = &client;  
  57.         if (connector.connect(pcport_to_connect) == -1)   
  58.         {  
  59.             ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p. %s/n"), ACE_TEXT ("Connect"), ACE_TEXT("Auto re-connect 5 seconds later")));  
  60.   
  61.             ACE_OS::sleep(5);  
  62.             continue;  
  63.         }  
  64.   
  65.         ACE_Reactor::instance()->run_reactor_event_loop();  
  66.   
  67.         client.close();  
  68.   
  69.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) Auto re-connect 3 seconds later/n")));  
  70.         ACE_OS::sleep(3);  
  71.   
  72.         ACE_Reactor::instance()->reset_reactor_event_loop();  
  73.     } while(true);  
  74.   
  75.     ACE_Reactor::instance()->close();  
  76.   
  77.     ACE_Thread_Manager::instance()->wait(&ACE_Time_Value(10));  
  78.   
  79.     ACE_OS::exit(0);  
  80.   
  81.     return (0);  

2、Client21.cpp

              
              
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4. #include <ace/OS.h>  
  5. #include <ace/Log_Msg.h>  
  6. #include <ace/Reactor.h>  
  7. #include <ace/Message_Block.h>  
  8. #include <ace/Synch.h>  
  9. #include <ace/INET_Addr.h>  
  10. #include <ace/Svc_Handler.h>  
  11. #include <ace/SOCK_Stream.h>  
  12. #include <ace/SOCK_Connector.h>  
  13. #include <ace/Connector.h>  
  14. #include <ace/Reactor.h>  
  15. #include <ace/Reactor_Notification_Strategy.h>  
  16.   
  17. #include "Global_Define.h"  
  18.   
  19. /*记录最近一次接入的客户端ACE_SOCK_STREAM,用于控制一次只能允许一个客户端接入的情况*/  
  20. //ACE_SOCK_STREAM * last_peer = NULL;  
  21.   
  22. Client21::Client21(void) : active_(false/*方式2*/ /*notifier_(0, this, ACE_Event_Handler::WRITE_MASK)*/  
  23. {  
  24.     this->active_ = false;  
  25.   
  26.     this->msg_queue()->high_water_mark(SEND_HIGHT_MARK);  
  27.   
  28.     /*方式2*/  
  29.     //this->notifier_.reactor(this->reactor());  
  30.     //this->msg_queue()->notification_strategy(&this->notifier_);  
  31.   
  32.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Client21 start/n")));  
  33.     return;  
  34. }  
  35.   
  36. Client21::~Client21(void)  
  37. {  
  38.     this->active_ = false;  
  39.   
  40.     this->msg_queue()->close();  
  41.   
  42.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Client21 stop/n")));  
  43.     return;  
  44. }  
  45.   
  46. // 在连接建立后被自动回调  
  47. int Client21::open(void *p)  
  48. {  
  49.     if (super::open(p) == -1return -1;  
  50.   
  51.     ACE_TCHAR peer_name[MAXHOSTNAMELEN];  
  52.     ACE_INET_Addr peer_addr;  
  53.     if (this->peer().get_remote_addr(peer_addr) == 0 && peer_addr.addr_to_string (peer_nameMAXHOSTNAMELEN) == 0)  
  54.         ACE_DEBUG((LM_INFOACE_TEXT("(%P|%t) Connected to %s/n"), peer_name));  
  55.   
  56.     this->active_ = true;  
  57.     task_recv.set_active(true);  
  58.     task_send.set_active(true);  
  59.   
  60.     task_recv.set_task_send(&task_send);  
  61.     if (task_recv.activate(THR_NEW_LWP | THR_JOINABLETASK_RECV_POOL_SIZE) == -1)  
  62.     {  
  63.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) TaskRecv activate failed/n")));  
  64.     }  
  65.   
  66.     task_send.set_task_peer((ACE_Task<ACE_MT_SYNCH> *)this);  
  67.     if (task_send.activate(THR_NEW_LWP | THR_JOINABLETASK_SEND_POOL_SIZE) == -1)  
  68.     {  
  69.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) TaskSend activate failed/n")));  
  70.     }  
  71.   
  72.     /*回调*/  
  73.     this->start_0();  
  74.   
  75.     /*开启定时处理线程*/  
  76.     ACE_Time_Value interval(1); // One seconds  
  77.     return this->reactor()->schedule_timer(this0ACE_Time_Value::zerointerval);  
  78.     //return 0;  
  79. }  
  80.   
  81. // 客户端接收到服务端发送的数据后,回调此函数  
  82. int Client21::handle_input(ACE_HANDLE)  
  83. {  
  84.     char buffer[INPUT_SIZE] = {0};  
  85.     ssize_t recv_cnt = 0;  
  86.   
  87. #if (MSG_HEAD_MODE==1) /*接收消息头模式*/  
  88.   
  89.     /**************************************************************** 
  90.     * TODO 根据实际消息头格式修改解析方法 
  91.     *****************************************************************/  
  92.   
  93.     ssize_t msg_len = 0;  
  94.   
  95.     recv_cnt = this->peer().recv(bufferMSG_HEAD_SIZE);  
  96.   
  97.     if (recv_cnt > 0 && recv_cnt == MSG_HEAD_SIZE)  
  98.     {  
  99.         /************************* 
  100.         * TODO 注意这里的4个字节 
  101.         **************************/  
  102.         msg_len = SET_BYTE4(buffer[0]&0xFF) + SET_BYTE3(buffer[1]&0xFF) + SET_BYTE2(buffer[2]&0xFF) + SET_BYTE1(buffer[3]&0xFF);  
  103.         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Message length (%d) %s/n"), msg_lenmsg_len<INPUT_SIZE-MSG_HEAD_SIZE?ACE_TEXT(""):ACE_TEXT(": warning!!! out of range")));  
  104.   
  105.         if (msg_len > 0 && msg_len < INPUT_SIZE-MSG_HEAD_SIZE)  
  106.         {  
  107.             if (msg_len == MSG_HEAD_SIZE)  
  108.             {  
  109.                 ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Recv(%d+%d):[%s]/n"), MSG_HEAD_SIZEmsg_len-MSG_HEAD_SIZEbuffer));  
  110.   
  111.                 ACE_Message_Block *mb = NULL;  
  112.                 ACE_NEW_RETURN(mbACE_Message_Block(msg_len+1), -1);  
  113.                 ACE_OS::memcpy(mb->wr_ptr(), buffermsg_len);  
  114.                 mb->wr_ptr(msg_len);  
  115.   
  116.                 if (task_recv.putq(mb) == -1)  
  117.                 {  
  118.                     ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("Client21 enqueue to TaskRecv failed")));  
  119.                     mb->release();  
  120.                     return 0;  
  121.                 }  
  122.   
  123.                 return 0;  
  124.             }  
  125.             else  
  126.             {  
  127.                 recv_cnt = this->peer().recv(buffer+MSG_HEAD_SIZE, (msg_len-MSG_HEAD_SIZE));  
  128.   
  129.                 if (recv_cnt > 0 && recv_cnt == (msg_len-MSG_HEAD_SIZE))  
  130.                 {  
  131.                     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Recv(%d+%d):[%s]/n"), MSG_HEAD_SIZEmsg_len-MSG_HEAD_SIZEbuffer));  
  132.   
  133.                     ACE_Message_Block *mb = NULL;  
  134.                     ACE_NEW_RETURN(mbACE_Message_Block(msg_len+1), -1);  
  135.                     ACE_OS::memcpy(mb->wr_ptr(), buffermsg_len);  
  136.                     mb->wr_ptr(msg_len);  
  137.   
  138.                     if (task_recv.putq(mb) == -1)  
  139.                     {  
  140.                         ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("Client21 enqueue to TaskRecv failed")));  
  141.                         mb->release();  
  142.                         return 0;  
  143.                     }  
  144.   
  145.                     return 0;  
  146.                 }  
  147.   
  148.                 if (recv_cnt <= 0 || ACE_OS::last_error() != EWOULDBLOCK)  
  149.                 {  
  150.                     this->active_ = false;  
  151.   
  152.                     ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) Connection closed1/n")));  
  153.   
  154.                     /*表示客户端已断开*/  
  155.                     return -1;  
  156.                 }  
  157.             }  
  158.         }  
  159.   
  160.         return 0;  
  161.     }  
  162.   
  163.     if (recv_cnt <= 0 || ACE_OS::last_error() != EWOULDBLOCK)  
  164.     {  
  165.         this->active_ = false;  
  166.   
  167.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) Connection closed/n")));  
  168.   
  169.         /*表示客户端已断开*/  
  170.         return -1;  
  171.     }  
  172.   
  173. #else /*不接收消息头模式*/  
  174.       
  175.     recv_cnt = this->peer().recv(buffersizeof(buffer));  
  176.   
  177.     if (recv_cnt > 0)  
  178.     {  
  179.         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Recv(%d):[%s]/n"), recv_cntbuffer));  
  180.   
  181.         ACE_Message_Block *mb = NULL;  
  182.         ACE_NEW_RETURN(mbACE_Message_Block(recv_cnt+1), -1);  
  183.         ACE_OS::memcpy(mb->wr_ptr(), bufferrecv_cnt);  
  184.         mb->wr_ptr(recv_cnt);  
  185.   
  186.         if (task_recv.putq(mb) == -1)  
  187.         {  
  188.             ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("Client21 enqueue to TaskRecv failed")));  
  189.             mb->release();  
  190.             return 0;  
  191.         }  
  192.   
  193.         return 0;  
  194.     }  
  195.   
  196.     if (recv_cnt <= 0 || ACE_OS::last_error() != EWOULDBLOCK)  
  197.     {  
  198.         this->active_ = false;  
  199.   
  200.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) Connection closed/n")));  
  201.   
  202.         /*表示客户端已断开*/  
  203.         return -1;  
  204.     }  
  205.   
  206. #endif  
  207.   
  208.     return 0;  
  209. }  
  210.   
  211. // 客户端向服务端发送数据时,回调此函数  
  212. int Client21::handle_output (ACE_HANDLE)  
  213. {  
  214.     ACE_Message_Block *mb;  
  215.     ACE_Time_Value nowait (ACE_OS::gettimeofday ());  
  216.     while (!this->msg_queue()->is_empty())  
  217.         if (-1 != this->getq(mb, &nowait))  
  218.         {  
  219.             ssize_t send_cnt = this->peer().send (mb->rd_ptr(), mb->length());  
  220.             if (send_cnt == -1)  
  221.             {  
  222.                 ACE_ERROR ((LM_ERRORACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("Client21 send")));  
  223.             }  
  224.             else  
  225.             {  
  226.                 ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Send(%d):[%s]/n"), send_cntmb->rd_ptr()));  
  227.                 mb->rd_ptr(ACE_static_cast(size_tsend_cnt));  
  228.             }  
  229.   
  230.             mb->release ();  
  231.         }  
  232.   
  233.     /*方式2*/  
  234. /* 
  235.     if (this->msg_queue()->is_empty()) 
  236.         this->reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK); 
  237.     else 
  238.         this->reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK); 
  239. */  
  240.   
  241.     /*(方法1)*/ this->reactor()->cancel_wakeup(thisACE_Event_Handler::WRITE_MASK);  
  242.   
  243.     return 0;  
  244. }  
  245.   
  246. // 定时处理函数  
  247. int Client21::handle_timeout(const ACE_Time_Value ¤t_timeconst void *act)  
  248. {  
  249.     if (this->active_ != truereturn 0;  
  250.   
  251.     this->timeout_0();  
  252.   
  253.     return 0;  
  254. }  
  255.   
  256.   
  257. // 服务端断开时,回调此函数  
  258. int Client21::handle_close (ACE_HANDLE hACE_Reactor_Mask mask)  
  259. {  
  260.     if (mask == ACE_Event_Handler::WRITE_MASK)  
  261.         return 0;  
  262.     else  
  263.     {  
  264.         ACE_TCHAR peer_name[MAXHOSTNAMELEN];  
  265.         ACE_INET_Addr peer_addr;  
  266.         if (this->peer().get_remote_addr(peer_addr) == 0 && peer_addr.addr_to_string (peer_nameMAXHOSTNAMELEN) == 0)  
  267.             ACE_DEBUG((LM_INFOACE_TEXT("(%P|%t) Disconnected %s/n"), peer_name));  
  268.   
  269.         /*释放队列资源*/  
  270.         task_send.set_active(false);  
  271.         task_recv.set_active(false);  
  272.         this->set_active(false);  
  273.   
  274.         task_send.msg_queue()->close();  
  275.         task_recv.msg_queue()->close();  
  276.         this->msg_queue()->close();  
  277.   
  278.         task_send.wait();  
  279.         task_recv.wait();  
  280.         this->wait();  
  281.   
  282.         /*回调*/  
  283.         this->stop_0();  
  284.   
  285.         /*关闭链路*/  
  286.         this->peer().close_reader();  
  287.         this->peer().close_writer();  
  288.         this->peer().close();  
  289.   
  290.         return super::handle_close (hmask);  
  291.     }  
  292. }  
  293.   
  294. /**********************************************************************************************************************************/  
  295.   
  296. void Client21::set_active(bool b)  
  297. {  
  298.     this->active_ = b;  
  299. }  
  300.   
  301. bool Client21::get_active()  
  302. {  
  303.     return this->active_;  
  304. }  
  305.   
  306. /**********************************************************************************************************************************/  
  307.   
  308. void Client21::start_0()  
  309. {  
  310.     /* 
  311.     if (last_peer != NULL) 
  312.     { 
  313.     last_peer->close_reader(); 
  314.     last_peer->close_writer(); 
  315.     last_peer->close(); 
  316.     } 
  317.     last_peer = &this->peer(); 
  318.     */  
  319.   
  320.     /**************************************************************** 
  321.     * TODO 可以在此实现接入服务端后需要的初始化工作 - (已经实际接入) 
  322.     *****************************************************************/  
  323.   
  324. }  
  325.   
  326. void Client21::stop_0()  
  327. {  
  328.     //if (last_peer == &this->peer()) last_peer = NULL;  
  329.   
  330.     if (this->get_active() == true)  
  331.     {  
  332.         /*退出客户端*/  
  333.         this->reactor()->end_reactor_event_loop();  
  334.     }  
  335.   
  336.     /**************************************************************** 
  337.     * TODO 可以在此实现断开服务端后需要执行的工作 
  338.     *****************************************************************/  
  339.   
  340. }  
  341.   
  342. void Client21::timeout_0()  
  343. {  
  344.     /**************************************************************** 
  345.     * TODO 实现客户端定时任务,如发送心跳等 
  346.     *****************************************************************/  
  347.   
  348.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) handle_timeout/n")));  
  349.   

3、TaskRecv.cpp

              
              
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4. #include "Global_Define.h"  
  5.   
  6. #include <ace/OS.h>  
  7. #include <ace/Message_Block.h>  
  8. #include <ace/Log_Msg.h>  
  9.   
  10. //处理接收队列  
  11. int TaskRecv::svc(void)  
  12. {  
  13.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskRecv::svc() start/n")));  
  14.   
  15.     while (this->active_==true)  
  16.     {  
  17.         ACE_Message_Block *mb = NULL;  
  18.         if (this->getq(mb) == -1)  
  19.         {  
  20.             continue;  
  21.         }  
  22.   
  23.         process_recv(mb);  
  24.     }  
  25.   
  26.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskRecv::svc() stop/n")));  
  27.     return 0;  
  28. }  
  29.   
  30. void TaskRecv::process_recv(ACE_Message_Block *mb)  
  31. {  
  32.     char * data = mb->rd_ptr();  
  33.     size_t data_size = mb->length();  
  34.   
  35.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Processing recv message: length %d : %s/n"), data_sizedata));  
  36.   
  37.     /**************************************************************** 
  38.     * TODO 处理接收到的对等端数据,数据的起始地址为data,长度为data_size 
  39.     *****************************************************************/  
  40.   
  41.     ACE_OS::sleep(3);  
  42.   
  43.     //如何发送的例子  
  44.     send_msg(datadata_size);  
  45.   
  46.   
  47.   
  48.     //数据处理结束必需释放内存  
  49.     mb->release();  
  50. }  
  51.   
  52. //向对等端发送数据,实际操作是向发送队列插入一条 ACE_Message_Block  
  53. //返回 -1:失败 >=0:发送数据长度  
  54. int TaskRecv::send_msg(char * _bufsize_t _size)  
  55. {  
  56.     if (_size == 0return 0;  
  57.     if (this->active_ != truereturn -1;  
  58.   
  59.     return this->task_send_->send_msg(_buf_size);  
  60. }  
  61.   
  62. /**********************************************************************************************************************************/  
  63.   
  64. void TaskRecv::set_active(bool b)  
  65. {  
  66.     this->active_ = b;  
  67. }  
  68.   
  69. bool TaskRecv::get_active()  
  70. {  
  71.     return this->active_;  
  72. }  
  73.   
  74. void TaskRecv::set_task_send(TaskSend *_task_send)  
  75. {  
  76.     if (!this->task_send_)   
  77.     {  
  78.         this->task_send_ = _task_send;  
  79.     }  
  80. }  
  81.   
  82. TaskSend * TaskRecv::get_task_send()  
  83. {  
  84.     return this->task_send_;  

4、TaskSend.cpp

              
              
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4. #include "Global_Define.h"  
  5.   
  6. #include <ace/OS.h>  
  7. #include <ace/Message_Block.h>  
  8. #include <ace/Log_Msg.h>  
  9.   
  10. //处理发送队列  
  11. int TaskSend::svc(void)  
  12. {  
  13.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskSend::svc() start/n")));  
  14.   
  15.     while (this->active_==true)  
  16.     {  
  17.         ACE_Message_Block *mb = NULL;  
  18.         if (this->getq(mb) == -1)  
  19.         {  
  20.             continue;  
  21.         }  
  22.   
  23.         process_send(mb);  
  24.     }  
  25.   
  26.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskSend::svc() stop/n")));  
  27.     return 0;  
  28. }  
  29.   
  30. void TaskSend::process_send(ACE_Message_Block *mb)  
  31. {  
  32.     if (((Client21 *)this->task_peer_)->get_active() != truereturn;  
  33.   
  34.     char * data = mb->rd_ptr();  
  35.     size_t data_size = mb->length();  
  36.   
  37.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Processing send message: length %d : %s/n"), data_sizedata));  
  38.   
  39.     if (this->task_peer_->putq(mb) == -1)  
  40.     {  
  41.         ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("TaskSend enqueue to Svc_Handler failed")));  
  42.         mb->release();  
  43.     }  
  44.     /*(方法1)*/ this->task_peer_->reactor()->schedule_wakeup(this->task_peer_ACE_Event_Handler::WRITE_MASK);  
  45. }  
  46.   
  47. /**********************************************************************************************************************************/  
  48.   
  49. void TaskSend::set_active(bool b)  
  50. {  
  51.     this->active_ = b;  
  52. }  
  53.   
  54. bool TaskSend::get_active()  
  55. {  
  56.     return this->active_;  
  57. }  
  58.   
  59. void TaskSend::set_task_peer(ACE_Task<ACE_MT_SYNCH> * _task_peer_)  
  60. {  
  61.     if (!this->task_peer_)   
  62.     {  
  63.         this->task_peer_ = _task_peer_;  
  64.     }  
  65. }  
  66.   
  67. ACE_Task<ACE_MT_SYNCH> * TaskSend::get_task_peer()  
  68. {  
  69.     return this->task_peer_;  
  70. }  
  71.   
  72. /**********************************************************************************************************************************/  
  73.   
  74. // 可以调用此方法向对等端发送数据,实际操作是向发送队列插入一条 ACE_Message_Block  
  75. // 返回 -1:失败 >=0:发送数据长度  
  76. int TaskSend::send_msg(char * _bufsize_t _size)  
  77. {  
  78.     if (_size==0return 0;  
  79.     if (this->active_ != truereturn -1;  
  80.   
  81.     ACE_Message_Block *mb = NULL;  
  82.     ACE_NEW_RETURN(mbACE_Message_Block(_size+1), -1);  
  83.     ACE_OS::memcpy(mb->wr_ptr(), _buf_size);  
  84.     mb->wr_ptr(_size);  
  85.   
  86.     if (this->putq(mb) == -1)  
  87.     {  
  88.         ACE_DEBUG((LM_ERRORACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("TaskSend enqueue failed")));  
  89.         mb->release();  
  90.         return -1;  
  91.     }  
  92.   
  93.     return _size;  
5、ScheduleHandler.cpp

              
              
  1. /******************************************************************************************** 
  2. * huangjf 2009年5月 于福州 
  3. ********************************************************************************************/  
  4.   
  5. #include "ace/OS.h"  
  6. #include "ace/Reactor.h"  
  7. #include "ace/Timer_Queue.h"  
  8. #include "ace/Time_Value.h"  
  9. #include "ace/Event_Handler.h"  
  10. #include "ace/Log_Msg.h"  
  11.   
  12. #include "Global_Define.h"  
  13.   
  14. // 定时任务,定时更新配置参数  
  15. int ScheduleHandler::handle_timeout(const ACE_Time_Value &c_tvconst void *arg)  
  16. {  
  17.     GlobalValue * _val = (GlobalValue *)arg;  
  18.   
  19.     _val->load_config(CONFIG_FILE);  
  20.   
  21.     return 0;  
  22. }  
  23.   
  24. // 信号处理  
  25. int ScheduleHandler::handle_signal(int signumsiginfo_t *, ucontext_t *)  
  26. {  
  27.     ACE_UNUSED_ARG (signum);  
  28.   
  29.     ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) Receive system signal %d./n"), signum));  
  30.   
  31.     /**************************************************************** 
  32.     * TODO 如果需要,在此处理信号,信号必需已注册 
  33.     *****************************************************************/  
  34.   
  35.     ACE_OS::exit(0);  
  36.   
  37.     return 0;  

6、Config.cpp

              
              
  1. /******************************************************************************************** 
  2. * huangjf 2009年5月 于福州 
  3. ********************************************************************************************/  
  4.   
  5. #include "Global_Define.h"  
  6.   
  7. #include <ace/OS.h>  
  8. #include <ace/Configuration.h>  
  9. #include <ace/Configuration_Import_Export.h>  
  10.   
  11. // 载入配置文件  
  12. int GlobalValue::load_config(const charconfig_filename_)  
  13. {  
  14.     ACE_TString str;  
  15.     long num = 0;  
  16.   
  17.     ACE_Configuration_Heap config;  
  18.     if (config.open() == -1)  
  19.     {  
  20.         ACE_ERROR_RETURN((LM_ERRORACE_TEXT("(%P|%t) %p/n"), ACE_TEXT("config.open()")), -1);  
  21.     }  
  22.   
  23.     ACE_Ini_ImpExp config_importer(config);  
  24.     if (config_importer.import_config(config_filename_) == -1)  
  25.     {  
  26.         ACE_ERROR_RETURN((LM_ERRORACE_TEXT("(%P|%t) %p/n"), ACE_TEXT(config_filename_)), -1);  
  27.     }  
  28.   
  29.     ACE_Configuration_Section_Key status_section;  
  30.     if (config.open_section (config.root_section(), ACE_TEXT("SYSTEM"), 0status_section) == -1)  
  31.     {  
  32.         ACE_ERROR_RETURN ((LM_ERRORACE_TEXT("(%P|%t) %p/n"), ACE_TEXT ("Can't open [SYSTEM] section")), -1);  
  33.     }  
  34.   
  35.     // 服务地址  
  36.     if (config.get_string_value(status_sectionACE_TEXT("CLIENT_HOST"), str) != -1)  
  37.     {  
  38.         if (str.compare(this->client_host) != 0)  
  39.         {  
  40.             ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_HOST' is updated (%s)->(%s)/n"), this->client_host.c_str(), str.c_str()));  
  41.             this->client_host = str;  
  42.         }  
  43.         str.clear();  
  44.     }  
  45.     else  
  46.     {  
  47.         this->client_host.clear();  
  48.         this->client_host = ACE_TEXT("127.0.0.1");  
  49.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_HOST' does not exist, default value is (%s)/n"), this->client_host.c_str()));  
  50.     }  
  51.   
  52.     // 服务端口  
  53.     if (config.get_string_value(status_sectionACE_TEXT("CLIENT_PORT"), str) != -1)  
  54.     {  
  55.         try  
  56.         {  
  57.             num = ACE_OS::strtol(str.c_str(), NULL10);  
  58.             if (num != this->client_port)  
  59.             {  
  60.                 ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_PORT' is updated (%d)->(%d)/n"), this->client_portnum));  
  61.                 this->client_port = static_cast<u_short> (num);  
  62.             }  
  63.         }  
  64.         catch (...)  
  65.         {  
  66.             this->client_port = 50001;  
  67.             ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_PORT' is catch exception, default value is (%d)/n"), this->client_port));  
  68.         }  
  69.         num = 0;  
  70.     }  
  71.     else  
  72.     {  
  73.         this->client_port = 50001;  
  74.         ACE_DEBUG((LM_ERRORACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_PORT' does not exist, default value is (%d)/n"), this->client_port));  
  75.     }  
  76.   
  77.     /**************************************************************** 
  78.     * TODO 在此增加读取配置文件的参数 
  79.     *****************************************************************/  
  80.   
  81.   
  82.     return 0;  

7、Global_Define.h


  • /******************************************************************************************** 
  • * huangjf 2009年4月 于宁夏银川 
  • ********************************************************************************************/  
  • #ifndef _Global_Define_h  
  • #define _Global_Define_h  
  •   
  • #include <ace/Task.h>  
  • #include <ace/Synch.h>  
  • #include <ace/INET_Addr.h>  
  • #include <ace/Svc_Handler.h>  
  • #include <ace/SOCK_Stream.h>  
  • #include <ace/SOCK_Connector.h>  
  • #include <ace/Connector.h>  
  • #include <ace/Reactor.h>  
  • #include <ace/Reactor_Notification_Strategy.h>  
  •   
  • #define RECV_HIGHT_MARK 8*1024 /*接收队列高水位标*/  
  • #define SEND_HIGHT_MARK 8*1024 /*发送队列高水位标*/  
  • #define INPUT_SIZE 4*1024 /*接收数据缓冲区大小*/  
  • #define TASK_RECV_POOL_SIZE 8 //处理服务器接收到的客户端数据队列的线程池大小  
  • #define TASK_SEND_POOL_SIZE 1 //处理服务器向客户端发送的数据队列的线程池大小  
  •   
  • #define MSG_HEAD_MODE 0 /*表示是否采用消息头模式,0:表示不使用,1:表示使用*/  
  • #define MSG_HEAD_SIZE 12  
  •   
  • #define CONFIG_FILE "../config/config.cfg"  
  •   
  • #define GET_BYTE1(a)    (  (a)%0x100 ) /*低1字节*/  
  • #define GET_BYTE2(a)    ( ((a)/0x100)%0x100 ) /*低2字节*/  
  • #define GET_BYTE3(a)    ( ((a)/0x10000)%0x100 ) /*低3字节*/  
  • #define GET_BYTE4(a)    ( ((a)/0x1000000)%0x100 ) /*低4字节*/  
  •   
  • #define SET_BYTE1(a)    ( (a) ) /*低1字节*/  
  • #define SET_BYTE2(a)    ( (a)*0x100 ) /*低2字节*/  
  • #define SET_BYTE3(a)    ( (a)*0x10000 ) /*低3字节*/  
  • #define SET_BYTE4(a)    ( (a)*0x1000000 ) /*低4字节*/  
  •   
  • /**********************************************************************************************************************************/  
  •   
  • /******************************************************************************************** 
  • * TODO 全局参数类,在此增加全局参数 
  • ********************************************************************************************/  
  • class GlobalValue  
  • {  
  • public:  
  •     ACE_TString client_host/*客户端主机地址*/  
  •     u_short client_port/*客户端监听端口*/  
  •   
  •     int load_config(const charconfig_filename_);  
  • };  
  •   
  • /**********************************************************************************************************************************/  
  •   
  • /******************************************************************************************** 
  • * 采用ACE_Task任务或主动对象处理模式,处理服务器向客户端发送的数据队列 
  • ********************************************************************************************/  
  • class TaskSendpublic ACE_Task<ACE_MT_SYNCH>  
  • {  
  • public:  
  •     TaskSend() : active_(false), task_peer_(NULL)   
  •     {  
  •         this->active_ = false;  
  •         this->msg_queue()->high_water_mark(SEND_HIGHT_MARK);  
  •         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskSend start/n")));  
  •     }  
  •   
  •     virtual ~TaskSend()  
  •     {  
  •         this->active_ = false;  
  •         this->msg_queue()->close();  
  •         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskSend stop/n")));  
  •     }  
  •   
  •     virtual int svc(void);  
  •   
  •     void set_active(bool b);  
  •     bool get_active();  
  •   
  •     void set_task_peer(ACE_Task<ACE_MT_SYNCH> * _task_peer_);  
  •     ACE_Task<ACE_MT_SYNCH> * get_task_peer();  
  •   
  •     int send_msg(char * _bufsize_t _size);  
  •   
  • private:  
  •     bool active_;  
  •   
  •     ACE_Task<ACE_MT_SYNCH> * task_peer_;  
  •   
  •     void process_send(ACE_Message_Block *mb = NULL);  
  • };  
  •   
  • /******************************************************************************************** 
  • * 采用ACE_Task任务或主动对象处理模式,处理服务器接收到的客户端数据队列 
  • ********************************************************************************************/  
  • class TaskRecvpublic ACE_Task<ACE_MT_SYNCH>  
  • {  
  • public:  
  •     TaskRecv() : active_(false), task_send_(NULL)   
  •     {  
  •         this->active_ = false;  
  •         this->msg_queue()->high_water_mark(RECV_HIGHT_MARK);  
  •         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskRecv start/n")));  
  •     }  
  •   
  •     virtual ~TaskRecv()   
  •     {  
  •         this->active_ = false;  
  •         this->msg_queue()->close();  
  •         ACE_DEBUG((LM_DEBUGACE_TEXT("(%P|%t) TaskRecv stop/n")));  
  •     }  
  •   
  •     virtual int svc(void);  
  •   
  •     void set_active(bool b);  
  •     bool get_active();  
  •   
  •     void set_task_send(TaskSend *_task_send);  
  •     TaskSend * get_task_send();  
  •   
  • private:  
  •     bool active_;  
  •   
  •     TaskSend *task_send_;  
  •   
  •     void process_recv(ACE_Message_Block *mb = NULL);  
  •     int send_msg(char * _bufsize_t _size);  
  • };  
  •   
  • /******************************************************************************************** 
  • * 采用ACE连接器(Connector)连接建立模式,实现双工单路客户端 
  • ********************************************************************************************/  
  • class Client21 : public ACE_Svc_Handler<ACE_SOCK_STREAMACE_MT_SYNCH>  
  • {  
  •     typedef ACE_Svc_Handler<ACE_SOCK_STREAMACE_MT_SYNCHsuper;  
  •   
  • public:  
  •     Client21(void);  
  •   
  •     virtual ~Client21(void);  
  •   
  •     // 在连接建立后被自动回调  
  •     virtual int open (void * = 0);  
  •   
  •     // Called when input is available from the client.  
  •     virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  •   
  •     // Called when output is possible.  
  •     virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  •   
  •     // Called when a timer expires.  
  •     virtual int handle_timeout (const ACE_Time_Value ¤t_timeconst void *act = 0);  
  •   
  •     // Called when this handler is removed from the ACE_Reactor.  
  •     virtual int handle_close(ACE_HANDLE handleACE_Reactor_Mask close_mask);  
  •   
  •     void set_active(bool b);  
  •     bool get_active();  
  •   
  • private:  
  •     bool active_;  
  •   
  •     TaskRecv task_recv;  
  •     TaskSend task_send;  
  •   
  •     /******************************************************************************************** 
  •     * 策略类,实现了Strategy模式。如果ACE_Message_Queue拥有一个策略对象,无论何时有ACE_Message_Block对象 
  •     * 进入队列,ACE_Message_Queue都会调用该策略对象的notify()方法,把一个通知放入队列,通知的目标是对象的handle_output()方法 
  •     ********************************************************************************************/  
  •     /*方式2*/ //ACE_Reactor_Notification_Strategy notifier_;   
  •   
  •     /*回调函数,使用者在此实现对应功能*/  
  •     void start_0(); /*对等端接入后回调*/  
  •     void stop_0(); /*对等端关闭后回调*/  
  •     void timeout_0(); /*定时任务*/  
  • };  
  •   
  • /**********************************************************************************************************************************/  
  •   
  • /******************************************************************************************** 
  • * 应用程序定时任务,及信号处理 
  • ********************************************************************************************/  
  • class ScheduleHandler : public ACE_Event_Handler  
  • {  
  • public:  
  •     virtual int handle_timeout(const ACE_Time_Value ¤t_timeconst void *act = 0);  
  •   
  •     virtual int handle_signal(int signumsiginfo_t * = 0ucontext_t * = 0);  
  • };  
  •   
  • /**********************************************************************************************************************************/  
  •   
  • typedef ACE_Connector<Client21ACE_SOCK_CONNECTORClientConnector;  
  •   
  • #endif 

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值