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

模拟服务器

开发平台:

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. #include "..heaveninterfaceIServer.h"
  22. /*
  23.  * namespace OnlineGameLib::Win32
  24.  */
  25. namespace OnlineGameLib {
  26. namespace Win32 {
  27. /*
  28.  * CSocketServer
  29.  */
  30. class CSocketServer : 
  31.    protected CThread, 
  32.    private CUsesWinsock, 
  33.    protected CIOBuffer::Allocator
  34. {
  35. public:
  36. class Socket;
  37. friend class Socket;
  38. virtual ~CSocketServer();
  39. using CThread::Start;
  40. void StartAcceptingConnections();
  41. void StopAcceptingConnections();
  42. void InitiateShutdown();
  43. void WaitForShutdownToComplete();
  44. protected:
  45. class WorkerThread;
  46. friend class WorkerThread;
  47. CSocketServer(
  48. size_t maxFreeSockets,
  49. size_t maxFreeBuffers,
  50. size_t bufferSize = 1024,
  51. size_t numThreads = 0,
  52. bool useSequenceNumbers = true,
  53. bool postZeroByteReads = false);
  54. void Open( unsigned long addressToListenOn, unsigned short portToListenOn );
  55. static void SetServerDataPtr( Socket *pSocket, void *pData );
  56. static void *GetServerDataPtr( const Socket *pSocket );
  57. static void WriteCompleted( Socket *pSocket );
  58. static CSocketServer &GetServer( Socket *pSocket );
  59. /*
  60.  * Thread virtual function
  61.  */
  62. virtual int Run();
  63. enum enumConnectionErrorSource
  64. {
  65. enumZeroByteReadError,
  66. enumReadError,
  67. enumWriteError
  68. };
  69. private:
  70. class UserData;
  71. class ServerData;
  72. /*
  73.  * Override this to create your worker thread
  74.  */
  75. virtual WorkerThread *CreateWorkerThread( CIOCompletionPort &iocp );
  76. /*
  77.  * Override this to create the listening socket of your choice
  78.  */
  79. virtual SOCKET CreateListeningSocket( unsigned long address, 
  80. unsigned short port );
  81. /*
  82.  * Interface for derived classes to receive state change notifications...
  83.  */
  84. virtual void OnStartAcceptingConnections() {}
  85. virtual void OnStopAcceptingConnections() {}
  86. virtual void OnShutdownInitiated() {}
  87. virtual void OnShutdownComplete() {}
  88. virtual void OnConnectionCreated() {}
  89. virtual void OnConnectionEstablished( Socket *pSocket, CIOBuffer *pAddress ) = 0;
  90. virtual void OnConnectionClientClose( Socket * /*pSocket*/ ) {}
  91. virtual void OnConnectionReset( Socket * /*pSocket*/ ) {}
  92. virtual bool OnConnectionClosing( Socket * /*pSocket*/ ) { return false; }
  93. virtual void OnConnectionClosed( Socket * /*pSocket*/ ) {}
  94. virtual void OnConnectionDestroyed() {}
  95. virtual void OnConnectionError( enumConnectionErrorSource source,
  96. Socket *pSocket,
  97. CIOBuffer *pBuffer,
  98. DWORD lastError );
  99. virtual void OnError( const _tstring &message );
  100. virtual void OnBufferCreated() {}
  101. virtual void OnBufferAllocated() {}
  102. virtual void OnBufferReleased() {}
  103. virtual void OnThreadCreated() {}
  104. virtual void OnThreadDestroyed() {}
  105. virtual bool FilterSocketShutdown( Socket *pSocket, int how );
  106. virtual bool FilterSocketClose( Socket *pSocket );
  107. virtual void ReadCompleted( Socket *pSocket, CIOBuffer *pBuffer ) = 0;
  108. virtual void WriteCompleted( Socket *pSocket, CIOBuffer *pBuffer );
  109. void ReleaseSockets();
  110. Socket *AllocateSocket( SOCKET theSocket );
  111. void ReleaseSocket( Socket *pSocket );
  112. void DestroySocket( Socket *pSocket );
  113. enum enumIO_Operation
  114. enumIO_Zero_Byte_Read_Request,
  115. enumIO_Zero_Byte_Read_Completed,
  116. enumIO_Read_Request, 
  117. enumIO_Read_Completed, 
  118. enumIO_Write_Request, 
  119. enumIO_Write_Completed,
  120. };
  121. void PostIoOperation( Socket *pSocket, 
  122. CIOBuffer *pBuffer, 
  123. enumIO_Operation operation );
  124. const size_t m_numThreads;
  125. CCriticalSection m_listManipulationSection;
  126. typedef OnlineGameLib::TNodeList< Socket > SocketList;
  127. SocketList m_activeList;
  128. SocketList m_freeList;
  129. SOCKET m_listeningSocket;
  130. CIOCompletionPort m_iocp;
  131. CManualResetEvent m_shutdownEvent;
  132. CManualResetEvent m_acceptConnectionsEvent;
  133. unsigned long m_address;
  134. unsigned short m_port;
  135. const size_t m_maxFreeSockets;
  136. const bool m_useSequenceNumbers;
  137. const bool m_postZeroByteReads;
  138. /*
  139.  * No copies do not implement
  140.  */
  141. CSocketServer( const CSocketServer &rhs );
  142. CSocketServer &operator=( const CSocketServer &rhs );
  143. };
  144. /*
  145.  * CSocketServer::UserData
  146.  */
  147. class CSocketServer::UserData : public COpaqueUserData
  148. {
  149.    /*
  150.     * UserData is a shim class that allows Socket to inherit from two 
  151.     * COpaqueUserData bases without ambiguity
  152. */
  153. };
  154. /*
  155.  * CSocketServer::ServerData
  156.  */
  157. class CSocketServer::ServerData : public COpaqueUserData
  158. {
  159.    /*
  160.     * ServerData is a shim class that allows Socket to inherit from two 
  161.     * COpaqueUserData bases without ambiguity
  162. */
  163. };
  164. /*
  165.  * CSocketServer::Socket
  166.  */
  167. class CSocketServer::Socket : 
  168.    public CNodeList::Node, 
  169.    public CSocketServer::UserData, 
  170.    protected CSocketServer::ServerData
  171. {
  172. public:
  173. friend class CSocketServer;
  174. friend class CSocketServer::WorkerThread;
  175. using UserData::SetUserData;
  176. using UserData::GetUserData;
  177. using UserData::SetUserPtr;
  178. using UserData::GetUserPtr;
  179. bool Read( CIOBuffer *pBuffer = 0, bool throwOnFailure = false );
  180. bool Write( const char *pData, 
  181. size_t dataLength, 
  182. bool throwOnFailure = false );
  183. bool Write( const BYTE *pData, 
  184. size_t dataLength,
  185. bool throwOnFailure = false );
  186. bool Write( CIOBuffer *pBuffer,
  187. bool throwOnFailure = false );
  188. void AddRef();
  189. void Release();
  190. void Shutdown( int how = SD_BOTH );
  191. void Close();
  192. void AbortiveClose();
  193. bool IsConnected( int how = SD_BOTH ) const;
  194. void SetMessageCallback(IMessageProcess* pIM)
  195. { m_pIM = pIM; }
  196. IMessageProcess* GetMessageCallback() const
  197. { return m_pIM; }
  198. private:
  199. Socket( CSocketServer &server,                                 
  200. SOCKET socket,
  201. bool useSequenceNumbers );
  202. ~Socket();
  203. void Attach( SOCKET socket );
  204. void *GetServerDataPtr() const
  205. {
  206. return ServerData::GetUserPtr();
  207. }
  208. void SetServerDataPtr( void *pData )
  209. {
  210. ServerData::SetUserPtr( pData );
  211. }
  212. void WriteCompleted();
  213. bool WritePending();
  214. void OnClientClose();
  215. void OnConnectionReset();
  216. bool IsValid();
  217. void InternalClose();
  218. void OnConnectionError( CSocketServer::enumConnectionErrorSource source,
  219. CIOBuffer *pBuffer,
  220. DWORD lastError);
  221. CCriticalSection m_crit;
  222. CCriticalSection m_critWriteQueue;
  223. CSocketServer &m_server;
  224. SOCKET m_socket;
  225. long m_ref;
  226. long m_outstandingWrites;
  227. /*
  228.    * We could store all of these 1 bit flags 
  229.    * in with the outstanding write count..
  230.    */
  231. bool m_readShutdown;       
  232. bool m_writeShutdown;
  233. bool m_closing;
  234. long m_clientClosed;       
  235. IMessageProcess* m_pIM;
  236. enum enumSequenceType
  237. {
  238. enumReadSequenceNo,
  239. enumWriteSequenceNo,
  240. enumFilteredReadSequenceNo,
  241. enumFilteredWriteSequenceNo,
  242. enumMaxSequenceNo
  243. };
  244. long GetSequenceNumber( enumSequenceType type );
  245. CIOBuffer *GetNextBuffer( CIOBuffer *pBuffer = 0 );
  246. struct SequenceData
  247. {
  248. explicit SequenceData( CCriticalSection &section );
  249. void Reset();
  250. long m_numbers[4];
  251. CIOBuffer::InOrderBufferList m_outOfSequenceWrites;
  252. };
  253. SequenceData *m_pSequenceData;
  254. /*
  255.  * No copies do not implement
  256.  */
  257. Socket( const Socket &rhs );
  258. Socket &operator=( const Socket &rhs );
  259. };
  260. /*
  261.  * CSocketServer::WorkerThread
  262.  */
  263. class CSocketServer::WorkerThread : public CThread
  264. {
  265. public :
  266. WorkerThread( CSocketServer &server, CIOCompletionPort &iocp );
  267. virtual ~WorkerThread();
  268. void InitiateShutdown();
  269. void WaitForShutdownToComplete();
  270. protected:
  271. /*
  272.  * Thread virtual function
  273.  */
  274. virtual int Run();
  275. virtual void HandleOperation( Socket *pSocket,
  276. CIOBuffer *pBuffer,
  277. DWORD dwIoSize,
  278. bool weClosedSocket );
  279. private:
  280. void ZeroByteRead( Socket *pSocket, CIOBuffer *pBuffer ) const;
  281. void Read( Socket *pSocket, CIOBuffer *pBuffer ) const;
  282. void Write( Socket *pSocket, CIOBuffer *pBuffer ) const;
  283. CSocketServer &m_server;
  284. CIOCompletionPort &m_iocp;
  285. /*
  286.  * No copies do not implement
  287.  */
  288. WorkerThread( const WorkerThread &rhs );
  289. WorkerThread &operator=( const WorkerThread &rhs );
  290. };
  291. } // End of namespace OnlineGameLib
  292. } // End of namespace Win32
  293. #endif // __INCLUDE_SOCKETSERVER_H__