转载于:http://www.cnblogs.com/TianFang/archive/2006/12/18/595808.html
在Socket编程中,常见的事件就是"读就绪","写就绪",通过对这两个事件的捕获分发,可以实现Socket中的异步操作。
Socket编程中的事件处理器
在前面我们已经介绍过,在ACE反应器框架中,任何都必须派生自ACE_Event_Handler类,并通过重载其相应会调事件处理函数来实现相应的回调处理的。在Socket编程中,我们通常需要重载的函数有
- handle_input()
当I/O句柄(比如UNIX中的文件描述符)上的输入可用时,反应器自动回调该方法。 - handle_output()
当I/O设备的输出队列有可用空间时,反应器自动回调该方法。 - handle_close()
当事件处理器中的事件从Reactor中移除的时候调用。
此外,为了使Reactor能通过I/O句柄找到对应的事件处理器,还必须重载其get_handle()方法以使得Reactor建立起I/O句柄和事件处理器的关联。
使用Reactor框架。
下面我们将以一个客户端的程序为例,介绍如何在Socket编程中使用Reactor框架。
一.建立一个客户端对象(事件处理器)。
客户端对象就是一个事件处理器,其声明如下:
1 class Client:public ACE_Event_Handler 2 { 3 public: 4 ACE_HANDLE get_handle(void) const; 5 int handle_input (ACE_HANDLE fd); 6 int handle_close (ACE_HANDLE handle, 7 ACE_Reactor_Mask close_mask); 8 ACE_SOCK_Stream& Peer(); 9 private: 10 ACE_SOCK_Stream peer; 11 };
在Client端中我只关心"读就绪"事件,故只重载了handle_input函数(大多数应用下只需要重载handle_input函数)。另外,在客户端还保存了一个ACE_SOCK_Stream的peer对象用来进行Socket通信,同时封装了一个Peer()函数返回它的引用。
二.重载相应回调处理函数
1 ACE_SOCK_Stream& Client::Peer() 2 { 3 return peer; 4 } 5 6 ACE_HANDLE Client::get_handle(void) const 7 { 8 return peer.get_handle(); 9 } 10 11 int Client::handle_input (ACE_HANDLE fd) 12 { 13 int rev=0; 14 if((rev = peer.recv(buffer,1000))>0) 15 { 16 buffer[rev]='