register_handler(this, ACE_Event_Handler::READ_MASK)失败
基于反应器框架,我写了2个类,可是总是在注册“读事件”时失败,请版主帮忙找找问题所在。class MyConnection: public ACE_Event_Handler
{
public:
MyConnection();
virtual ~MyConnection();
int init_as_client_bindip(const char *szIP); // 作为UDP客户端绑定IP
// get remote address of this connection
virtual int get_remote_addr(ACE_INET_Addr& addr);
virtual int handle_timeout (const ACE_Time_Value &tv, const void *act = 0)
{
return 0;
}
virtual int handle_input (ACE_HANDLE handle);
virtual int handle_close (ACE_HANDLE handle,ACE_Reactor_Mask close_mask);
protected:
// parse received msg
virtual int on_msg (ACE_UINT8 msg_type, MessageBlock* mb) = 0;
private:
ACE_SOCK_Dgram m_dgram;
}
class MyClient : public MyConnection
{
public:
MyClient();
virtual ~MyClient();
virtual int handle_timeout (const ACE_Time_Value &tv, const void *act = 0);
protected:
// 定一些业务上处理的方法,与所提的问题无关,下面就不列出来了
.............
}
我的注册函数写在MyConnection类的构造函数中,是这样写的:
if ( -1 == ACE_Reactor::instance ()->register_handler(this, ACE_Event_Handler::READ_MASK) )
{
printf("ACE_Reactor::MyConnection register_handler failed.");
}
此时总是失败。我想假若在构造的时候不能注册,是不是构造之后就可以注册了?后来,我把注册函数移到对象构造成功之后,
即用下面代码
if ( -1 == ACE_Reactor::instance ()->register_handler(对象指针, ACE_Event_Handler::READ_MASK) )
{
printf("ACE_Reactor::MyConnection register_handler failed.");
}
可是还是注册失败。 你应该要有一个
ACE_HANDLE get_handle (void) const;
返回UDP SOCKET本地 ACE_SOCK_Dgram的句柄 我在UDPConnection类加了下面的函数
virtual ACE_HANDLE get_handle (void) const
{
return this->m_dgram.get_handle();
}
可是注册仍然失败
回复 #3 xiaokousky 的帖子
注册失败返回什么出错信息?No such device or address? if ( -1 == ACE_Reactor::instance ()->register_handler(this, ACE_Event_Handler::READ_MASK) )
{
ACE_DEBUG((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("ACE_Reactor::MyConnection register_handler failed")));
}
打印信息如下:
ACE_Reactor::UDPConnection register_handler failed: Invalid argument 终于发现问题所在!
问题出在int init_as_client_bindip(const char *szIP); // 作为UDP客户端绑定IP
这个函数在前摄器模式下工作OK,到linux epoll模式下,绑定端口后,再进行注册“读事件”会失败。
int MyConnection::init_as_client_bindip(const char *szIP)
{
// Create a UDP socket to transfer datagrams.
ACE_SOCK_Dgram sock;
ACE_INET_Addr ace_addr;
sockaddr_in sockaddr;
ACE_UINT16 localPort = 32500;
do
{
memset(&sockaddr, 0, sizeof(sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(localPort++);
sockaddr.sin_addr.s_addr = inet_addr(szIP);
ACE_INET_Addr ace_addr_temp(&sockaddr, sizeof(sockaddr_in));
ace_addr = ace_addr_temp;
if (localPort-32500>100)
{
ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open udp socket failed"), -1);
return -1;
}
}
while (m_dgram.open(ace_addr, ACE_PROTOCOL_FAMILY_INET, 0, 1) == -1);
printf.StatusOut("Bind local UDP socket at port %d.", localPort-1);
return 0;
}
换成下面的函数,程序就OK了(上面的绑定本地IP和端口的函数在前摄器模式下工作OK)
int MyConnection::init_as_client ()
{
// Create a UDP socket to transfer datagrams.
if (m_dgram.open (ACE_INET_Addr::sap_any) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open udp socket failed"), -1);
return 0;
} 为什么不能绑定本机IP和端口呢?
比如本机有两张网卡,绑定本机指定的IP和端口的应用是存在的。
在前摄器模式下工作very good
在linux epoll模式下,难道不能绑定UDP ip和端口?又或者是在此模式下需要其他方式绑定IP,其他函数来绑定IP? 因为你使用的是udp协议ACE_SOCK_Dgram,所以在注册READ_MASK事件之前,必须先指定在本地的监听端口.
按照你提供的代码来看,你应该在调用register_handler()之前增加如下代码即可:
ACE_INET_Addr m_localAddr; //这个你查一下构造函数初始化一下
m_dgram.open(m_localAddr);
if ( -1 == ACE_Reactor::instance ()->register_handler(this, ACE_Event_Handler::READ_MASK) )
{
printf("ACE_Reactor::MyConnection register_handler failed.");
} 原帖由 xiaokousky 于 2009-4-7 15:47 发表 http://www.acejoy.com/bbs/images/common/back.gif
终于发现问题所在!
问题出在int init_as_client_bindip(const char *szIP); // 作为UDP客户端绑定IP
这个函数在前摄器模式下工作OK,到linux epoll模式下,绑定端口后,再进行注册“读事件”会失败。
int MyConnectio ...
回复完了才看到.............晕死..... 有没有方法在linux epoll模式下,绑定本地指定的IP和端口?
我在用上面发放绑定IP,端口后,注册读事件失败。
页:
[1]