AsyncSocketServerImpl.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. #ifndef __ASYNCSOCKETSERVERIMPL_20160228__
  2. #define __ASYNCSOCKETSERVERIMPL_20160228__
  3. #pragma once
  4. #pragma warning(push)
  5. #pragma warning(disable:4995)
  6. #include <vector>
  7. #include <list>
  8. #include <algorithm>
  9. #pragma warning(pop)
  10. #include "CritSection.h"
  11. #include "SocketHandle.h"
  12. /************************************************************************/
  13. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  14. /* 模 块 名:PerSocketContext;
  15. /* 描 述:重叠IO缓冲类,每个客户端连接对象类;
  16. /*
  17. /* 版 本:[V];
  18. /* 作 者:[IT];
  19. /* 日 期:[2/23/2016];
  20. /*
  21. /*
  22. /* 注 意:;
  23. /*
  24. /* 修改记录:[IT];
  25. /* 修改日期:;
  26. /* 修改版本:;
  27. /* 修改内容:;
  28. /************************************************************************/
  29. class PerSocketContext
  30. {
  31. public:
  32. PerSocketContext(SOCKET sock):_socket(sock){
  33. _npendingSize = 0;
  34. _ncurSize = 0;
  35. _pendingbuf = NULL;
  36. memset(&_Overlapped, 0, sizeof(_Overlapped));
  37. }
  38. explicit PerSocketContext(SOCKET sock, size_t size): _socket(sock){
  39. _npendingSize = 0;
  40. _pendingbuf = NULL;
  41. _ncurSize= 0;
  42. memset(&_Overlapped, 0, sizeof(_Overlapped));
  43. _data.resize( size );
  44. }
  45. PerSocketContext(const PerSocketContext& sbuf){
  46. Copy(sbuf);
  47. }
  48. PerSocketContext& operator=(const PerSocketContext& sbuf){
  49. return Copy(sbuf);
  50. }
  51. ~PerSocketContext(){
  52. Free();
  53. }
  54. bool IsValid() const { return (_socket != INVALID_SOCKET); }
  55. void ReAlloc( size_t count) { _data.resize(count); }
  56. void Free()
  57. {
  58. _data.clear();
  59. if (_pendingbuf)
  60. delete []_pendingbuf;
  61. _pendingbuf = NULL;
  62. }
  63. size_t BufferSize() const { return _data.size(); }
  64. PerSocketContext& Copy(const PerSocketContext& sbuf)
  65. {
  66. if ( this != &sbuf )
  67. {
  68. _socket = sbuf._socket;
  69. _sockAddr = sbuf._sockAddr;
  70. if ( !sbuf._data.empty() )
  71. {
  72. _data.resize( sbuf._data.size() );
  73. memcpy(&_data[0], &(sbuf._data[0]), _data.size());
  74. }
  75. _ncurSize = sbuf._ncurSize;
  76. _pendingbuf = NULL;
  77. _npendingSize = sbuf._npendingSize;
  78. if ( !sbuf._pendingbuf )
  79. {
  80. _pendingbuf = new unsigned char[_npendingSize];
  81. memcpy(_pendingbuf, sbuf._pendingbuf,_ncurSize);
  82. }
  83. }
  84. return *this;
  85. }
  86. // Quick access operator
  87. operator SOCKET() { return _socket; }
  88. operator SOCKET() const { return _socket; }
  89. operator SockAddrIn&() { return _sockAddr; }
  90. operator const SockAddrIn&() const { return _sockAddr; }
  91. operator LPSOCKADDR() { return _sockAddr; }
  92. operator LPWSAOVERLAPPED() { return &_Overlapped; }
  93. operator LPBYTE() { return &_data[0]; }
  94. bool IsEqual(const PerSocketContext& sbuf) const { return (_socket == sbuf._socket); }
  95. bool operator==(const PerSocketContext& sbuf) const { return IsEqual( sbuf ); }
  96. bool operator==(SOCKET sock) const { return (_socket == sock); }
  97. bool operator!=(const PerSocketContext& sbuf) const { return !IsEqual( sbuf ); }
  98. private:
  99. SOCKET _socket;
  100. SockAddrIn _sockAddr;
  101. WSAOVERLAPPED _Overlapped;
  102. std::vector<unsigned char> _data;
  103. PerSocketContext();
  104. public:
  105. unsigned char *_pendingbuf; // 超过一次接收包,需要分包处理的包缓冲区;
  106. unsigned int _npendingSize; // 总包大小(多个分包);
  107. unsigned int _ncurSize; // 当前接收到的分包接收的大小;
  108. };
  109. typedef std::list<PerSocketContext> SocketContextList;
  110. static DWORD WM_ADD_CONNECTION = WM_USER+0x101;
  111. /************************************************************************/
  112. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  113. /* 模 块 名:IASocketServerHandler;
  114. /* 描 述:Event handler that ASocketServerImpl<T> must implement;
  115. /* This class is not required, you can do the same thing as long your class exposes these functions.
  116. /* (These functions are not pure to save you some typing)
  117. /*
  118. /* 版 本:[V];
  119. /* 作 者:[IT];
  120. /* 日 期:[2/23/2016];
  121. /*
  122. /*
  123. /* 注 意:;
  124. /*
  125. /* 修改记录:[IT];
  126. /* 修改日期:;
  127. /* 修改版本:;
  128. /* 修改内容:;
  129. /************************************************************************/
  130. class IASocketServerHandler
  131. {
  132. public:
  133. virtual void OnThreadBegin(CSocketHandle* ) {}
  134. virtual void OnThreadExit(CSocketHandle* ) {}
  135. virtual void OnThreadLoopEnter(CSocketHandle* ) {}
  136. virtual void OnThreadLoopLeave(CSocketHandle* ) {}
  137. virtual void OnAddConnection(CSocketHandle* , SOCKET ) {}
  138. virtual void OnRemoveConnection(CSocketHandle* , SOCKET ) {}
  139. virtual void OnDataReceived(CSocketHandle* , const SOCKET sClient, const BYTE* pData, DWORD dwCount, const SockAddrIn&, BYTE **pendingbuf, unsigned int& npendingSize, unsigned int& ncursize) {}
  140. virtual void OnConnectionFailure(CSocketHandle*, SOCKET) {}
  141. virtual void OnConnectionDropped(CSocketHandle* ) {}
  142. virtual void OnConnectionError(CSocketHandle* , DWORD ) {}
  143. };
  144. /************************************************************************/
  145. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  146. /* 模 块 名:ASocketServerImpl<T, tBufferSize>;
  147. /* 描 述:Because <typename T> may refer to any class of your choosing,Server Communication wrapper;
  148. /*
  149. /* 版 本:[V];
  150. /* 作 者:[IT];
  151. /* 日 期:[2/23/2016];
  152. /*
  153. /*
  154. /* 注 意:;
  155. /*
  156. /* 修改记录:[IT];
  157. /* 修改日期:;
  158. /* 修改版本:;
  159. /* 修改内容:;
  160. /************************************************************************/
  161. template <typename T, size_t tBufferSize = 2048>
  162. class ASocketServerImpl
  163. {
  164. typedef ASocketServerImpl<T, tBufferSize> thisClass;
  165. public:
  166. ASocketServerImpl(): _pInterface(0), _thread(0), _threadId(0)
  167. {
  168. }
  169. void SetInterface(T* pInterface)
  170. {
  171. ::InterlockedExchangePointer(reinterpret_cast<void**>(&_pInterface), pInterface);
  172. }
  173. operator CSocketHandle*() throw()
  174. {
  175. return( &_socket );
  176. }
  177. CSocketHandle* operator->() throw()
  178. {
  179. return( &_socket );
  180. }
  181. bool IsOpen() const
  182. {
  183. return _socket.IsOpen();
  184. }
  185. bool CreateSocket(LPCTSTR pszHost, LPCTSTR pszServiceName, int nFamily, int nType, UINT uOptions = 0)
  186. {
  187. return _socket.CreateSocket(pszHost, pszServiceName, nFamily, nType, uOptions);
  188. }
  189. void Close()
  190. {
  191. _socket.Close();
  192. }
  193. DWORD Read(LPBYTE lpBuffer, DWORD dwSize, LPSOCKADDR lpAddrIn = NULL, DWORD dwTimeout = INFINITE)
  194. {
  195. return _socket.Read(lpBuffer, dwSize, lpAddrIn, dwTimeout);
  196. }
  197. DWORD Write(const LPBYTE lpBuffer, DWORD dwCount, const LPSOCKADDR lpAddrIn = NULL, DWORD dwTimeout = INFINITE)
  198. {
  199. return _socket.Write(lpBuffer, dwCount, lpAddrIn, dwTimeout);
  200. }
  201. const SocketContextList& GetSocketList() const
  202. {
  203. // direct access! - use Lock/Unlock to protect
  204. return _sockets;
  205. }
  206. SocketContextList& GetClientSocketList()
  207. {
  208. // direct access! - use Lock/Unlock to protect
  209. return _sockets;
  210. }
  211. bool Lock()
  212. {
  213. return _critSection.Lock();
  214. }
  215. bool Unlock()
  216. {
  217. return _critSection.Unlock();
  218. }
  219. void ResetConnectionList()
  220. {
  221. AutoThreadSection aSection(&_critSection);
  222. _sockets.clear();
  223. }
  224. size_t GetConnectionCount() //const
  225. {
  226. AutoThreadSection aSection(&_critSection);
  227. return _sockets.size();
  228. }
  229. void AddConnection(SOCKET sock)
  230. {
  231. AutoThreadSection aSection(&_critSection);
  232. _sockets.push_back( sock );
  233. }
  234. void RemoveConnection(SOCKET sock)
  235. {
  236. AutoThreadSection aSection(&_critSection);
  237. _sockets.remove( sock );
  238. }
  239. PerSocketContext* GetConnectionBuffer(SOCKET sock)
  240. {
  241. AutoThreadSection aSection(&_critSection);
  242. SocketContextList::iterator iter = std::find(_sockets.begin(), _sockets.end(), sock);
  243. return ((iter != _sockets.end()) ? &(*iter) : NULL);
  244. }
  245. bool CloseConnection(SOCKET sock)
  246. {
  247. return CSocketHandle::ShutdownConnection( sock );
  248. }
  249. void CloseAllConnections();
  250. bool StartServer(LPCTSTR pszHost, LPCTSTR pszServiceName, int nFamily, int nType, UINT uOptions = 0);
  251. void Terminate(DWORD dwTimeout = INFINITE);
  252. static bool IsConnectionDropped(DWORD dwError);
  253. ThreadSection *ReturnSection() { return &_critSection; }
  254. protected:
  255. void Run();
  256. void IoRun();
  257. bool AsyncRead(PerSocketContext* pBuffer);
  258. void OnIOComplete(DWORD dwError, PerSocketContext* pBuffer, DWORD cbTransferred, DWORD dwFlags);
  259. static DWORD WINAPI SocketServerProc(thisClass* _this);
  260. static DWORD WINAPI SocketServerIOProc(thisClass* _this);
  261. static void WINAPI CompletionRoutine(DWORD dwError, DWORD cbTransferred,
  262. LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags);
  263. T* _pInterface;
  264. HANDLE _thread;
  265. DWORD _threadId;
  266. ThreadSection _critSection;
  267. CSocketHandle _socket; // 服务端SOCKET;
  268. SocketContextList _sockets; // 客户端SOCKET连接列表;
  269. };
  270. template <typename T, size_t tBufferSize>
  271. void ASocketServerImpl<T, tBufferSize>::CloseAllConnections()
  272. {
  273. AutoThreadSection aSection(&_critSection);
  274. if ( !_sockets.empty() )
  275. {
  276. // NOTE(elaurentin): this function closes all connections but handles are kept inside of list
  277. // (socket handles are removed by the pooling thread)
  278. SocketContextList::iterator iter;
  279. for(iter = _sockets.begin(); iter != _sockets.end(); ++iter)
  280. {
  281. CloseConnection( (*iter) );
  282. }
  283. }
  284. }
  285. template <typename T, size_t tBufferSize>
  286. bool ASocketServerImpl<T, tBufferSize>::StartServer(LPCTSTR pszHost, LPCTSTR pszServiceName, int nFamily, int nType, UINT uOptions)
  287. {
  288. // must be closed first...
  289. if ( IsOpen() ) return false;
  290. bool result = false;
  291. result = _socket.CreateSocket(pszHost, pszServiceName, nFamily, nType, uOptions);
  292. if ( result )
  293. {
  294. _thread = AtlCreateThread(SocketServerProc, this);
  295. if ( _thread == NULL )
  296. {
  297. DWORD dwError = GetLastError();
  298. _socket.Close();
  299. SetLastError(dwError);
  300. result = false;
  301. }
  302. }
  303. return result;
  304. }
  305. template <typename T, size_t tBufferSize>
  306. void ASocketServerImpl<T, tBufferSize>::Run()
  307. {
  308. _ASSERTE( _pInterface != NULL && "Need an interface to pass events");
  309. SOCKET sock = _socket.GetSocket();
  310. int type = _socket.GetSocketType();
  311. // Notification: OnThreadBegin
  312. if ( _pInterface != NULL ) {
  313. _pInterface->OnThreadBegin(*this);
  314. }
  315. if (type == SOCK_STREAM)
  316. {
  317. HANDLE ioThread = NULL;
  318. DWORD ioThreadId = 0L;
  319. ioThread = CreateThreadT(0, 0, SocketServerIOProc, this, 0, &ioThreadId);
  320. if ( ioThread == NULL )
  321. {
  322. DWORD dwError = GetLastError();
  323. if ( _pInterface != NULL ) {
  324. _pInterface->OnConnectionError(*this, dwError);
  325. }
  326. }
  327. // In TCP mode, use an I/O thread to process all requests
  328. while( _socket.IsOpen() )
  329. {
  330. SOCKET newSocket = CSocketHandle::WaitForConnection(sock);
  331. if (!_socket.IsOpen())
  332. break;
  333. if (!PostThreadMessage(ioThreadId, WM_ADD_CONNECTION, 0, static_cast<ULONG_PTR>(newSocket)))
  334. {
  335. // Notification: OnConnectionFailure
  336. if ( _pInterface != NULL ) {
  337. _pInterface->OnConnectionFailure(*this, newSocket);
  338. }
  339. }
  340. }
  341. // close all connections
  342. CloseAllConnections();
  343. // wait for io thread
  344. if ( ioThread != NULL )
  345. {
  346. PostThreadMessage(ioThreadId, WM_QUIT, 0, 0);
  347. WaitForSingleObject(ioThread, INFINITE);
  348. CloseHandle(ioThread);
  349. }
  350. ResetConnectionList();
  351. }
  352. else
  353. {
  354. // UDP mode - let's reuse our thread here
  355. try
  356. {
  357. PerSocketContext ioBuffer(_socket.GetSocket(), tBufferSize);
  358. AsyncRead( &ioBuffer );
  359. // Save our thread id so we can exit gracefully
  360. _threadId = GetCurrentThreadId();
  361. // Process UDP packets
  362. IoRun();
  363. }
  364. catch(std::bad_alloc&)
  365. { /* memory exception */
  366. if ( _pInterface != NULL )
  367. {
  368. _pInterface->OnConnectionError(*this, ERROR_NOT_ENOUGH_MEMORY);
  369. }
  370. }
  371. }
  372. // Notification: OnThreadExit
  373. if ( _pInterface != NULL ) {
  374. _pInterface->OnThreadExit(*this);
  375. }
  376. }
  377. template <typename T, size_t tBufferSize>
  378. void ASocketServerImpl<T, tBufferSize>::IoRun()
  379. {
  380. _ASSERTE( _pInterface != NULL && "Need an interface to pass events");
  381. MSG msg;
  382. ::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
  383. // Notification: OnThreadLoopEnter
  384. if ( _pInterface != NULL ) {
  385. _pInterface->OnThreadLoopEnter(*this);
  386. }
  387. DWORD dwResult;
  388. while( (dwResult = MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_ALLEVENTS, MWMO_ALERTABLE)) != WAIT_FAILED)
  389. {
  390. msg.message = 0;
  391. PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
  392. // exit on WM_QUIT or main socket closed
  393. if ( msg.message == WM_QUIT || !_socket.IsOpen() )
  394. break;
  395. else if ( msg.message == WM_ADD_CONNECTION )
  396. {
  397. SOCKET sock = static_cast<SOCKET>(msg.lParam);
  398. AddConnection(sock);
  399. PerSocketContext* pBuffer = GetConnectionBuffer(sock);
  400. //pBuffer->dwTime = GetTickCount(); // Jeff add 2015.10.22
  401. _ASSERTE( pBuffer != NULL );
  402. if ( pBuffer != NULL )
  403. {
  404. pBuffer->ReAlloc( tBufferSize );
  405. if (!AsyncRead(pBuffer))
  406. {
  407. // remove and close connection
  408. // 清除SOCK不在这里做,因为清除线程里会有清除,这里也清除;
  409. RemoveConnection( sock );//Jeff.wasn't remove at here;
  410. CloseConnection( sock );// Jeff.doesn't close socket here;
  411. }
  412. else
  413. {
  414. // Notification: OnAddConnection
  415. if ( _pInterface != NULL ) {
  416. _pInterface->OnAddConnection(*this, sock);
  417. }
  418. }
  419. }
  420. }
  421. }
  422. // Notification: OnThreadLoopLeave
  423. if ( _pInterface != NULL ) {
  424. _pInterface->OnThreadLoopLeave(*this);
  425. }
  426. }
  427. template <typename T, size_t tBufferSize>
  428. bool ASocketServerImpl<T, tBufferSize>::AsyncRead(PerSocketContext* pBuffer)
  429. {
  430. CSocketHandle sockHandle;
  431. DWORD dwRead;
  432. PerSocketContext& sbuf = (*pBuffer);
  433. SOCKET sock = static_cast<SOCKET>(sbuf);
  434. sockHandle.Attach( sock );
  435. int type = sockHandle.GetSocketType();
  436. LPWSAOVERLAPPED lpOverlapped = static_cast<LPWSAOVERLAPPED>(sbuf);
  437. lpOverlapped->hEvent = reinterpret_cast<HANDLE>(this);
  438. lpOverlapped->Pointer = reinterpret_cast<PVOID>(pBuffer);
  439. if (type == SOCK_STREAM) {
  440. // TCP - save current peer address
  441. sockHandle.GetPeerName( sbuf );
  442. dwRead = sockHandle.ReadEx(static_cast<LPBYTE>(sbuf), // buffer
  443. static_cast<DWORD>(sbuf.BufferSize()), // buffer size
  444. NULL, // sockaddr
  445. lpOverlapped, // overlapped
  446. thisClass::CompletionRoutine );
  447. } else {
  448. dwRead = sockHandle.ReadEx(static_cast<LPBYTE>(sbuf), // buffer
  449. static_cast<DWORD>(sbuf.BufferSize()), // buffer size
  450. static_cast<LPSOCKADDR>(sbuf), // sockaddr
  451. lpOverlapped, // overlapped
  452. thisClass::CompletionRoutine );
  453. }
  454. sockHandle.Detach();
  455. return ( dwRead != -1L );
  456. }
  457. template <typename T, size_t tBufferSize>
  458. void ASocketServerImpl<T, tBufferSize>::OnIOComplete(DWORD dwError, PerSocketContext* pBuffer, DWORD cbTransferred, DWORD /*dwFlags*/)
  459. {
  460. _ASSERTE( _pInterface != NULL && "Need an interface to pass events");
  461. _ASSERTE( pBuffer != NULL && "Invalid Buffer");
  462. if ( pBuffer != NULL )
  463. {
  464. //pBuffer->dwTime = GetTickCount(); // Jeff add 2015.10.22
  465. CSocketHandle sockHandle;
  466. SOCKET sock = static_cast<SOCKET>(*pBuffer);
  467. sockHandle.Attach( sock );
  468. int type = sockHandle.GetSocketType();
  469. if ( dwError == NOERROR )
  470. {
  471. if (type == SOCK_STREAM && cbTransferred == 0L )
  472. {
  473. // connection broken
  474. if ( _pInterface != NULL ) {
  475. _pInterface->OnConnectionDropped(*this);
  476. }
  477. // remove connection
  478. // 清除SOCK不在这里做,因为清除线程里会有清除,这里也清除;
  479. RemoveConnection( sock );// Jeff.doesn't remove socket here;
  480. CloseConnection(sock);
  481. if ( _pInterface != NULL ) {
  482. // Notification: OnRemoveConnection
  483. _pInterface->OnRemoveConnection(*this, sock);
  484. }
  485. }
  486. else
  487. {
  488. // Notification: OnDataReceived
  489. if ( _pInterface != NULL ) {
  490. _pInterface->OnDataReceived(*this,
  491. static_cast<SOCKET>(*pBuffer),
  492. static_cast<LPBYTE>(*pBuffer), // Data
  493. cbTransferred, // Number of bytes
  494. static_cast<SockAddrIn&>(*pBuffer),
  495. (BYTE**)(&pBuffer->_pendingbuf),
  496. pBuffer->_npendingSize,
  497. pBuffer->_ncurSize);
  498. }
  499. // schedule another read for this socket
  500. AsyncRead( pBuffer );
  501. }
  502. }
  503. else
  504. {
  505. for ( ; _pInterface != NULL; )
  506. {
  507. if (IsConnectionDropped( dwError) ) {
  508. // Notification: OnConnectionDropped
  509. if (type == SOCK_STREAM || (dwError == WSAENOTSOCK || dwError == WSAENETDOWN))
  510. //if (type == SOCK_STREAM && (dwError == WSAENOTSOCK || dwError == WSAENETDOWN))// Jeff.set.
  511. {
  512. _pInterface->OnConnectionDropped(*this);
  513. // 清除SOCK不在这里做,因为清除线程里会有清除,这里也清除;
  514. CloseConnection(sock);
  515. RemoveConnection( sock );
  516. //CloseConnection( sock );
  517. //_pInterface->OnConnectionError(*this, dwError); // Jeff.add
  518. type = -1; // don't schedule other request
  519. break;
  520. }
  521. }
  522. // Notification: OnConnectionError
  523. _pInterface->OnConnectionError(*this, dwError);
  524. break;
  525. }
  526. // Schedule read request
  527. if ((type == SOCK_STREAM || type == SOCK_DGRAM) && _socket.IsOpen() ) {
  528. AsyncRead( pBuffer );
  529. }
  530. }
  531. // Detach or Close this socket (TCP-mode only)
  532. if (type != SOCK_STREAM ||
  533. (type == SOCK_STREAM && cbTransferred != 0L) )
  534. {
  535. sockHandle.Detach();
  536. }
  537. }
  538. }
  539. template <typename T, size_t tBufferSize>
  540. void ASocketServerImpl<T, tBufferSize>::Terminate(DWORD dwTimeout /*= INFINITE*/)
  541. {
  542. _socket.Close();
  543. if ( _thread != NULL )
  544. {
  545. if ( _threadId != 0 ) {
  546. PostThreadMessage(_threadId, WM_QUIT, 0, 0);
  547. }
  548. if ( WaitForSingleObject(_thread, dwTimeout) == WAIT_TIMEOUT ) {
  549. TerminateThread(_thread, 1);
  550. }
  551. CloseHandle(_thread);
  552. _thread = NULL;
  553. _threadId = 0L;
  554. }
  555. }
  556. template <typename T, size_t tBufferSize>
  557. DWORD WINAPI ASocketServerImpl<T, tBufferSize>::SocketServerProc(thisClass* _this)
  558. {
  559. if ( _this != NULL )
  560. {
  561. _this->Run();
  562. }
  563. return 0;
  564. }
  565. template <typename T, size_t tBufferSize>
  566. DWORD WINAPI ASocketServerImpl<T, tBufferSize>::SocketServerIOProc(thisClass* _this)
  567. {
  568. if ( _this != NULL )
  569. {
  570. _this->IoRun();
  571. }
  572. return 0;
  573. }
  574. template <typename T, size_t tBufferSize>
  575. void WINAPI ASocketServerImpl<T, tBufferSize>::CompletionRoutine(DWORD dwError, DWORD cbTransferred,
  576. LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
  577. {
  578. thisClass* _this = reinterpret_cast<thisClass*>( lpOverlapped->hEvent );
  579. if ( _this != NULL )
  580. {
  581. PerSocketContext* pBuffer = reinterpret_cast<PerSocketContext*>(lpOverlapped->Pointer);
  582. _this->OnIOComplete(dwError, pBuffer, cbTransferred, dwFlags);
  583. }
  584. }
  585. template <typename T, size_t tBufferSize>
  586. bool ASocketServerImpl<T, tBufferSize>::IsConnectionDropped(DWORD dwError)
  587. {
  588. // see: winerror.h for definition
  589. switch( dwError )
  590. {
  591. case WSAENOTSOCK:
  592. case WSAENETDOWN:
  593. case WSAENETUNREACH:
  594. case WSAENETRESET:
  595. case WSAECONNABORTED:
  596. case WSAECONNRESET:
  597. case WSAESHUTDOWN:
  598. case WSAEHOSTDOWN:
  599. case WSAEHOSTUNREACH:
  600. return true;
  601. default:
  602. TRACE("--------------%d\r\n",dwError);
  603. break;
  604. }
  605. return false;
  606. }
  607. #endif // __ASYNCSOCKETSERVERIMPL_20160228__