代码主要是基于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
修改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();