NetworkStream ns = tc.GetStream();
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
只在sr上关心读操作,而且使用者只需知道这是个可读流,跟网络、Socket等无关。 好的设计构架本质上是想通的,和c#中由NetworkStream到sr、sw的构造函数类似,ACE提供了open方法把流绑定到特定io上。 3.ACE_Asynch_Acceptor、ACE_Asynch_Connector ACE_Service_Handler是这两个类工厂的目标,也就是说,对于特定的事件,工厂会生产出ACE_Service_Handler应对特定处理。 同ACE中的其他open一样,ACE_Asynch_Acceptor<HANDLER>::open提供了socket的绑定、监听,当有连接到达的时候,open生成ACE_Service_Handler并调用新对象的open方法让对象可以对新的连接进行一些处理工作(譬如打开sr和sw等)。 ACE_Service_Handler继承于ACE_Handler,它声明了open方法,并且从基类中继承了handle_xxx系列方法,从这里开看,Proactor框架中处理数据靠的是这个类(我们需要做的是继承这个类以获得对实际问题的处理能力),而新建连接的问题,则有框架帮我们做好了,不需要定制处理、验证的话,没有必要修改其他类。 4.最后 到这里,在win32上使用完成端口的工作变得异常简单,实现一个ACE_Service_Handler就ok了。
示意代码:
void cleanup1()
{
ACE_Proactor::instance()->proactor_end_event_loop();
}
class myservicehandler :public ACE_Service_Handler
{
public:
virtual void open (ACE_HANDLE new_handle,ACE_Message_Block &message_block)
{
this->handle(new_handle);
rs.open(*this,handle());
ws.open(*this,handle());
ACE_Message_Block* mb = new ACE_Message_Block(1024);
rs.read(*mb,1024);
}
virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
cout<<"connected stream"<<endl;
ACE_Message_Block* mb = &result.message_block();
if (!result.success() || mb->length() <= 0) //注意这里对断开连接的判断
{
delete mb;
cout<<"disconnected connection"<<endl;
}
else
{
mb->length(0);
rs.read(*mb,1024);
}
}
private:
ACE_Asynch_Read_Stream rs;
ACE_Asynch_Write_Stream ws;
};
class mytask :public ACE_Task<ACE_NULL_SYNCH>
{
public:
int svc()
{
char c;
cin>>c;
cleanup1();
return 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
ACE::init();
ACE_INET_Addr addr(2350);
ACE_Asynch_Acceptor<myservicehandler> acceptor;
acceptor.open(addr);
mytask tk;
tk.activate();
ACE_Proactor::instance()->proactor_run_event_loop();
ACE::fini();
return 0;
}