ACE通用network框架

来源:互联网 发布:java虚拟主机 编辑:程序博客网 时间:2024/05/15 02:19

认真学习了《The ACE Programmers Guide》中7.6 Using the Acceptor-Connector Framework章节,整理了通用服务端和客户端框架,首次在网络上共享学习成果,希望对大家有所帮助。

    不爱废话,开始我们的编码旅程。补充一句,学习ACE不得不研读一下《ACE自适配通信环境中文技术文档-中篇:ACE程序员教程》这份文档,作者和马维达的翻译团队严谨的态度值得我们赞赏。

 

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

 

1、main.cpp

[cpp] view plaincopy
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4.   
  5. #include <ace/OS.h>  
  6. #include <ace/Log_Msg.h>  
  7. #include <ace/streams.h>  
  8.   
  9. #include <ace/Reactor.h>  
  10. #include <ace/TP_Reactor.h>  
  11. #include <ace/Select_Reactor.h>  
  12. #include <ace/INET_Addr.h>  
  13. #include <ace/Signal.h>  
  14.   
  15. #include "Global_Define.h"  
  16.   
  17. int ACE_TMAIN(int argc, ACE_TCHAR* argv[])  
  18. {  
  19.     ACE_TP_Reactor *tp_reactor = new ACE_TP_Reactor;  
  20.     ACE_Reactor *reactor = new ACE_Reactor(tp_reactor, 1);  
  21.     ACE_Reactor::instance(reactor, 1);  
  22.   
  23.     //ACE_Select_Reactor *select_reactor = new ACE_Select_Reactor;  
  24.     //ACE_Reactor *reactor = new ACE_Reactor(select_reactor, 1);  
  25.     //ACE_Reactor::instance(reactor, 1);  
  26.   
  27.     //ACE_TP_Reactor tp_reactor;  
  28.     //ACE_Reactor reactor(&tp_reactor, 0);  
  29.     //ACE_Reactor::instance(&reactor, 0);  
  30.   
  31.     //ACE_Select_Reactor select_reactor;  
  32.     //ACE_Reactor reactor(&select_reactor, 0);  
  33.     //ACE_Reactor::instance(&reactor, 0);  
  34.   
  35.     ScheduleHandler sh;  
  36.     GlobalValue g_val;  
  37.     if (g_val.load_config(CONFIG_FILE) == -1)  
  38.         ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("(%P|%t) Load config file fail!")), 1);  
  39.   
  40.     ACE_INET_Addr port_to_listen(g_val.port, g_val.host.c_str());  
  41.     ServerAcceptor acceptor;  
  42.   
  43.     do   
  44.     {  
  45.         if (acceptor.open(port_to_listen) == -1)  
  46.         {  
  47.             ACE_DEBUG((LM_ERROR, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("Listen fail")));  
  48.   
  49.             ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) Auto re-listen 10 seconds later./n")));  
  50.             ACE_OS::sleep(10);  
  51.             continue;  
  52.         }  
  53.         break;  
  54.     } while (true);  
  55.     ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Listen at %s:%d .../n"), port_to_listen.get_host_addr(), port_to_listen.get_port_number()));  
  56.   
  57.     /**************************************************************** 
  58.     * TODO 如果需要,在此处注册信号 
  59.     *****************************************************************/  
  60.   
  61.     // 注册信号,处理方法:ScheduleHandler::handle_signal()  
  62.     ACE_Sig_Set sig_set;  
  63.     sig_set.sig_add (SIGINT);  
  64.     sig_set.sig_add (SIGQUIT);  
  65.     sig_set.sig_add (SIGTERM);  
  66.     sig_set.sig_add (SIGSEGV);  
  67.     ACE_Reactor::instance()->register_handler(sig_set, &sh);  
  68.   
  69.     // 注册读取配置文件定时器,处理方法:ScheduleHandler::handle_timeout()  
  70.     ACE_Reactor::instance()->schedule_timer(&sh, (const void *)&g_val, ACE_Time_Value(10), ACE_Time_Value(10));  
  71.   
  72.     ACE_Reactor::instance()->run_reactor_event_loop();  
  73.   
  74.     acceptor.close();  
  75.   
  76.     ACE_Reactor::instance()->close();  
  77.   
  78.     ACE_Thread_Manager::instance()->wait(&ACE_Time_Value(10));  
  79.   
  80.     ACE_OS::exit(0);  
  81.   
  82.     return 0;  
  83. }  

 

2、Server.cpp

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

 

3、TaskRecv.cpp

[cpp] view plaincopy
  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_DEBUG, ACE_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_DEBUG, ACE_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_DEBUG, ACE_TEXT("(%P|%t) Processing recv message: length %d : %s/n"), data_size, data));  
  36.   
  37.     /**************************************************************** 
  38.     * TODO 处理接收到的对等端数据,数据的起始地址为data,长度为data_size 
  39.     *****************************************************************/  
  40.   
  41.     ACE_OS::sleep(3);  
  42.   
  43.     //如何发送的例子  
  44.     send_msg(data, data_size);  
  45.   
  46.   
  47.   
  48.     //数据处理结束必需释放内存  
  49.     mb->release();  
  50. }  
  51.   
  52. //向对等端发送数据,实际操作是向发送队列插入一条 ACE_Message_Block  
  53. //返回 -1:失败 >=0:发送数据长度  
  54. int TaskRecv::send_msg(char * _buf, size_t _size)  
  55. {  
  56.     if (_size == 0) return 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_;  
  85. }  

 

4、TaskSend.cpp

[cpp] view plaincopy
  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_DEBUG, ACE_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_DEBUG, ACE_TEXT("(%P|%t) TaskSend::svc() stop/n")));  
  27.     return 0;  
  28. }  
  29.   
  30. void TaskSend::process_send(ACE_Message_Block *mb)  
  31. {  
  32.     if (((Server21 *)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_DEBUG, ACE_TEXT("(%P|%t) Processing send message: length %d : %s/n"), data_size, data));  
  38.   
  39.     if (this->task_peer_->putq(mb) == -1)  
  40.     {  
  41.         ACE_DEBUG((LM_ERROR, ACE_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 * _buf, size_t _size)  
  77. {  
  78.     if (_size==0) return 0;  
  79.     if (this->active_ != truereturn -1;  
  80.   
  81.     ACE_Message_Block *mb = NULL;  
  82.     ACE_NEW_RETURN(mb, ACE_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_ERROR, ACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("TaskSend enqueue failed")));  
  89.         mb->release();  
  90.         return -1;  
  91.     }  
  92.   
  93.     return _size;  
  94. }  

 

5、ScheduleHandler.cpp

[cpp] view plaincopy
  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_tv, const 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 signum, siginfo_t *, ucontext_t *)  
  26. {  
  27.     ACE_UNUSED_ARG (signum);  
  28.   
  29.     ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Receive system signal %d./n"), signum));  
  30.   
  31.     /**************************************************************** 
  32.     * TODO 如果需要,在此处理信号,信号必需已注册 
  33.     *****************************************************************/  
  34.   
  35.     ACE_Reactor::instance()->end_reactor_event_loop();  
  36.   
  37.     return 0;  
  38. }  

 

6、Config.cpp

[cpp] view plaincopy
  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 char* config_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_ERROR, ACE_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_ERROR, ACE_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"), 0, status_section) == -1)  
  31.     {  
  32.         ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("(%P|%t) %p/n"), ACE_TEXT ("Can't open [SYSTEM] section")), -1);  
  33.     }  
  34.   
  35.     // 服务地址  
  36.     if (config.get_string_value(status_section, ACE_TEXT("HOST"), str) != -1)  
  37.     {  
  38.         if (str.compare(this->host) != 0)  
  39.         {  
  40.             ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [SYSTEM]->'HOST' is updated (%s)->(%s)/n"), this->host.c_str(), str.c_str()));  
  41.             this->host = str;  
  42.         }  
  43.         str.clear();  
  44.     }  
  45.     else  
  46.     {  
  47.         this->host.clear();  
  48.         this->host = ACE_TEXT("127.0.0.1");  
  49.         ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) [SYSTEM]->'HOST' does not exist, default value is (%s)/n"), this->host.c_str()));  
  50.     }  
  51.   
  52.     // 服务端口  
  53.     if (config.get_string_value(status_section, ACE_TEXT("PORT"), str) != -1)  
  54.     {  
  55.         try  
  56.         {  
  57.             num = ACE_OS::strtol(str.c_str(), NULL, 10);  
  58.             if (num != this->port)  
  59.             {  
  60.                 ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [SYSTEM]->'PORT' is updated (%d)->(%d)/n"), this->port, num));  
  61.                 this->port = static_cast<u_short> (num);  
  62.             }  
  63.         }  
  64.         catch (...)  
  65.         {  
  66.             this->port = 50001;  
  67.             ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) [SYSTEM]->'PORT' is catch exception, default value is (%d)/n"), this->port));  
  68.         }  
  69.         num = 0;  
  70.     }  
  71.     else  
  72.     {  
  73.         this->port = 50001;  
  74.         ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) [SYSTEM]->'PORT' does not exist, default value is (%d)/n"), this->port));  
  75.     }  
  76.   
  77.     /**************************************************************** 
  78.     * TODO 在此增加读取配置文件的参数 
  79.     *****************************************************************/  
  80.   
  81.   
  82.     return 0;  
  83. }  

 

7、Global_Define.h

[cpp] view plaincopy
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4. #ifndef _Global_Define_h  
  5. #define _Global_Define_h  
  6.   
  7. #include <ace/OS.h>  
  8. #include <ace/SString.h>  
  9. #include <ace/Task.h>  
  10. #include <ace/Synch.h>  
  11. #include <ace/Message_Block.h>  
  12. #include <ace/Log_Msg.h>  
  13. #include <ace/Svc_Handler.h>  
  14. #include <ace/Acceptor.h>  
  15. #include <ace/SOCK_Stream.h>  
  16. #include <ace/SOCK_Acceptor.h>  
  17.   
  18. #define RECV_HIGHT_MARK 8*1024 /*接收队列高水位标*/  
  19. #define SEND_HIGHT_MARK 8*1024 /*发送队列高水位标*/  
  20. #define INPUT_SIZE 4*1024 /*接收数据缓冲区大小*/  
  21. #define TASK_RECV_POOL_SIZE 10 //处理服务器接收到的客户端数据队列的线程池大小  
  22. #define TASK_SEND_POOL_SIZE 1 //处理服务器向客户端发送的数据队列的线程池大小  
  23.   
  24. #define MSG_HEAD_MODE 0 /*表示是否采用消息头模式,0:表示不使用,1:表示使用*/  
  25. #define MSG_HEAD_SIZE 12  
  26.   
  27. #define CONFIG_FILE "../config/config.cfg"  
  28.   
  29. #define GET_BYTE1(a)    (  (a)%0x100 ) /*低1字节*/  
  30. #define GET_BYTE2(a)    ( ((a)/0x100)%0x100 ) /*低2字节*/  
  31. #define GET_BYTE3(a)    ( ((a)/0x10000)%0x100 ) /*低3字节*/  
  32. #define GET_BYTE4(a)    ( ((a)/0x1000000)%0x100 ) /*低4字节*/  
  33.   
  34. #define SET_BYTE1(a)    ( (a) ) /*低1字节*/  
  35. #define SET_BYTE2(a)    ( (a)*0x100 ) /*低2字节*/  
  36. #define SET_BYTE3(a)    ( (a)*0x10000 ) /*低3字节*/  
  37. #define SET_BYTE4(a)    ( (a)*0x1000000 ) /*低4字节*/  
  38.   
  39. /**********************************************************************************************************************************/  
  40.   
  41. /******************************************************************************************** 
  42. * TODO 全局参数类,在此增加全局参数 
  43. ********************************************************************************************/  
  44. class GlobalValue  
  45. {  
  46. public:  
  47.     ACE_TString host; /*服务器主机地址*/  
  48.     u_short port; /*服务器监听端口*/  
  49.   
  50.     int load_config(const char* config_filename_);  
  51. };  
  52.   
  53. /**********************************************************************************************************************************/  
  54.   
  55. /******************************************************************************************** 
  56. * 采用ACE_Task任务或主动对象处理模式,处理服务器向客户端发送的数据队列 
  57. ********************************************************************************************/  
  58. class TaskSend: public ACE_Task<ACE_MT_SYNCH>  
  59. {  
  60. public:  
  61.     TaskSend() : active_(false), task_peer_(NULL)   
  62.     {  
  63.         this->active_ = false;  
  64.         this->msg_queue()->high_water_mark(SEND_HIGHT_MARK);  
  65.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskSend start/n")));  
  66.     }  
  67.   
  68.     virtual ~TaskSend()  
  69.     {  
  70.         this->active_ = false;  
  71.         this->msg_queue()->close();  
  72.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskSend stop/n")));  
  73.     }  
  74.   
  75.     virtual int svc(void);  
  76.   
  77.     void set_active(bool b);  
  78.     bool get_active();  
  79.   
  80.     void set_task_peer(ACE_Task<ACE_MT_SYNCH> * _task_peer_);  
  81.     ACE_Task<ACE_MT_SYNCH> * get_task_peer();  
  82.   
  83.     int send_msg(char * _buf, size_t _size);  
  84.   
  85. private:  
  86.     bool active_;  
  87.   
  88.     ACE_Task<ACE_MT_SYNCH> * task_peer_;  
  89.   
  90.     void process_send(ACE_Message_Block *mb = NULL);  
  91. };  
  92.   
  93. /******************************************************************************************** 
  94. * 采用ACE_Task任务或主动对象处理模式,处理服务器接收到的客户端数据队列 
  95. ********************************************************************************************/  
  96. class TaskRecv: public ACE_Task<ACE_MT_SYNCH>  
  97. {  
  98. public:  
  99.     TaskRecv() : active_(false), task_send_(NULL)   
  100.     {  
  101.         this->active_ = false;  
  102.         this->msg_queue()->high_water_mark(RECV_HIGHT_MARK);  
  103.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskRecv start/n")));  
  104.     }  
  105.   
  106.     virtual ~TaskRecv()   
  107.     {  
  108.         this->active_ = false;  
  109.         this->msg_queue()->close();  
  110.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskRecv stop/n")));  
  111.     }  
  112.   
  113.     virtual int svc(void);  
  114.   
  115.     void set_active(bool b);  
  116.     bool get_active();  
  117.   
  118.     void set_task_send(TaskSend *_task_send);  
  119.     TaskSend * get_task_send();  
  120.   
  121. private:  
  122.     bool active_;  
  123.   
  124.     TaskSend *task_send_;  
  125.   
  126.     void process_recv(ACE_Message_Block *mb = NULL);  
  127.     int send_msg(char * _buf, size_t _size);  
  128. };  
  129.   
  130. /******************************************************************************************** 
  131. * 采用ACE接受器(Acceptor)连接建立模式,实现双工单路服务端 
  132. ********************************************************************************************/  
  133. class Server21 : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>  
  134. {  
  135.     typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> super;  
  136.   
  137. public:  
  138.     Server21(void);  
  139.   
  140.     virtual ~Server21(void);  
  141.   
  142.     // 在连接建立后被自动回调  
  143.     virtual int open (void * = 0);  
  144.   
  145.     // Called when input is available from the client.  
  146.     virtual int handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  147.   
  148.     // Called when output is possible.  
  149.     virtual int handle_output(ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  150.   
  151.     // Called when a timer expires.  
  152.     virtual int handle_timeout (const ACE_Time_Value ¤t_time, const void *act = 0);  
  153.   
  154.     // Called when this handler is removed from the ACE_Reactor.  
  155.     virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask);  
  156.   
  157.     void set_active(bool b);  
  158.     bool get_active();  
  159.   
  160. private:  
  161.     bool active_;  
  162.   
  163.     TaskRecv task_recv;  
  164.     TaskSend task_send;  
  165.   
  166.     /******************************************************************************************** 
  167.     * 策略类,实现了Strategy模式。如果ACE_Message_Queue拥有一个策略对象,无论何时有ACE_Message_Block对象 
  168.     * 进入队列,ACE_Message_Queue都会调用该策略对象的notify()方法,把一个通知放入队列,通知的目标是对象的handle_output()方法 
  169.     ********************************************************************************************/  
  170.     /*方式2*/ //ACE_Reactor_Notification_Strategy notifier_;   
  171.   
  172.     /*回调函数,使用者在此实现对应功能*/  
  173.     void start_0(); /*对等端接入后回调*/  
  174.     void stop_0(); /*对等端关闭后回调*/  
  175.     void timeout_0(); /*定时任务*/  
  176. };  
  177.   
  178. /**********************************************************************************************************************************/  
  179.   
  180. /******************************************************************************************** 
  181. * 应用程序定时任务,及信号处理 
  182. ********************************************************************************************/  
  183. class ScheduleHandler : public ACE_Event_Handler  
  184. {  
  185. public:  
  186.     virtual int handle_timeout(const ACE_Time_Value ¤t_time, const void *act = 0);  
  187.   
  188.     virtual int handle_signal(int signum, siginfo_t * = 0, ucontext_t * = 0);  
  189. };  
  190.   
  191. /**********************************************************************************************************************************/  
  192.   
  193. typedef ACE_Acceptor<Server21, ACE_SOCK_ACCEPTOR> ServerAcceptor;  
  194.   
  195. #endif  

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

   

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

   

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

 

1、main.cpp

[cpp] view plaincopy
  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 (int, ACE_TCHAR *[])  
  17. {  
  18.     ACE_TP_Reactor *tp_reactor = new ACE_TP_Reactor;  
  19.     ACE_Reactor *reactor = new ACE_Reactor(tp_reactor, 1);  
  20.     ACE_Reactor::instance(reactor, 1);  
  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_ERROR, ACE_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_val, ACE_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_port, g_val.client_host.c_str());  
  52.     ClientConnector connector;  
  53.   
  54.     do {  
  55.         Client21 client;  
  56.         Client21 *pc = &client;  
  57.         if (connector.connect(pc, port_to_connect) == -1)   
  58.         {  
  59.             ACE_DEBUG((LM_ERROR, ACE_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_ERROR, ACE_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);  
  82. }  

 

2、Client21.cpp

[cpp] view plaincopy
  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_DEBUG, ACE_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_DEBUG, ACE_TEXT("(%P|%t) Client21 stop/n")));  
  43.     return;  
  44. }  
  45.   
  46. // 在连接建立后被自动回调  
  47. int Client21::open(void *p)  
  48. {  
  49.     if (super::open(p) == -1) return -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_name, MAXHOSTNAMELEN) == 0)  
  54.         ACE_DEBUG((LM_INFO, ACE_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_JOINABLE, TASK_RECV_POOL_SIZE) == -1)  
  62.     {  
  63.         ACE_DEBUG((LM_ERROR, ACE_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_JOINABLE, TASK_SEND_POOL_SIZE) == -1)  
  68.     {  
  69.         ACE_DEBUG((LM_ERROR, ACE_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(this, 0, ACE_Time_Value::zero, interval);  
  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(buffer, MSG_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_DEBUG, ACE_TEXT("(%P|%t) Message length (%d) %s/n"), msg_len, msg_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_DEBUG, ACE_TEXT("(%P|%t) Recv(%d+%d):[%s]/n"), MSG_HEAD_SIZE, msg_len-MSG_HEAD_SIZE, buffer));  
  110.   
  111.                 ACE_Message_Block *mb = NULL;  
  112.                 ACE_NEW_RETURN(mb, ACE_Message_Block(msg_len+1), -1);  
  113.                 ACE_OS::memcpy(mb->wr_ptr(), buffer, msg_len);  
  114.                 mb->wr_ptr(msg_len);  
  115.   
  116.                 if (task_recv.putq(mb) == -1)  
  117.                 {  
  118.                     ACE_DEBUG((LM_ERROR, ACE_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_DEBUG, ACE_TEXT("(%P|%t) Recv(%d+%d):[%s]/n"), MSG_HEAD_SIZE, msg_len-MSG_HEAD_SIZE, buffer));  
  132.   
  133.                     ACE_Message_Block *mb = NULL;  
  134.                     ACE_NEW_RETURN(mb, ACE_Message_Block(msg_len+1), -1);  
  135.                     ACE_OS::memcpy(mb->wr_ptr(), buffer, msg_len);  
  136.                     mb->wr_ptr(msg_len);  
  137.   
  138.                     if (task_recv.putq(mb) == -1)  
  139.                     {  
  140.                         ACE_DEBUG((LM_ERROR, ACE_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_ERROR, ACE_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_ERROR, ACE_TEXT("(%P|%t) Connection closed/n")));  
  168.   
  169.         /*表示客户端已断开*/  
  170.         return -1;  
  171.     }  
  172.   
  173. #else /*不接收消息头模式*/  
  174.       
  175.     recv_cnt = this->peer().recv(buffer, sizeof(buffer));  
  176.   
  177.     if (recv_cnt > 0)  
  178.     {  
  179.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Recv(%d):[%s]/n"), recv_cnt, buffer));  
  180.   
  181.         ACE_Message_Block *mb = NULL;  
  182.         ACE_NEW_RETURN(mb, ACE_Message_Block(recv_cnt+1), -1);  
  183.         ACE_OS::memcpy(mb->wr_ptr(), buffer, recv_cnt);  
  184.         mb->wr_ptr(recv_cnt);  
  185.   
  186.         if (task_recv.putq(mb) == -1)  
  187.         {  
  188.             ACE_DEBUG((LM_ERROR, ACE_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_ERROR, ACE_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_ERROR, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("Client21 send")));  
  223.             }  
  224.             else  
  225.             {  
  226.                 ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Send(%d):[%s]/n"), send_cnt, mb->rd_ptr()));  
  227.                 mb->rd_ptr(ACE_static_cast(size_t, send_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(this, ACE_Event_Handler::WRITE_MASK);  
  242.   
  243.     return 0;  
  244. }  
  245.   
  246. // 定时处理函数  
  247. int Client21::handle_timeout(const ACE_Time_Value ¤t_time, const 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 h, ACE_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_name, MAXHOSTNAMELEN) == 0)  
  267.             ACE_DEBUG((LM_INFO, ACE_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 (h, mask);  
  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_DEBUG, ACE_TEXT("(%P|%t) handle_timeout/n")));  
  349.   
  350. }  

 

3、TaskRecv.cpp

[cpp] view plaincopy
  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_DEBUG, ACE_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_DEBUG, ACE_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_DEBUG, ACE_TEXT("(%P|%t) Processing recv message: length %d : %s/n"), data_size, data));  
  36.   
  37.     /**************************************************************** 
  38.     * TODO 处理接收到的对等端数据,数据的起始地址为data,长度为data_size 
  39.     *****************************************************************/  
  40.   
  41.     ACE_OS::sleep(3);  
  42.   
  43.     //如何发送的例子  
  44.     send_msg(data, data_size);  
  45.   
  46.   
  47.   
  48.     //数据处理结束必需释放内存  
  49.     mb->release();  
  50. }  
  51.   
  52. //向对等端发送数据,实际操作是向发送队列插入一条 ACE_Message_Block  
  53. //返回 -1:失败 >=0:发送数据长度  
  54. int TaskRecv::send_msg(char * _buf, size_t _size)  
  55. {  
  56.     if (_size == 0) return 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_;  
  85. }  

 

4、TaskSend.cpp

[cpp] view plaincopy
  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_DEBUG, ACE_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_DEBUG, ACE_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_DEBUG, ACE_TEXT("(%P|%t) Processing send message: length %d : %s/n"), data_size, data));  
  38.   
  39.     if (this->task_peer_->putq(mb) == -1)  
  40.     {  
  41.         ACE_DEBUG((LM_ERROR, ACE_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 * _buf, size_t _size)  
  77. {  
  78.     if (_size==0) return 0;  
  79.     if (this->active_ != truereturn -1;  
  80.   
  81.     ACE_Message_Block *mb = NULL;  
  82.     ACE_NEW_RETURN(mb, ACE_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_ERROR, ACE_TEXT ("(%P|%t) %p; discarding data/n"), ACE_TEXT ("TaskSend enqueue failed")));  
  89.         mb->release();  
  90.         return -1;  
  91.     }  
  92.   
  93.     return _size;  
  94. }  

 

5、ScheduleHandler.cpp

[cpp] view plaincopy
  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_tv, const 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 signum, siginfo_t *, ucontext_t *)  
  26. {  
  27.     ACE_UNUSED_ARG (signum);  
  28.   
  29.     ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Receive system signal %d./n"), signum));  
  30.   
  31.     /**************************************************************** 
  32.     * TODO 如果需要,在此处理信号,信号必需已注册 
  33.     *****************************************************************/  
  34.   
  35.     ACE_OS::exit(0);  
  36.   
  37.     return 0;  
  38. }  

 

6、Config.cpp

[cpp] view plaincopy
  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 char* config_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_ERROR, ACE_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_ERROR, ACE_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"), 0, status_section) == -1)  
  31.     {  
  32.         ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("(%P|%t) %p/n"), ACE_TEXT ("Can't open [SYSTEM] section")), -1);  
  33.     }  
  34.   
  35.     // 服务地址  
  36.     if (config.get_string_value(status_section, ACE_TEXT("CLIENT_HOST"), str) != -1)  
  37.     {  
  38.         if (str.compare(this->client_host) != 0)  
  39.         {  
  40.             ACE_DEBUG((LM_DEBUG, ACE_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_ERROR, ACE_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_section, ACE_TEXT("CLIENT_PORT"), str) != -1)  
  54.     {  
  55.         try  
  56.         {  
  57.             num = ACE_OS::strtol(str.c_str(), NULL, 10);  
  58.             if (num != this->client_port)  
  59.             {  
  60.                 ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) [SYSTEM]->'CLIENT_PORT' is updated (%d)->(%d)/n"), this->client_port, num));  
  61.                 this->client_port = static_cast<u_short> (num);  
  62.             }  
  63.         }  
  64.         catch (...)  
  65.         {  
  66.             this->client_port = 50001;  
  67.             ACE_DEBUG((LM_ERROR, ACE_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_ERROR, ACE_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;  
  83. }  

 

7、Global_Define.h

[cpp] view plaincopy
  1. /******************************************************************************************** 
  2. * huangjf 2009年4月 于宁夏银川 
  3. ********************************************************************************************/  
  4. #ifndef _Global_Define_h  
  5. #define _Global_Define_h  
  6.   
  7. #include <ace/Task.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. #define RECV_HIGHT_MARK 8*1024 /*接收队列高水位标*/  
  18. #define SEND_HIGHT_MARK 8*1024 /*发送队列高水位标*/  
  19. #define INPUT_SIZE 4*1024 /*接收数据缓冲区大小*/  
  20. #define TASK_RECV_POOL_SIZE 8 //处理服务器接收到的客户端数据队列的线程池大小  
  21. #define TASK_SEND_POOL_SIZE 1 //处理服务器向客户端发送的数据队列的线程池大小  
  22.   
  23. #define MSG_HEAD_MODE 0 /*表示是否采用消息头模式,0:表示不使用,1:表示使用*/  
  24. #define MSG_HEAD_SIZE 12  
  25.   
  26. #define CONFIG_FILE "../config/config.cfg"  
  27.   
  28. #define GET_BYTE1(a)    (  (a)%0x100 ) /*低1字节*/  
  29. #define GET_BYTE2(a)    ( ((a)/0x100)%0x100 ) /*低2字节*/  
  30. #define GET_BYTE3(a)    ( ((a)/0x10000)%0x100 ) /*低3字节*/  
  31. #define GET_BYTE4(a)    ( ((a)/0x1000000)%0x100 ) /*低4字节*/  
  32.   
  33. #define SET_BYTE1(a)    ( (a) ) /*低1字节*/  
  34. #define SET_BYTE2(a)    ( (a)*0x100 ) /*低2字节*/  
  35. #define SET_BYTE3(a)    ( (a)*0x10000 ) /*低3字节*/  
  36. #define SET_BYTE4(a)    ( (a)*0x1000000 ) /*低4字节*/  
  37.   
  38. /**********************************************************************************************************************************/  
  39.   
  40. /******************************************************************************************** 
  41. * TODO 全局参数类,在此增加全局参数 
  42. ********************************************************************************************/  
  43. class GlobalValue  
  44. {  
  45. public:  
  46.     ACE_TString client_host; /*客户端主机地址*/  
  47.     u_short client_port; /*客户端监听端口*/  
  48.   
  49.     int load_config(const char* config_filename_);  
  50. };  
  51.   
  52. /**********************************************************************************************************************************/  
  53.   
  54. /******************************************************************************************** 
  55. * 采用ACE_Task任务或主动对象处理模式,处理服务器向客户端发送的数据队列 
  56. ********************************************************************************************/  
  57. class TaskSend: public ACE_Task<ACE_MT_SYNCH>  
  58. {  
  59. public:  
  60.     TaskSend() : active_(false), task_peer_(NULL)   
  61.     {  
  62.         this->active_ = false;  
  63.         this->msg_queue()->high_water_mark(SEND_HIGHT_MARK);  
  64.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskSend start/n")));  
  65.     }  
  66.   
  67.     virtual ~TaskSend()  
  68.     {  
  69.         this->active_ = false;  
  70.         this->msg_queue()->close();  
  71.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskSend stop/n")));  
  72.     }  
  73.   
  74.     virtual int svc(void);  
  75.   
  76.     void set_active(bool b);  
  77.     bool get_active();  
  78.   
  79.     void set_task_peer(ACE_Task<ACE_MT_SYNCH> * _task_peer_);  
  80.     ACE_Task<ACE_MT_SYNCH> * get_task_peer();  
  81.   
  82.     int send_msg(char * _buf, size_t _size);  
  83.   
  84. private:  
  85.     bool active_;  
  86.   
  87.     ACE_Task<ACE_MT_SYNCH> * task_peer_;  
  88.   
  89.     void process_send(ACE_Message_Block *mb = NULL);  
  90. };  
  91.   
  92. /******************************************************************************************** 
  93. * 采用ACE_Task任务或主动对象处理模式,处理服务器接收到的客户端数据队列 
  94. ********************************************************************************************/  
  95. class TaskRecv: public ACE_Task<ACE_MT_SYNCH>  
  96. {  
  97. public:  
  98.     TaskRecv() : active_(false), task_send_(NULL)   
  99.     {  
  100.         this->active_ = false;  
  101.         this->msg_queue()->high_water_mark(RECV_HIGHT_MARK);  
  102.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskRecv start/n")));  
  103.     }  
  104.   
  105.     virtual ~TaskRecv()   
  106.     {  
  107.         this->active_ = false;  
  108.         this->msg_queue()->close();  
  109.         ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) TaskRecv stop/n")));  
  110.     }  
  111.   
  112.     virtual int svc(void);  
  113.   
  114.     void set_active(bool b);  
  115.     bool get_active();  
  116.   
  117.     void set_task_send(TaskSend *_task_send);  
  118.     TaskSend * get_task_send();  
  119.   
  120. private:  
  121.     bool active_;  
  122.   
  123.     TaskSend *task_send_;  
  124.   
  125.     void process_recv(ACE_Message_Block *mb = NULL);  
  126.     int send_msg(char * _buf, size_t _size);  
  127. };  
  128.   
  129. /******************************************************************************************** 
  130. * 采用ACE连接器(Connector)连接建立模式,实现双工单路客户端 
  131. ********************************************************************************************/  
  132. class Client21 : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>  
  133. {  
  134.     typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> super;  
  135.   
  136. public:  
  137.     Client21(void);  
  138.   
  139.     virtual ~Client21(void);  
  140.   
  141.     // 在连接建立后被自动回调  
  142.     virtual int open (void * = 0);  
  143.   
  144.     // Called when input is available from the client.  
  145.     virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  146.   
  147.     // Called when output is possible.  
  148.     virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);  
  149.   
  150.     // Called when a timer expires.  
  151.     virtual int handle_timeout (const ACE_Time_Value ¤t_time, const void *act = 0);  
  152.   
  153.     // Called when this handler is removed from the ACE_Reactor.  
  154.     virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask);  
  155.   
  156.     void set_active(bool b);  
  157.     bool get_active();  
  158.   
  159. private:  
  160.     bool active_;  
  161.   
  162.     TaskRecv task_recv;  
  163.     TaskSend task_send;  
  164.   
  165.     /******************************************************************************************** 
  166.     * 策略类,实现了Strategy模式。如果ACE_Message_Queue拥有一个策略对象,无论何时有ACE_Message_Block对象 
  167.     * 进入队列,ACE_Message_Queue都会调用该策略对象的notify()方法,把一个通知放入队列,通知的目标是对象的handle_output()方法 
  168.     ********************************************************************************************/  
  169.     /*方式2*/ //ACE_Reactor_Notification_Strategy notifier_;   
  170.   
  171.     /*回调函数,使用者在此实现对应功能*/  
  172.     void start_0(); /*对等端接入后回调*/  
  173.     void stop_0(); /*对等端关闭后回调*/  
  174.     void timeout_0(); /*定时任务*/  
  175. };  
  176.   
  177. /**********************************************************************************************************************************/  
  178.   
  179. /******************************************************************************************** 
  180. * 应用程序定时任务,及信号处理 
  181. ********************************************************************************************/  
  182. class ScheduleHandler : public ACE_Event_Handler  
  183. {  
  184. public:  
  185.     virtual int handle_timeout(const ACE_Time_Value ¤t_time, const void *act = 0);  
  186.   
  187.     virtual int handle_signal(int signum, siginfo_t * = 0, ucontext_t * = 0);  
  188. };  
  189.   
  190. /**********************************************************************************************************************************/  
  191.   
  192. typedef ACE_Connector<Client21, ACE_SOCK_CONNECTOR> ClientConnector;  
  193.   
  194. #endif  


0 0
原创粉丝点击