ACE Proactor 框架移植到Linux平台后无法响应events

这部分代码主要是基于ACE_wrappers/examples/Reactor/Proactor/test_udp_proactor.cpp  
   
  简化后,改部分代码在windows下的运行效果是:  
  工作在2000端口,监听udp报文并对udp报文进行处理,利用另外一台服务器向这台机器发送udp报文(利用flowtools发送netflow报文)可以得到如下的效果:  
  proactor.cpp:82:Receiver::open_addr   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  handle_read_dgram   called  
  一直继续下去  
   
  但是同样的代码在Linux下编译成功,却无法响应udp   报文  
  运行效果是:  
    ./Proactor  
  Proactor.cpp:54:Receiver::open_addr   called  
  (7704   |   1077249920)   ACE_POSIX_AIOCB_Proactor::Max   Number   of   AIOs=1024  
  然后就没有任何的效果了  
   
  怀疑问题可能是出在recv函数,也就是  
  rd_.recv   (msg,  
  number_of_bytes_recvd,  
  0,  
  PF_INET,  
  this->act_);没有起作用  
   
  也有可能是linux下的ACE_POSIX_AIOCB_Proactor有问题,这是Proactor在linux下的默认构造  
   
  编译时候的选项如下:  
  g++       -I.   -I.   -Iinc/stlport   -Ii  
  nc           -g   -O2   -c   -o   Proactor.o   `test   -f   'Proactor.cpp'   ||   echo   './'`Proactor.cpp  
   
  libtool   --mode=link   g++   -g   -o2   -o   Proactor     -lACE   -lstlport_gcc   Proactor.o  
  编译选项时是否需要把thread给补充进去?  
   
  源代码如下:  
  //   Proactor.cpp  
   
  #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"  
   
  //ACE_RCSID(Proactor,   test_udp_proactor,   "test_proactor.cpp,v   1.29   2001/02/02   23:41:16   shuston   Exp")  
   
  #if   defined   (ACE_WIN32)   &&   !defined   (ACE_HAS_WINCE)   ||   defined   (ACE_HAS_AIO_CALLS)  
   
  class   Receiver   :   public   ACE_Service_Handler  
  {  
  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   0;  
  }  
   
  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_);  
  }  
   
   
   
  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 12:34:36 得分 0

a   letter   from   Alexander   Libman:  
   
  This   example   designed   only   for   Windows.  
  Proactor   I/O   UDP   functions   are   only   declarative   for   UNIX.  
  POSIX   aio_read/aio_write   does   not   support   UDP.  
  Moreover,   POSIX   aio   is   broken   or   not   fully   implemented   on   many   POSIX   platforms    
  including   RedHat9.  
   
  If   you   have   to   port   your   Proactor   application   to   POSIX/Linux,  
  I   recommend   you   to   use   ACE-   compatible   Proactor   from   Terabit:  
  http://www.terabit.com.au  
  Details   in   :   http://www.terabit.com.au/docs/Proactor2.htm  
  Download:   http://www.terabit.com.au/Proactor541N.tar.gz  
   
  Top

2 楼darkstar21cn(≮天残≯无畏)(死亡进行时)回复于 2005-06-22 16:33:02 得分 25

sockDgram_.open   ()调用失败了。   
   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值