关于ACE_Event_Handler
大家好,有关ACE_Event_Handler的问题,需要请教大家。源代码和问题如下:服务端代码:#include "stdafx.h"
#include <ace/OS.h>
#include <ace/Reactor.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Auto_Ptr.h>
#include <iostream>
#pragma comment(lib, "ace.lib")
#pragma comment(lib, "aced.lib")
class ClientService : public ACE_Event_Handler
{
public:
ACE_SOCK_Stream &peer (void) { return this->sock_; }
int open (void)
{
//注册读就绪回调函数
return this->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK);
}
virtual ACE_HANDLE get_handle (void) const { return this->sock_.get_handle (); }
virtual int handle_input (ACE_HANDLE fd )
{
//一个简单的EchoServer,将客户端的信息返回
int rev = peer().recv(buf,100);
if(rev<=0)
return -1;
buf='\0';
std::cout<<"Receive from client:"<<buf<<std::endl;
peer().send(buf,rev);
std::cout<<"Send to client:"<<buf<<std::endl;
return 0;
}
// 释放相应资源
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask mask)
{
if (mask == ACE_Event_Handler::WRITE_MASK)
return 0;
mask = ACE_Event_Handler::ALL_EVENTS_MASK |
ACE_Event_Handler::DONT_CALL;
this->reactor ()->remove_handler (this, mask);
this->sock_.close ();
delete this; //socket出错时,将自动删除该客户端,释放相应资源
return 0;
}
protected:
char buf;
ACE_SOCK_Stream sock_;
};
class ClientAcceptor : public ACE_Event_Handler
{
public:
virtual ~ClientAcceptor (){this->handle_close (ACE_INVALID_HANDLE, 0);}
int open (const ACE_INET_Addr &listen_addr)
{
if (this->acceptor_.open (listen_addr, 1) == -1)
{
ACE_OS::printf("open port fail");
return -1;
}
//注册接受连接回调事件
return this->reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
}
virtual ACE_HANDLE get_handle (void) const
{ return this->acceptor_.get_handle (); }
virtual int handle_input (ACE_HANDLE fd )
{
ClientService *client = new ClientService();
auto_ptr<ClientService> p (client);
if (this->acceptor_.accept (client->peer ()) == -1)
{
ACE_OS::printf("accept client fail \n");
return -1;
}
p.release ();
client->reactor (this->reactor ());
if (client->open () == -1)
client->handle_close (ACE_INVALID_HANDLE, 0);
return 0;
}
virtual int handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask close_mask)
{
if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE)
{
ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK |
ACE_Event_Handler::DONT_CALL;
this->reactor ()->remove_handler (this, m);
this->acceptor_.close ();
}
return 0;
}
protected:
ACE_SOCK_Acceptor acceptor_;
};
int main(int argc, char *argv[])
{
ACE_INET_Addr addr(3000,"127.0.0.1");
ClientAcceptor server;
server.reactor(ACE_Reactor::instance());
server.open(addr);
while(true)
{
ACE_Reactor::instance()->handle_events();
}
return 0;
}
客户端代码:#include "stdafx.h"
#include <iostream>
#include <string>
#include <ace/ACE.h>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Stream.h>
#pragma comment(lib, "ace.lib")
#pragma comment(lib, "aced.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ACE::init();
std::string str="Hello Server \n";
ACE_INET_Addr svr_addr(3000, "127.0.0.1");
ACE_SOCK_STREAM stream;
ACE_SOCK_Connector connector;
int ret=connector.connect(stream, svr_addr);
if(0 != ret)
{
std::cout<<"Error in connect"<<std::endl;
return -1;
}
std::cout<<"sending data:"<<std::endl<<str<<std::endl;
ret=stream.send(str.c_str(), str.length());
if(-1 == ret)
{
std::cout<<"Error in send"<<std::endl;
return -1;
}
str.erase();
str.resize(1024);
ret=stream.recv((void *)str.c_str(), str.length());
if(-1 == ret)
{
std::cout<<"Error in recv"<<std::endl;
return -1;
}
std::cout<<"recived data::"<<std::endl<<str<<std::endl;
ACE::fini();
return 0;
}
请问:
客户端socket只发送了一次数据给服务端,但是为什么ClientService的handle_input会执行两次呢?
谢谢大家! 估计你是在win下面跑,默认使用ACE_WFMO_Reacotr,该复用是边缘触发方式,
当你recv后,状态复位,由可读变为不可读,使得读事件再度被激发,其中未必真的有数据到达。 今天再次阅读发现自己的回答有误,更正下。
第二次触发应该是你socket关闭产生的事件,而且是非优雅的关闭,recv返回-1,楼主大意了
我说的那个lt/et的问题应该是output中有所区别,特此说明
页:
[1]