CMyError类的实现:
#ifndef __MYERROR_H__
#define __MYERROR_H__
#include "Error.h"
class CMyError : public LinWin::CError
{
public:
virtual int OnError(int level) { return -1; }
virtual int OnError(int code, int level) { return 0; }
};
#endif
一个接口返回了-1,一个接口返回 了0;算是最简单的一个实现类了吧,具体的实现类可以更复杂,这就根据需求了。我在这里,只是给出一个最简单的处理。
返回-1(非0)表示,表示不作任何处理,让调用者使用默认处理。返回0,表示已处理过了,调用者不需要再处理。
CMyExit类:
#ifndef __MYEXIT_H__
#define __MYEXIT_H__
#include "Exit.h"
class CMyExit : public LinWin::CExit
{
private:
bool m_bExit;
public:
CMyExit() : m_bExit(false) {}
bool OnExit() { return m_bExit; }
void SetExit() { m_bExit = true; }
};
#endif
退出的实现类也很简单,就一个数据成员,两个接口的实现也都是只有一行代码。
CMySelectEvent类
头文件 MySelectEvent.h
#ifndef __MYSELECTEVENT_H__
#define __MYSELECTEVENT_H__
#include "SocketImpl.h"
#include "TcpClient.h"
#include "NetworkEvent.h"
#include "Exit.h"
#include <map>
class CMySelectEvent : public LinWin::CNetworkEvent
{
private:
LinWin::CSocketImpl* m_server;
LinWin::CExit* m_exit;
std::map<net_socket_fd, LinWin::CTcpClient*> m_mapClients;
public:
CMySelectEvent();
CMySelectEvent(LinWin::CSocketImpl* server, LinWin::CExit* exit);
~CMySelectEvent();
void SetServer(LinWin::CSocketImpl* server);
void SetExit(LinWin::CExit* exit);
virtual int OnAccept(net_socket_fd &fdAccept);
virtual int OnRead(net_socket_fd fd);
virtual int OnWrite(net_socket_fd fd);
virtual int OnClose(net_socket_fd fd);
};
#endif
实现文件CMySelectEvent.cpp
#include "MySelectEvent.h"
#include "Exit.h"
#include <iostream>
CMySelectEvent::CMySelectEvent() : m_server(NULL), m_exit(NULL)
{
}
CMySelectEvent::CMySelectEvent(LinWin::CSocketImpl* server, LinWin::CExit* exit) : m_server(server), m_exit(exit)
{
}
CMySelectEvent::~CMySelectEvent()
{
}
void CMySelectEvent::SetServer(LinWin::CSocketImpl* server)
{
m_server = server;
}
void CMySelectEvent::SetExit(LinWin::CExit* exit)
{
m_exit = exit;
}
int CMySelectEvent::OnAccept(net_socket_fd &fdAccept)
{
LinWin::CSocketAddress clientAddr;
LinWin::CTcpClient* sockClient = new LinWin::CTcpClient;
if (!sockClient)
return -1;
if (sockClient->Create(true) != 0)
return -1;
if (m_server->Accept(sockClient->Handle(), clientAddr) != 0)
return -1;
fdAccept = sockClient->Sockfd();
m_mapClients.insert(std::make_pair(fdAccept, sockClient));
std::cout << "Recevie a connect: " << clientAddr.ToString() << std::endl;
//sockClient->Close();
return 0;
}
int CMySelectEvent::OnRead(net_socket_fd fd)
{
char buf[1024] = { 0 };
if (m_mapClients.find(fd) == m_mapClients.end())
return -1;
int ret = m_mapClients[fd]->Recv(buf, 1023);
if (ret == NET_SOCKET_ERROR || ret == 0)
return -1;
buf[ret] = '\0';
std::cout << "Receive: " << buf << std::endl;
return 0;
}
int CMySelectEvent::OnWrite(net_socket_fd fd)
{
std::cout << "OnWrite" << std::endl;
return 0;
}
int CMySelectEvent::OnClose(net_socket_fd fd)
{
if (m_mapClients.find(fd) == m_mapClients.end())
return -1;
delete m_mapClients[fd];
m_mapClients.erase(fd);
std::cout << "Close a client." << std::endl;
if (m_mapClients.size() == 0)
{
m_exit->SetExit();
std::cout << "All clients quit." << std::endl;
}
return 0;
}
这个事件类的实现,比较麻烦,多用了一个map类。其实,完全可以把这个map类省掉。因为,有这样CSocketImpl(net_socket_fd sockfd)的构造函数。我可以很容易的包装一个net_socket_fd。