ACE Proactor无法持续响应udp报文的问题

代码主要是基于ACE_wrappers/examples/Reactor/Proactor/test_udp_proactor的代码  
   
  简化后的代码主要在收到udp报文后打印handle_read_dgram   called  
   
  程序在2000端口监听,仅仅只能够接收一个udp报文  
  我很想知道如果想持续的接收报文,应该怎么去做?  
   
  我简化后的代码如下:  
  #include   "ace/OS_main.h"  
  #include   "ace/Proactor.h"  
  #include   "ace/Asynch_IO.h"  
  #include   "ace/INET_Addr.h"  
  #include   "ace/SOCK_Dgram.h"  
  #include   "ace/Message_Block.h"  
  #include   "ace/Get_Opt.h"  
   
   
  #if   defined   (ACE_WIN32)   &&   !defined   (ACE_HAS_WINCE)   ||   defined   (ACE_HAS_AIO_CALLS)  
  //   This   only   works   on   Win32   platforms.  
   
  class   Receiver   :   public   ACE_Service_Handler  
  {  
  //   =   TITLE  
  //           This   class   will   receive   data   from  
  //           the   network   connection   and   dump   it   to   a   file.  
  public:  
  //   =   Initialization   and   termination.  
  Receiver   (void);  
  ~Receiver   (void);  
   
  int   open_addr   (const   ACE_INET_Addr   &localAddr);  
   
  protected:  
  //   These   methods   are   called   by   the   framework  
   
  ///   This   method   will   be   called   when   an   asynchronous   read   completes   on  
  ///   a   UDP   socket.  
  virtual   void   handle_read_dgram   (const   ACE_Asynch_Read_Dgram::Result   &result);  
   
  private:  
  ACE_SOCK_Dgram   sockDgram_;  
  ACE_Asynch_Read_Dgram   rd_;  
  //   rd   (read   dgram):   for   reading   from   a   UDP   socket.  
  const   char*   completion_key_;  
  const   char*   act_;  
  };  
   
  Receiver::Receiver   (void)  
  :   completion_key_   ("Receiver   Completion   Key"),  
  act_   ("Receiver   ACT")  
  {  
  }  
   
  Receiver::~Receiver   (void)  
  {  
  sockDgram_.close   ();  
  }  
   
  int  
  Receiver::open_addr   (const   ACE_INET_Addr   &localAddr)  
  {  
  ACE_DEBUG   ((LM_DEBUG,  
  "%N:%l:Receiver::open_addr   called/n"));  
   
  //   Create   a   local   UDP   socket   to   receive   datagrams.  
  if   (this->sockDgram_.open   (localAddr)   ==   -1)  
  ACE_ERROR_RETURN   ((LM_ERROR,  
  "%p/n",  
  "ACE_SOCK_Dgram::open"),   -1);  
   
  //   Initialize   the   asynchronous   read.  
  if   (this->rd_.open   (*this,  
  this->sockDgram_.get_handle   (),  
  this->completion_key_,  
  ACE_Proactor::instance   ())   ==   -1)  
  ACE_ERROR_RETURN   ((LM_ERROR,  
  "%p/n",  
  "ACE_Asynch_Read_Dgram::open"),   -1);  
   
  //   Create   a   buffer   to   read   into.     We   are   using   scatter/gather   to  
  //   read   the   message   header   and   message   body   into   2   buffers  
   
  //   create   a   message   block   to   read   the   message   header  
  ACE_Message_Block*   msg   =   0;  
  ACE_NEW_RETURN   (msg,   ACE_Message_Block   (1024),   -1);  
   
  //   the   next   line   sets   the   size   of   the   header,   even   though   we  
  //   allocated   a   the   message   block   of   1k,   by   setting   the   size   to   20  
  //   bytes   then   the   first   20   bytes   of   the   reveived   datagram   will   be  
  //   put   into   this   message   block.  
  msg->size   (20);   //   size   of   header   to   read   is   20   bytes  
   
  //   create   a   message   block   to   read   the   message   body  
  ACE_Message_Block*   body   =   0;  
  ACE_NEW_RETURN   (body,   ACE_Message_Block   (1024),   -1);  
  //   The   message   body   will   not   exceed   1024   bytes,   at   least   not   in   this   test.  
   
  //   set   body   as   the   cont   of   msg.     This   associates   the   2   message  
  //   blocks   so   that   a   read   will   fill   the   first   block   (which   is   the  
  //   header)   up   to   size(),   and   use   the   cont()   block   for   the   rest   of  
  //   the   data.     You   can   chain   up   to   IOV_MAX   message   block   using   this  
  //   method.  
  msg->cont   (body);  
   
  //   ok   lets   do   the   asynch   read  
  size_t   number_of_bytes_recvd   =   0;  
   
  int   res   =   rd_.recv   (msg,  
  number_of_bytes_recvd,  
  0,  
  PF_INET,  
  this->act_);  
  return   res;  
  }  
   
  void  
  Receiver::handle_read_dgram   (const   ACE_Asynch_Read_Dgram::Result   &result)  
  {  
  ACE_DEBUG   ((LM_DEBUG,  
  "handle_read_dgram   called/n"));  
  }  
   
   
   
  int  
  ACE_TMAIN   (int   argc,   ACE_TCHAR   *argv[])  
  {  
  Receiver   receiver;  
   
  if   (receiver.open_addr   (ACE_INET_Addr   (2000))   ==   -1)  
  return   -1;  
  ACE_Proactor::instance()   ->   proactor_run_event_loop();  
   
  return   0;  
  }  
   
  #else   /*   ACE_WIN32   &&   !ACE_HAS_WINCE   ||   ACE_HAS_AIO_CALLS*/  
   
  int  
  ACE_TMAIN   (int,   ACE_TCHAR   *[])  
  {  
  ACE_DEBUG   ((LM_DEBUG,  
  "This   example   does   not   work   on   this   platform./n"));  
  return   1;  
  }  
   
  #endif   /*   ACE_WIN32   &&   !ACE_HAS_WINCE   ||   ACE_HAS_AIO_CALLS*/ 问题点数:50、回复次数:3Top

1 楼energumen1(华林) 回复于 2005-06-15 10:43:00 得分 0

修改handle_read_dgram函数如下  
  void  
  Receiver::handle_read_dgram   (const   ACE_Asynch_Read_Dgram::Result   &result)  
  {  
  ACE_DEBUG   ((LM_DEBUG,  
  "handle_read_dgram   called/n"));  
   
  ACE_Message_Block*   msg   =   new   ACE_Message_Block   (1024);  
   
  //   create   a   message   block   to   read   the   message   body  
  ACE_Message_Block*   body   =new   ACE_Message_Block   (1024);  
  msg->cont   (body);  
   
  //   ok   lets   do   the   asynch   read  
  size_t   number_of_bytes_recvd   =   1024;  
   
  int   res   =   rd_.recv   (msg,  
  number_of_bytes_recvd,  
  0,  
  PF_INET,  
  this->act_);  
  }  
  就可以持续的获得报文的响应了  
  原因可能在于没有调用recv中的actTop

2 楼ydogg(灰毛兔频频)回复于 2005-06-21 23:13:04 得分 50

Proactor是异步模式,提前向系统发起“接受”的请求,在每次收到数据后必需重新向系统发起recv请求。你的解决主要是在接受后重新发起了接受请求.  
   
  我个人的建议是,读例子没有问题,但在读例子前就需要了解一些基本接口方法  
  Top

3 楼darkstar21cn(≮天残≯无畏)(死亡进行时)回复于 2005-06-22 14:20:36 得分 0

while   (1)//加上这个  
  ACE_Proactor::instance()   ->   proactor_run_event_loop(); 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值