测试代码之Reactor模式
class Handler
{
public:
virtual void OnRead(SOCKET s) = 0;
virtual void OnSend(SOCKET s) = 0;
virtual void OnAccept(SOCKET s) = 0;
};
class Reactor
{
public:
typedef std::map<SOCKET, Handler*> HANDLERLIST;
typedef std::map<SOCKET, Handler*>::iterator HANDLERLIST_ITER;
public:
void RegisterHandler(SOCKET sock, Handler* handler)
{
m_HandlerList.insert(std::make_pair(sock, handler));
}
void RemoveHandler(SOCKET sock)
{
HANDLERLIST_ITER iter = m_HandlerList.find(sock);
if ( iter != m_HandlerList.end() )
{
m_HandlerList.erase(iter);
}
}
void Poll()
{
while(true)
{
fd_set rset, wset;
FD_ZERO(&rset);
FD_ZERO(&wset);
HANDLERLIST_ITER iter = m_HandlerList.begin();
for( ; iter != m_HandlerList.end(); iter++ )
{
FD_SET(iter->first, &rset);
FD_SET(iter->first, &wset);
}
timeval time_val;
time_val.tv_sec = 0;
time_val.tv_usec = 600;
if ( 0 == select(0, &rset, &wset, 0, &time_val))
{
//time out
continue;
}
for(int i = 0; i < rset.fd_count; i++)
{
if(FD_ISSET(rset.fd_array[i], &rset))
{
HANDLERLIST_ITER iter = m_HandlerList.find(rset.fd_array[i]);
if( iter != m_HandlerList.end() )
{
iter->second->OnRead(rset.fd_array[i]);
}
}
}
for(int i = 0; i < wset.fd_count; i++)
{
if(FD_ISSET(wset.fd_array[i], &wset))
{
HANDLERLIST_ITER iter = m_HandlerList.find(rset.fd_array[i]);
if( iter != m_HandlerList.end() )
{
iter->second->OnSend(rset.fd_array[i]);
}
}
}
}
}
private:
HANDLERLIST m_HandlerList;
};
Reactor g_reactor;
class MyHandler : public Handler
{
public:
MyHandler() {
}
public:
virtual void OnRead(SOCKET s)
{
cout<<"can recv "<< s <<endl;
char buff[256] = {0};
int len = ::recv(s, buff, 256, 0 );
if(len > 0)
{
cout<<"socket " << m_index <<" recv" <<buff<<endl;
}
else
{
g_reactor.RemoveHandler(s);
}
}
virtual void OnSend(SOCKET s)
{
// cout<<"can send "<< s <<endl;
}
virtual void OnAccept(SOCKET s)
{
// cout<<"can accept "<< s <<endl;
}
};