找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3190|回复: 2

test_ace_udp_proactor例子,出现了问题,求助!!

[复制链接]
发表于 2009-7-15 19:23:56 | 显示全部楼层 |阅读模式
例子代码如下:
receiver端:

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,ACE_Message_Block* msg);
  int send_msg();
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);
  virtual void handle_write_dgram (const ACE_Asynch_Write_Dgram::Result &result);

private:
  ACE_SOCK_Dgram sock_dgram_;

  ACE_Asynch_Read_Dgram rd_;
  // rd (read dgram): for reading from a UDP socket.
   ACE_Asynch_Write_Dgram wd_;
  const char* completion_key_;
  const char* act_;
};

Receiver::Receiver (void)
  : completion_key_ ("Receiver Completion Key"),
    act_ ("Receiver ACT")
{
}

Receiver::~Receiver (void)
{
  sock_dgram_.close ();
}

int
Receiver::open_addr (const ACE_INET_Addr &localAddr,ACE_Message_Block* msg)
{
  ACE_DEBUG ((LM_DEBUG,
              "%N:%l:Receiver::open_addr called\n"));

  // Create a local UDP socket to receive datagrams.
  if (this->sock_dgram_.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->sock_dgram_.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
  

  // 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_);
  switch (res)
    {
    case 0:
      // this is a good error.  The proactor will call our handler when the
      // read has completed.
      break;
    case 1:
      // actually read something, we will handle it in the handler callback
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      ACE_DEBUG ((LM_DEBUG,
                  "%s = %d\n",
                  "bytes recieved immediately",
                  number_of_bytes_recvd));
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      res = 0;
      break;
    case -1:
      // Something else went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Read_Dgram::recv"));
      // the handler will not get called in this case so lets clean up our msg
      msg->release ();
      break;
    default:
      // Something undocumented really went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Read_Dgram::recv"));
      msg->release ();
      break;
    }

  return res;
}

int Receiver::send_msg()
{
  ACE_Message_Block* msg = 0;
  ACE_NEW_RETURN (msg, ACE_Message_Block (100), -1);
  const char raw_msg [] = "To be or not to be.";
  // Copy buf into the Message_Block and update the wr_ptr ().
  msg->copy (raw_msg, ACE_OS::strlen (raw_msg) + 1);

  // create a message block for the message body
  ACE_Message_Block* body = 0;
  ACE_NEW_RETURN (body, ACE_Message_Block (100), -1);
  ACE_OS::memset (body->wr_ptr (), 'X', 100);
  body->wr_ptr (100); // always remember to update the wr_ptr ()

  // set body as the cont of msg.  This associates the 2 message blocks so
  // that a send will send the first block (which is the header) up to
  // length (), and use the cont () to get the next block to send.  You can
  // chain up to IOV_MAX message block using this method.
  msg->cont (body);

  // do the asynch send
  size_t number_of_bytes_sent = 0;
  ACE_INET_Addr serverAddr (port, host);
  int res = this->wd_.send (msg, number_of_bytes_sent, 0, serverAddr, this->act_);//====2===问题出在这里,说是不能发送数据给已经建立连接的通道。

  switch (res)
    {
    case 0:
      // this is a good error.  The proactor will call our handler when the
      // send has completed.
      break;
    case 1:
      // actually sent something, we will handle it in the handler callback
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      ACE_DEBUG ((LM_DEBUG,
                  "%s = %d\n",
                  "bytes sent immediately",
                  number_of_bytes_sent));
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      res = 0;
      break;
    case -1:
      // Something else went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Write_Dgram::recv"));
      // the handler will not get called in this case so lets clean up our msg
      msg->release ();
      break;
    default:
      // Something undocumented really went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Write_Dgram::recv"));
      msg->release ();
      break;
    }
        return res;
}
void
Receiver::handle_read_dgram (const ACE_Asynch_Read_Dgram::Result &result)
{
  ACE_DEBUG ((LM_DEBUG,
              "handle_read_dgram called\n"));

  ACE_DEBUG ((LM_DEBUG, "********************\n"));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_read", result.bytes_to_read ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", result.handle ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transfered", result.bytes_transferred ()));
  ACE_INET_Addr peerAddr;
  result.remote_address (peerAddr);
  ACE_DEBUG ((LM_DEBUG, "%s = %s:%d\n", "peer_address", peerAddr.get_host_addr (), peerAddr.get_port_number ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "flags", result.flags ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "act", result.act ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "success", result.success ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "completion_key", result.completion_key ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", result.error ()));
  ACE_DEBUG ((LM_DEBUG, "********************\n"));
       
  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_);   

  
  
}
void
Receiver::handle_write_dgram (const ACE_Asynch_Write_Dgram::Result &result)
{
  ACE_DEBUG ((LM_DEBUG,
              "handle_write_dgram called\n"));

  ACE_DEBUG ((LM_DEBUG, "WWWWWWWWWWWWWWWWWWWWWWWW\n"));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_write", result.bytes_to_write ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", result.handle ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transfered", result.bytes_transferred ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "flags", result.flags ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "act", result.act ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "success", result.success ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "completion_key", result.completion_key ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", result.error ()));
  ACE_DEBUG ((LM_DEBUG, "WWWWWWWWWWWWWWWWWWWWWWWW\n"));


  ACE_DEBUG ((LM_DEBUG,
              "Sender completed\n"));

  // No need for this message block anymore.
  result.message_block ()->release ();

done++;
}

int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
   
        Receiver receiver;

        ACE_Message_Block* msg = 0;
        ACE_NEW_RETURN (msg, ACE_Message_Block (1024), -1);

    msg->size (20); // size of header to read is 20 bytes

    ACE_Message_Block* body = 0;
    ACE_NEW_RETURN (body, ACE_Message_Block (1024), -1);
  
    msg->cont (body);

      if (receiver.open_addr (ACE_INET_Addr(2000),msg) == -1)
        return -1;
      if (receiver.send_msg() == -1)//===代码问题出在这,说是参数非法:===1.====在2中有标记
         return -1;
       
         ACE_Proactor::instance ()->proactor_run_event_loop();

  return 0;
}
 楼主| 发表于 2009-7-15 19:34:01 | 显示全部楼层
打算修改一下D:\ACE_wrappers\examples\Reactor\Proactor中,的test_udp_proactor例子中,的receiver端的代码,让它既可以接收又可以发送,可是发送却出了问题。问题定位到了代码中的=====1====和======2===上面。
问题是:不能够在建立连接的 Dgarm通道中发送数据给客户端。


自己定位的原因是:发送函数int res = this->wd_.send (msg, number_of_bytes_sent, 0, serverAddr, this->act_);不合适。
还请各位 朋友帮帮忙修改下。
谢谢大家了
 楼主| 发表于 2009-7-16 09:31:04 | 显示全部楼层
已经解决,改int send_msg()为:int send_msg(ACE_INET_Addr serverAddr)
主函数改为:
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
        Receiver receiver;
    ACE_INET_Addr local_addr = ACE_INET_Addr(2000, "192.168.20.214");
    ACE_SOCK_Dgram sock;
    // Create a UDP socket to transfer datagrams.
        if (sock.open (local_addr) == -1)
        ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open udp socket failed"), -1);

   // ACE_Message_Block mb;
       

        ACE_Message_Block* msg = 0;
        ACE_NEW_RETURN (msg, ACE_Message_Block (1024), -1);

    msg->size (20); // size of header to read is 20 bytes

    ACE_Message_Block* body = 0;
    ACE_NEW_RETURN (body, ACE_Message_Block (1024), -1);
  
    msg->cont (body);

    if (receiver.open_addr (local_addr,sock,msg) == -1)
        return -1;
        if (receiver.send_msg(local_addr) == -1)
        return -1;
       
         ACE_Proactor::instance ()->proactor_run_event_loop();

  return 0;
}
就可以发送
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-23 18:08 , Processed in 0.021225 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表