|
e_read_dgram (const ACE_Asynch_Read_Dgram::Result &result);
private:
ACE_SOCK_Dgram sock_dgram_;
/// rd (read dgram): for reading from a UDP socket.
ACE_Asynch_Read_Dgram rd_;
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_DEBUG ((LM_DEBUG,
"[%D][line:%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,
"[%D][line:%l]%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,
"[%D][line:%l]%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_);
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,
"[%D][line:%l]%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,
"[%D][line:%l]%p\n",
"ACE_Asynch_Read_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;
resul |