zhghost 发表于 2009-7-15 19:23:56

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

例子代码如下:
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;
}

zhghost 发表于 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_);不合适。
还请各位 朋友帮帮忙修改下。
谢谢大家了

zhghost 发表于 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;
}
就可以发送
页: [1]
查看完整版本: test_ace_udp_proactor例子,出现了问题,求助!!