里面的代码我附上,是一个台湾同胞开发的!注意里面一个很重要的类YaSelectList,里面使用的是STL中的vector进行存储!其实我觉得如果使用list存储会更好,因为里面的socket删除操作比较频繁!
记得前面一个很重要的类:
TCPServer:
class TCPServer : public SocketsReader {
public:
TCPServer();
// add a TCP listener
void AddListener(TCPListenSocket *socket) { AddSocket(socket); }
// since listeners may be closed and deleted unexpectedly,
// the method provides a thread-safe way to close a listener
bool CloseListener(TCPListenSocket *socket);
private:
// override from class SocketsReader
virtual void ReadSocket(IPSocket *);
virtual void CleanUp();
};
继承类:SocketsReader
class SocketsReader : public RegularJob {
public:
SocketsReader(int = 1000);
~SocketsReader();
// override from class RegularJob
virtual void Stop();
protected:
// the derived classes should provide new interface to add sockets
void AddSocket(IPSocket *);
// new virtual function
// build a list of sockets for selecting
// return true if the list is not empty
// default behavior: put all sockets into the list
virtual bool BuildSelectList(SocketSelectList &);
// read data from the specified socket
virtual void ReadSocket(IPSocket *) = 0;
// clean up routine
// default behavior: delete sockets in m_removed
virtual void CleanUp();
bool SelectSockets(SocketSelectList &);
typedef std::list<IPSocket *>::iterator iterator;
typedef std::list<IPSocket *>::const_iterator const_iterator;
// remove closed sockets
void RemoveClosed(bool);
// for historical reason, assume the list has been locked
void RemoveSocket(iterator);
void RemoveSocket(IPSocket *);
PTimeInterval m_timeout;
std::list<IPSocket *> m_sockets, m_removed;
// keep the size of list since list::size() is not thread-safe
int m_socksize, m_rmsize;
mutable PReadWriteMutex m_listmutex;
mutable PMutex m_rmutex;
private:
// override from class Task
virtual void Exec();
};
实现方法见代码细节!
TCPServer的主执行函数
TCPServer::TCPServer()
{
SetName("TCPSrv");
Execute();
}
函数使用的是:
void SocketsReader::Exec()
{
ReadLock cfglock(ConfigReloadMutex);
SocketSelectList slist(GetName());
if (BuildSelectList(slist)) {
if (SelectSockets(slist)) {
int ss = slist.GetSize();
for (int i = 0; i < ss; ++i)
#ifdef LARGE_FDSET
ReadSocket(slist[i]);
#else
ReadSocket(dynamic_cast<IPSocket *>(slist[i]));
#endif
}
CleanUp();
} else {
CleanUp();
ConfigReloadMutex.EndRead();
PTRACE(6, GetName() << " waiting...");
Wait(SOCKETSREADER_IDLE_TIMEOUT);
ConfigReloadMutex.StartRead();
}
}
代码中使用了不少Mutex对象,对性能可能会有一些差异!
记得前面一个很重要的类:
TCPServer:
class TCPServer : public SocketsReader {
public:
TCPServer();
// add a TCP listener
void AddListener(TCPListenSocket *socket) { AddSocket(socket); }
// since listeners may be closed and deleted unexpectedly,
// the method provides a thread-safe way to close a listener
bool CloseListener(TCPListenSocket *socket);
private:
// override from class SocketsReader
virtual void ReadSocket(IPSocket *);
virtual void CleanUp();
};
继承类:SocketsReader
class SocketsReader : public RegularJob {
public:
SocketsReader(int = 1000);
~SocketsReader();
// override from class RegularJob
virtual void Stop();
protected:
// the derived classes should provide new interface to add sockets
void AddSocket(IPSocket *);
// new virtual function
// build a list of sockets for selecting
// return true if the list is not empty
// default behavior: put all sockets into the list
virtual bool BuildSelectList(SocketSelectList &);
// read data from the specified socket
virtual void ReadSocket(IPSocket *) = 0;
// clean up routine
// default behavior: delete sockets in m_removed
virtual void CleanUp();
bool SelectSockets(SocketSelectList &);
typedef std::list<IPSocket *>::iterator iterator;
typedef std::list<IPSocket *>::const_iterator const_iterator;
// remove closed sockets
void RemoveClosed(bool);
// for historical reason, assume the list has been locked
void RemoveSocket(iterator);
void RemoveSocket(IPSocket *);
PTimeInterval m_timeout;
std::list<IPSocket *> m_sockets, m_removed;
// keep the size of list since list::size() is not thread-safe
int m_socksize, m_rmsize;
mutable PReadWriteMutex m_listmutex;
mutable PMutex m_rmutex;
private:
// override from class Task
virtual void Exec();
};
实现方法见代码细节!
TCPServer的主执行函数
TCPServer::TCPServer()
{
SetName("TCPSrv");
Execute();
}
函数使用的是:
void SocketsReader::Exec()
{
ReadLock cfglock(ConfigReloadMutex);
SocketSelectList slist(GetName());
if (BuildSelectList(slist)) {
if (SelectSockets(slist)) {
int ss = slist.GetSize();
for (int i = 0; i < ss; ++i)
#ifdef LARGE_FDSET
ReadSocket(slist[i]);
#else
ReadSocket(dynamic_cast<IPSocket *>(slist[i]));
#endif
}
CleanUp();
} else {
CleanUp();
ConfigReloadMutex.EndRead();
PTRACE(6, GetName() << " waiting...");
Wait(SOCKETSREADER_IDLE_TIMEOUT);
ConfigReloadMutex.StartRead();
}
}
代码中使用了不少Mutex对象,对性能可能会有一些差异!