IServerImpl.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #include "StdAfx.h"
  2. #include "IServerImpl.h"
  3. #include <comdef.h>
  4. #include <atlbase.h>
  5. #include <strsafe.h>
  6. #include "ThreadPool.hpp"
  7. #include "ClientProcess.h"
  8. // #ifdef _DEBUG
  9. // #define new DEBUG_NEW
  10. // #endif
  11. const int AF_IPV4 = 0;
  12. const int AF_IPV6 = 1;
  13. const int SOCK_TCP = SOCK_STREAM-1;
  14. const int SOCK_UDP = SOCK_DGRAM-1;
  15. namespace ServerSocketImpl
  16. {
  17. IServerImpl* g_pServerSocket[20] = {0};
  18. IServerImpl::IServerImpl():m_nMode(AF_IPV4)
  19. ,m_nSockType(SOCK_TCP)
  20. ,m_strPort(_T("64320"))
  21. ,m_nSocketIndex(0)
  22. {
  23. m_bStopbeat = FALSE;
  24. m_hRunObject = NULL;
  25. m_hClearInvalidateSocketThread = NULL;
  26. InitializeCriticalSection( &m_csProcessData );
  27. m_SocketServer.SetInterface(this);
  28. }
  29. IServerImpl::~IServerImpl()
  30. {
  31. m_SocketServer.Terminate();
  32. DeleteCriticalSection( &m_csProcessData );
  33. }
  34. BOOL IServerImpl::Initialize()
  35. {
  36. TCHAR szIPAddr[MAX_PATH] = { 0 };
  37. CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET);
  38. //AppendText(_T("Local Address (IPv4): %s\r\n"), szIPAddr);
  39. CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET6);
  40. //AppendText(_T("Local Address (IPv6): %s\r\n"), szIPAddr);
  41. return TRUE;
  42. }
  43. void IServerImpl::Start(IN LPCTSTR strPort,IN const int &nMode)
  44. {
  45. m_nMode = nMode;
  46. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  47. if (!m_SocketServer.StartServer(NULL, strPort, nFamily, (m_nSockType+1)))
  48. {
  49. //OutputDebugString(_T("\n连接服务器失败!\n"));
  50. AfxMessageBox(_T("Failed to start server."), NULL, MB_ICONSTOP);
  51. return;
  52. }
  53. CClientProcess::GetInstance()->StartMsgWork();
  54. //SyncControls();
  55. }
  56. void IServerImpl::Stop()
  57. {
  58. if(m_hRunObject)
  59. SetEvent(m_hRunObject);
  60. if( m_hClearInvalidateSocketThread )
  61. {
  62. if (WaitForSingleObject(m_hClearInvalidateSocketThread,INFINITE) != WAIT_FAILED)
  63. {
  64. CloseHandle(m_hClearInvalidateSocketThread);
  65. m_hClearInvalidateSocketThread = NULL;
  66. }
  67. }
  68. if ( m_hRunObject )
  69. CloseHandle( m_hRunObject );
  70. m_hRunObject = NULL;
  71. m_SocketServer.Terminate();
  72. //SyncControls();
  73. }
  74. void IServerImpl::Send()
  75. {
  76. if ( m_SocketServer.IsOpen() )
  77. {
  78. CString strMsg;
  79. //m_ctlMessage.GetWindowText( strMsg );
  80. if ( strMsg.IsEmpty() )
  81. {
  82. //AppendText( _T("Please enter the message to send.\r\n") );
  83. return;
  84. }
  85. USES_CONVERSION;
  86. if (m_nSockType == SOCK_TCP)
  87. {
  88. const LPBYTE lpbData = (const LPBYTE)(T2CA(strMsg));
  89. // unsafe access to Socket list!
  90. #ifdef SOCKHANDLE_USE_OVERLAPPED
  91. const SocketContextList& sl = m_SocketServer.GetSocketList();
  92. for(SocketContextList::const_iterator citer = sl.begin(); citer != sl.end(); ++citer)
  93. #else
  94. const SocketList& sl = m_SocketServer.GetSocketList();
  95. for(SocketList::const_iterator citer = sl.begin(); citer != sl.end(); ++citer)
  96. #endif
  97. {
  98. CSocketHandle sockHandle;
  99. sockHandle.Attach( (*citer) );
  100. sockHandle.Write(lpbData, strMsg.GetLength(), NULL);
  101. sockHandle.Detach();
  102. }
  103. }
  104. else
  105. {
  106. SockAddrIn servAddr, sockAddr;
  107. m_SocketServer->GetSockName(servAddr);
  108. GetDestination(sockAddr);
  109. if ( servAddr != sockAddr )
  110. {
  111. m_SocketServer.Write((const LPBYTE)(T2CA(strMsg)), strMsg.GetLength(), sockAddr);
  112. }
  113. else
  114. {
  115. //AppendText( _T("Please change the port number to send message to a client.\r\n") );
  116. }
  117. }
  118. }
  119. else
  120. {
  121. AfxMessageBox(_T("Socket is not connected"));
  122. }
  123. }
  124. void IServerImpl::SendAll(CSocketHandle &sockHandle, unsigned char *pMsg, int nLength)
  125. {
  126. if ( m_SocketServer.IsOpen() )
  127. {
  128. USES_CONVERSION;
  129. if (m_nSockType == SOCK_TCP)
  130. {
  131. // unsafe access to Socket list!
  132. const LPBYTE lpbData = (const LPBYTE)(pMsg);
  133. sockHandle.Write(lpbData, nLength, NULL);
  134. }
  135. else
  136. {
  137. SockAddrIn servAddr, sockAddr;
  138. m_SocketServer->GetSockName(servAddr);
  139. GetDestination(sockAddr);
  140. if ( servAddr != sockAddr )
  141. {
  142. m_SocketServer.Write((const LPBYTE)*pMsg, nLength, sockAddr);
  143. }
  144. else
  145. {
  146. }
  147. }
  148. }
  149. else
  150. {
  151. }
  152. }
  153. void IServerImpl::ToprocessRecivebuf(IN PerSocketContext &sockHandle, IN const BYTE* pReceivebuf, IN DWORD dwReceiveSize)
  154. {
  155. }
  156. int IServerImpl::OnIntegrityPacket(IN PerSocketContext &sockHandle, IN void *pIntegrityPacket)
  157. {
  158. return 0;
  159. }
  160. void IServerImpl::GetAddress(const SockAddrIn& addrIn, CString& rString) const
  161. {
  162. TCHAR szIPAddr[MAX_PATH] = { 0 };
  163. CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn);
  164. rString.Format(_T("%s : %d"), szIPAddr, static_cast<int>(static_cast<UINT>(ntohs(addrIn.GetPort()))) );
  165. }
  166. void IServerImpl::AppendText(LPCTSTR lpszFormat, ...)
  167. {
  168. // if ( !::IsWindow(m_ctlMsgList.GetSafeHwnd()) ) return;
  169. // TCHAR szBuffer[512];
  170. // HWND hWnd = m_ctlMsgList.GetSafeHwnd();
  171. // DWORD dwResult = 0;
  172. // if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, 0, SMTO_NORMAL, 500L, &dwResult) != 0)
  173. // {
  174. // int nLen = (int) dwResult;
  175. // if (SendMessageTimeout(hWnd, EM_SETSEL, nLen, nLen, SMTO_NORMAL, 500L, &dwResult) != 0)
  176. // {
  177. // size_t cb = 0;
  178. // va_list args;
  179. // va_start(args, lpszFormat);
  180. // ::StringCchVPrintfEx(szBuffer, 512, NULL, &cb, 0, lpszFormat, args);
  181. // va_end(args);
  182. // SendMessageTimeout(hWnd, EM_REPLACESEL, FALSE, reinterpret_cast<LPARAM>(szBuffer), SMTO_NORMAL, 500L, &dwResult);
  183. // }
  184. // }
  185. }
  186. bool IServerImpl::GetDestination(SockAddrIn& addrIn) const
  187. {
  188. CString strPort;
  189. //GetDlgItemText(IDC_SVR_PORT, strPort);
  190. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  191. return addrIn.CreateFrom(NULL, strPort, nFamily);
  192. }
  193. bool IServerImpl::SetupMCAST()
  194. {
  195. const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2");
  196. const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address
  197. bool result = false;
  198. if ( m_nSockType == SOCK_UDP )
  199. {
  200. if ( m_nMode == AF_IPV4 ) {
  201. result = m_SocketServer->AddMembership(szIPv4MCAST, NULL);
  202. } else {
  203. result = m_SocketServer->AddMembership(szIPv6MCAST, NULL);
  204. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  205. hr = hr;
  206. }
  207. }
  208. return result;
  209. }
  210. ///////////////////////////////////////////////////////////////////////////////
  211. void IServerImpl::OnThreadBegin(CSocketHandle* pSH)
  212. {
  213. ASSERT( pSH == m_SocketServer );
  214. (pSH);
  215. CString strAddr;
  216. SockAddrIn sockAddr;
  217. m_SocketServer->GetSockName(sockAddr);
  218. GetAddress( sockAddr, strAddr );
  219. //AppendText( _T("Server Running on: %s\r\n"), strAddr);
  220. }
  221. void IServerImpl::OnThreadExit(CSocketHandle* pSH)
  222. {
  223. ASSERT( pSH == m_SocketServer );
  224. (pSH);
  225. //AppendText( _T("Server Down!\r\n"));
  226. }
  227. void IServerImpl::OnConnectionFailure(CSocketHandle* pSH, SOCKET newSocket)
  228. {
  229. ASSERT( pSH == m_SocketServer );
  230. (pSH);
  231. CString strAddr;
  232. CSocketHandle sockHandle;
  233. SockAddrIn sockAddr;
  234. if (newSocket != INVALID_SOCKET)
  235. {
  236. sockHandle.Attach( newSocket );
  237. sockHandle.GetPeerName( sockAddr );
  238. GetAddress( sockAddr, strAddr );
  239. sockHandle.Close();
  240. //AppendText( _T("Connection abandoned: %s\r\n"), strAddr );
  241. //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned:%s",strAddr));
  242. //OutputDebugString(_T("\n客户端连接中断:"));
  243. //OutputDebugString(strAddr);
  244. //OutputDebugString(_T("\n\n"));
  245. }
  246. else
  247. {
  248. //OutputDebugString(_T("\n客户端连接中断,不是一个有效的套接字:"));
  249. //OutputDebugString(strAddr);
  250. //OutputDebugString(_T("\n\n"));
  251. //AppendText( _T("Connection abandoned. Not a valid socket.\r\n"), strAddr );
  252. //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned. Not a valid socket:%s",strAddr));
  253. }
  254. }
  255. void IServerImpl::OnAddConnection(CSocketHandle* pSH, SOCKET newSocket)
  256. {
  257. ASSERT( pSH == m_SocketServer );
  258. (pSH);
  259. CString strAddr;
  260. CSocketHandle sockHandle;
  261. SockAddrIn sockAddr;
  262. sockHandle.Attach( newSocket );
  263. sockHandle.GetPeerName( sockAddr );
  264. GetAddress( sockAddr, strAddr );
  265. sockHandle.Detach();
  266. //OutputDebugString(_T("\n新的连接接入:"));
  267. //OutputDebugString(strAddr);
  268. //OutputDebugString(_T("\n"));
  269. //LOG4C_NO_FILENUM((LOG_NOTICE,"新的连接接入:%s",strAddr));
  270. //AppendText( _T("Connection established: %s\r\n"), strAddr );
  271. }
  272. void IServerImpl::OnDataReceived(CSocketHandle* pSH, const SOCKET sClient, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr, BYTE **pendingbuf, unsigned int& npendingSize, unsigned int& ncursize)
  273. {
  274. ASSERT( pSH == m_SocketServer );
  275. (pSH);
  276. CString strAddr, strText;
  277. //USES_CONVERSION;
  278. //LPTSTR pszText = strText.GetBuffer(dwCount+1);
  279. //::StringCchCopyN(pszText, dwCount+1, A2CT(reinterpret_cast<LPCSTR>(pbData)), dwCount);
  280. //strText.ReleaseBuffer();
  281. GetAddress( addr, strAddr );
  282. //AppendText( _T("%s>(%s)\r\n"), strAddr, strText);
  283. const SocketContextList& sl = m_SocketServer.GetClientSocketList();
  284. CClientProcess::GetInstance()->ClientProcess(sClient, pbData, dwCount, strAddr, pendingbuf, npendingSize, ncursize);
  285. }
  286. void IServerImpl::OnConnectionDropped(CSocketHandle* pSH)
  287. {
  288. ASSERT( pSH == m_SocketServer );
  289. (pSH);
  290. CString strAddr;
  291. CSocketHandle sockHandle;
  292. SockAddrIn sockAddr;
  293. //sockHandle.Attach( pSH->GetSocket() );
  294. sockHandle.GetPeerName( sockAddr );
  295. GetAddress( sockAddr, strAddr );
  296. //sockHandle.Detach();
  297. //AppendText( _T("Connection lost with client.\r\n") );
  298. //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection lost with client"));
  299. }
  300. void IServerImpl::OnConnectionError(CSocketHandle* pSH, DWORD dwError)
  301. {
  302. ASSERT( pSH == m_SocketServer );
  303. (pSH);
  304. _com_error err(dwError);
  305. //AppendText( _T("Communication Error:\r\n%s\r\n"), err.ErrorMessage() );
  306. CString strAddr;
  307. CSocketHandle sockHandle;
  308. SockAddrIn sockAddr;
  309. sockHandle.GetPeerName( sockAddr );
  310. GetAddress( sockAddr, strAddr );
  311. //LOG4C((LOG_NOTICE,"IP:%s Communication Error:%s", strAddr, err.ErrorMessage()));
  312. }
  313. #if defined(SOCKHANDLE_USE_OVERLAPPED)
  314. void IServerImpl::OnRemoveConnection(CSocketHandle* pSH, SOCKET dropSocket)
  315. {
  316. return;
  317. ASSERT( pSH == m_SocketServer );
  318. (pSH);
  319. CString strAddr;
  320. CSocketHandle sockHandle;
  321. SockAddrIn sockAddr;
  322. sockHandle.Attach( dropSocket );
  323. sockHandle.GetPeerName( sockAddr );
  324. GetAddress( sockAddr, strAddr );
  325. sockHandle.Detach();
  326. //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned. Not a valid socket:%s",strAddr));
  327. }
  328. #endif
  329. DWORD IServerImpl::GetClientConnectCount()
  330. {
  331. //DWORD dwClientSize = 0;
  332. //m_SocketServer->GetConnectionCount();
  333. return m_SocketServer.GetConnectionCount();
  334. }
  335. void IServerImpl::StartClearInvalidateSocketThread()
  336. {
  337. m_hRunObject = CreateEvent( NULL, TRUE, FALSE, _T("ClearInvalidateSocketThread") );
  338. if ( m_hRunObject == NULL )
  339. {
  340. // LOG4C((LOG_NOTICE,"创建事件失败"));
  341. }
  342. m_hClearInvalidateSocketThread = CreateThread(NULL,0,ClearInvalidateSocketThread,this,0,NULL);
  343. if ( m_hClearInvalidateSocketThread == NULL )
  344. {
  345. // LOG4C((LOG_NOTICE,"创建线程失败"));
  346. }
  347. }
  348. DWORD WINAPI IServerImpl::ClearInvalidateSocketThread(void *pInstance)
  349. {
  350. //LOG4C((LOG_NOTICE,"服务端心跳检测线程"));
  351. IServerImpl *pServerImpl = (IServerImpl*)pInstance;
  352. #ifdef SOCKHANDLE_USE_OVERLAPPED
  353. /*const*/ SocketContextList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
  354. SocketContextList::iterator citer = sl.begin();
  355. #else
  356. /*const*/ SocketList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
  357. SocketList::const_iterator citer = sl.begin();
  358. #endif
  359. //SockAddrIn sockAddr;
  360. //size_t nSize = sl.size();
  361. DWORD dwError;
  362. //CSocketHandle tSocketHandle;
  363. do
  364. {
  365. //nSize = sl.size();
  366. if ( !pServerImpl->m_bStopbeat )
  367. {
  368. //AutoThreadSection aSenction(pServerImpl->m_SocketServer.ReturnSection());
  369. //if( (nSize != 0) && (citer != sl.end()))
  370. if ( citer != sl.end())
  371. {
  372. //SocketIOBuffer *buf = citer;
  373. DWORD dwTick = GetTickCount();
  374. //if ( ( dwTick - citer->dwTime) > 5000 )
  375. //{
  376. SOCKET sokt = static_cast<SOCKET>(*citer++);
  377. WORD wMessageId = MSG_LOGIN_RESP;
  378. LOGIN_RESULT_STRU tLoginResult = {0};
  379. tLoginResult.tCommonMsg.dwConnectionID = 0;
  380. tLoginResult.tCommonMsg.wMessageId = wMessageId;
  381. tLoginResult.byResult = LOGIN_RESULT_SUC;
  382. tLoginResult.dwUserID = 0;
  383. tLoginResult.byStatus = USER_STATUS_ONLINE ;
  384. DWORD dwDataLen = sizeof(LOGIN_RESULT_STRU);
  385. TMessageHeader tHeader = {0};
  386. tHeader.wMessageId = wMessageId;
  387. tHeader.dwDataLen = dwDataLen;
  388. CSocketHandle hClient;
  389. hClient.Attach(sokt);
  390. INT nRet = CClientProcess::net_Send(&hClient, &tHeader, (void *)&tLoginResult, dwDataLen);
  391. hClient.Detach();
  392. if ( nRet <= 0 )
  393. {
  394. pServerImpl->m_SocketServer.RemoveConnection(sokt);
  395. pServerImpl->m_SocketServer.CloseConnection(sokt);
  396. }
  397. //}
  398. //else
  399. //{
  400. // citer++;
  401. //}
  402. //tSocketHandle.Attach( (*citer) );
  403. #if 0
  404. //tSocketHandle.Write(LPBYTE("0"), 1, NULL, 30000); // 心跳包超时值:30秒到1分钟为好!
  405. dwError = WSAGetLastError();
  406. switch( dwError )
  407. {
  408. case WSAENOTSOCK:
  409. case WSAENETDOWN:
  410. case WSAENETUNREACH:
  411. case WSAENETRESET:
  412. case WSAECONNABORTED:
  413. case WSAECONNRESET:
  414. case WSAESHUTDOWN:
  415. case WSAEHOSTDOWN:
  416. case WSAEHOSTUNREACH:
  417. //citer = sl.erase(citer);
  418. LOG4C_NO_FILENUM((LOG_NOTICE,"删除过期客户端连接"));
  419. //pServerImpl->m_SocketServer.CloseConnection(*citer);
  420. //pServerImpl->m_SocketServer.RemoveConnection(*citer);
  421. citer = sl.begin();
  422. default:
  423. //TRACE("--------------%d\r\n",dwError);
  424. if( citer != sl.end() )
  425. citer++;
  426. break;
  427. }
  428. #endif
  429. //tSocketHandle.Detach();
  430. }
  431. else if ( citer == sl.end() )
  432. {
  433. citer = sl.begin();
  434. }
  435. }
  436. } while (WaitForSingleObject(pServerImpl->m_hRunObject,5000L) == WAIT_TIMEOUT);
  437. return 0;
  438. }
  439. };