SocketServer.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:7k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /********************************************************************
  2. created: 2003/02/14
  3. file base: SocketServer
  4. file ext: h
  5. author: liupeng
  6. purpose: Build
  7. *********************************************************************/
  8. #ifndef __INCLUDE_SOCKETSERVER_H__
  9. #define __INCLUDE_SOCKETSERVER_H__
  10. #if defined (_MSC_VER) && (_MSC_VER >= 1020)
  11. #pragma once
  12. #endif
  13. #include "UsesWinsock.h"
  14. #include "Thread.h"
  15. #include "CriticalSection.h"
  16. #include "IOCompletionPort.h"
  17. #include "IOBuffer.h"
  18. #include "ManualResetEvent.h"
  19. #include "NodeList.h"
  20. #include "OpaqueUserData.h"
  21. /*
  22.  * namespace OnlineGameLib::Win32
  23.  */
  24. namespace OnlineGameLib {
  25. namespace Win32 {
  26. struct tagSockAddrIn
  27. {
  28. public:
  29. tagSockAddrIn() { Clear(); }
  30. tagSockAddrIn( const tagSockAddrIn& sin ) { Copy( sin ); }
  31. ~tagSockAddrIn() { }
  32. tagSockAddrIn& Copy( const tagSockAddrIn& sin );
  33. void Clear() { memset( &sockAddrIn, 0, sizeof( sockAddrIn ) ); }
  34. bool IsEqual( const tagSockAddrIn& sin );
  35. bool IsGreater( const tagSockAddrIn& sin );
  36. bool IsLower( const tagSockAddrIn& pm );
  37. bool IsNull() const { return ( ( sockAddrIn.sin_addr.s_addr == 0L ) && ( sockAddrIn.sin_port==0 ) ); }
  38. ULONG GetIPAddr() const { return sockAddrIn.sin_addr.s_addr; }
  39. short GetPort() const { return sockAddrIn.sin_port; }
  40. tagSockAddrIn& operator=( const tagSockAddrIn& sin ) { return Copy( sin ); }
  41. bool operator==( const tagSockAddrIn& sin ) { return IsEqual( sin ); }
  42. bool operator!=( const tagSockAddrIn& sin ) { return !IsEqual( sin ); }
  43. bool operator<( const tagSockAddrIn& sin )  { return IsLower( sin ); }
  44. bool operator>( const tagSockAddrIn& sin )  { return IsGreater( sin ); }
  45. bool operator<=( const tagSockAddrIn& sin ) { return !IsGreater( sin ); }
  46. bool operator>=( const tagSockAddrIn& sin ) { return !IsLower( sin ); }
  47. operator LPSOCKADDR() { return (LPSOCKADDR)(&sockAddrIn); }
  48. size_t Size() const { return sizeof( sockAddrIn ); }
  49. void SetAddr( SOCKADDR_IN* psin ) { memcpy( &sockAddrIn, psin, Size() ); }
  50. SOCKADDR_IN sockAddrIn;
  51. };
  52. /*
  53.  * CSocketServer
  54.  */
  55. class CSocketServer : protected CThread, private CUsesWinsock, private CIOBuffer::Allocator
  56. {
  57. public:
  58. class Socket;
  59. class WorkerThread;
  60. friend class Socket;
  61. virtual ~CSocketServer();
  62. void Open( 
  63. unsigned long addressToListenOn,
  64. unsigned short portToListenOn
  65. );
  66. using CThread::Start;
  67. void StartAcceptingConnections();
  68. void StopAcceptingConnections();
  69. void InitiateShutdown();
  70. void WaitForShutdownToComplete();
  71. protected:
  72. CSocketServer(
  73. unsigned long addressToListenOn,
  74. unsigned short portToListenOn,
  75. size_t maxFreeSockets,
  76. size_t maxFreeBuffers,
  77. size_t bufferSize = 1024,
  78. size_t numThreads = 0);
  79. CSocketServer(
  80. size_t maxFreeSockets,
  81. size_t maxFreeBuffers,
  82. size_t bufferSize = 1024,
  83. size_t numThreads = 0);
  84. void ReleaseSockets();
  85. void ReleaseBuffers();
  86. /*
  87.  * Virtual function has different access specifier to base class
  88.  */
  89. virtual int Run();
  90. private:
  91. /*
  92.  * Override this to create your worker thread
  93.  */
  94. virtual WorkerThread *CreateWorkerThread( CIOCompletionPort &iocp ) = 0;
  95. /*
  96.  * Override this to create the listening socket of your choice
  97.  */
  98. virtual SOCKET CreateListeningSocket( 
  99. unsigned long address,
  100. unsigned short port) = 0;
  101. /*
  102.  * Interface for derived classes to receive state change notifications...
  103.  */
  104. virtual void OnStartAcceptingConnections() {}
  105. virtual void OnStopAcceptingConnections() {}
  106. virtual void OnShutdownInitiated() {}
  107. virtual void OnShutdownComplete() {}
  108. virtual void OnConnectionCreated() {}
  109. virtual void OnConnectionEstablished(
  110. Socket *pSocket,
  111. CIOBuffer *pAddress) = 0;
  112. virtual void OnConnectionClosed( Socket * /*pSocket*/ ) {}
  113. virtual void OnConnectionDestroyed() {}
  114. virtual void OnError( const _tstring &message );
  115. virtual void OnBufferCreated() {}
  116. virtual void OnBufferAllocated() {}
  117. virtual void OnBufferReleased() {}
  118. virtual void OnBufferDestroyed() {}
  119. Socket *AllocateSocket( SOCKET theSocket );
  120. void ReleaseSocket( Socket *pSocket );
  121. void DestroySocket( Socket *pSocket );
  122. void PostAbortiveClose( Socket *pSocket );
  123. void Read( Socket *pSocket, CIOBuffer *pBuffer );
  124. void Write( Socket *pSocket, const char *pData, size_t dataLength, bool thenShutdown );
  125. void Write( Socket *pSocket, CIOBuffer *pBuffer, bool thenShutdown );
  126. virtual void PreWrite( 
  127. Socket *pSocket, 
  128. CIOBuffer *pBuffer, 
  129. const char *pData, 
  130. size_t dataLength ) {};
  131. const size_t m_numThreads;
  132. CCriticalSection m_listManipulationSection;
  133. typedef OnlineGameLib::TNodeList<Socket> SocketList;
  134. SocketList m_activeList;
  135. SocketList m_freeList;
  136. SOCKET m_listeningSocket;
  137. CIOCompletionPort m_iocp;
  138. CManualResetEvent m_shutdownEvent;
  139. CManualResetEvent m_acceptConnectionsEvent;
  140. unsigned long m_address;
  141. unsigned short m_port;
  142. const size_t m_maxFreeSockets;
  143. /*
  144.  * No copies do not implement
  145.  */
  146. CSocketServer( const CSocketServer &rhs );
  147. CSocketServer &operator=( const CSocketServer &rhs );
  148. };
  149. /*
  150.  * CSocketServer::Socket
  151.  */
  152. class CSocketServer::Socket : public CNodeList::Node, public COpaqueUserData
  153. {
  154. public :
  155. friend class CSocketServer;
  156. friend class CSocketServer::WorkerThread;
  157. void Read( CIOBuffer *pBuffer = 0 );
  158. void Write( const char *pData, size_t dataLength, bool thenShutdown = false );
  159. void Write( CIOBuffer *pBuffer, bool thenShutdown = false );
  160. void AddRef();
  161. void Release();
  162. void Shutdown( int how = SD_BOTH );
  163. void Close();
  164. void AbortiveClose();
  165. private:
  166. Socket( CSocketServer &server, SOCKET socket );
  167. ~Socket();
  168. void Attach( SOCKET socket );
  169. CSocketServer &m_server;
  170. SOCKET m_socket;
  171. long m_ref;
  172. /*
  173.  * No copies do not implement
  174.  */
  175. Socket( const Socket &rhs );
  176. Socket &operator=( const Socket &rhs );
  177. };
  178. /*
  179.  * CSocketServer::WorkerThread
  180.  */
  181. class CSocketServer::WorkerThread : public CThread
  182. {
  183. public:
  184. virtual ~WorkerThread() {}
  185. void InitiateShutdown();
  186. void WaitForShutdownToComplete();
  187. protected:
  188. explicit WorkerThread( CIOCompletionPort &iocp );
  189. /*
  190.  * Virtual function has different access specifier to base class
  191.  */
  192. virtual int Run();
  193. private:
  194. virtual void OnBeginProcessing() {}
  195. virtual void OnEndProcessing() {}
  196. virtual void OnError( const _tstring &message );
  197. void Read( Socket *pSocket, CIOBuffer *pBuffer ) const;
  198. virtual void ReadCompleted( Socket *pSocket, CIOBuffer *pBuffer ) = 0;
  199. void Write( Socket *pSocket, CIOBuffer *pBuffer ) const;
  200. virtual void WriteCompleted( Socket *pSocket, CIOBuffer *pBuffer );
  201. void AbortiveClose( Socket *pSocket );
  202. CIOCompletionPort &m_iocp;
  203. /*
  204.  * No copies do not implement
  205.  */
  206. WorkerThread( const WorkerThread &rhs );
  207. WorkerThread &operator=( const WorkerThread &rhs );
  208. };
  209. } // End of namespace OnlineGameLib
  210. } // End of namespace Win32
  211. #endif // __INCLUDE_SOCKETSERVER_H__