用ACE的Reactor模式实现网络通讯的例子,不罗嗦,直接上代码。
服务器代码:
#include <ace/Reactor.h> #include <ace/SOCK_Connector.h> #include <ace/SOCK_Acceptor.h> #include <ace/Auto_Ptr.h> 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 ) { int rev = peer().recv(buf,sizeof(buf)); if(rev<=0) return -1; buf[rev] = '\0'; printf("recv: %s",buf); strcpy(buf,"hello,Client\n"); peer().send(buf,strlen(buf)); //向客户端发送信息。 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[100]; 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) { printf("open port fail\n"); 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) { 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 "ace/Reactor.h" #include "ace/SOCK_Connector.h" #include <string> #include <iostream> using namespace std; class MyClient:public ACE_Event_Handler { public: bool open() { ACE_SOCK_Connector connector; ACE_INET_Addr addr(3000,"127.0.0.1"); ACE_Time_Value timeout(5,0); if(connector.connect(peer,addr,&timeout) != 0) { cout<<endl<<"connect fail."; return false; } ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK); cout<<endl<<"connected."; strcpy(buf, "hello,Server\n"); peer.send(buf,strlen(buf)); return true; } ACE_HANDLE get_handle(void) const { return peer.get_handle(); } int handle_input (ACE_HANDLE fd) { int rev=0; ACE_Time_Value timeout(5,0); if((rev=peer.recv(buf,sizeof(buf),&timeout))>0) { buf[rev]='\0'; cout<<endl<<"recv: "<<buf<<endl; } return 3; } private: ACE_SOCK_Stream peer; char buf[100]; }; int main(int argc, char *argv[]) { MyClient client; client.open(); while(true) { ACE_Reactor::instance()->handle_events(); } return 0; }
分别编译运行(先运行服务端,后运行客户端)下面是执行结果。
服务器:
recv: hello,Server
客户端:
connected.
recv: hello,Client
参考:
http://www.cnblogs.com/TianFang/archive/2006/12/13/591332.html
http://www.cnblogs.com/TianFang/archive/2006/12/18/595938.html