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

模拟服务器

开发平台:

C/C++

  1. // ClientSocket.cpp: implementation of the CClientSocket class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "S3DBClient.h"
  6. #include "S3PDBSocketParser.h"
  7. #include "ClientSocket.h"
  8. #include "objbase.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CClientSocket* CClientSocket::m_pInstance = NULL;
  18. CClientSocket::CClientSocket():
  19. //m_s( INVALID_SOCKET ),
  20. m_hServer( NULL ),
  21. m_pS( NULL )
  22. {
  23. memset( &m_serverAddr, 0, sizeof( struct sockaddr_in ) );
  24. }
  25. CClientSocket::~CClientSocket()
  26. {
  27. }
  28. CClientSocket* CClientSocket::Instance( short* psiPort/* = NULL */ )
  29. {
  30. if ( NULL == m_pInstance )
  31. {
  32. m_pInstance = new CClientSocket;
  33. }
  34. if ( NULL != m_pInstance )
  35. {
  36. if ( ( !( m_pInstance->HasValidSocket() ) )
  37. && ( NULL != psiPort ) )
  38. {
  39. if ( m_pInstance->InitWinSocket() )
  40. {
  41. m_pInstance->CreateSocket( *psiPort );
  42. }
  43. }
  44. }
  45. return m_pInstance;
  46. }
  47. CClientSocket* CClientSocket::GetInstance()
  48. {
  49. return m_pInstance;
  50. }
  51. void CClientSocket::ReleaseInstance()
  52. {
  53. if ( NULL != m_pInstance )
  54. {
  55. m_pInstance->ReleaseSocket();
  56. m_pInstance->UninitWinSocket();
  57. delete m_pInstance;
  58. m_pInstance = NULL;
  59. }
  60. }
  61. BOOL CClientSocket::HasValidSocket()
  62. {
  63. BOOL bRet = FALSE;
  64. if ( NULL != m_pS )
  65. {
  66. bRet = TRUE;
  67. }
  68. /*
  69. if ( INVALID_SOCKET != m_s )
  70. {
  71. bRet = TRUE;
  72. }
  73. */
  74. return bRet;
  75. }
  76. BOOL CClientSocket::CreateSocket(short siPort)
  77. {
  78. BOOL bRet = FALSE;
  79. try
  80. {
  81. m_pS = new CGameClient( 10, 1024 );
  82. if ( NULL != m_pS )
  83. {
  84. bRet = TRUE;
  85. }
  86. }
  87. catch ( ... )
  88. {
  89. bRet = FALSE;
  90. }
  91. /*
  92. m_s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
  93. if ( INVALID_SOCKET == m_s )
  94. {
  95. bRet = FALSE;
  96. }
  97. else
  98. {
  99. struct sockaddr_in local;
  100. local.sin_family = AF_INET;
  101. local.sin_port = htons( siPort );
  102. local.sin_addr.s_addr = INADDR_ANY;
  103. if ( SOCKET_ERROR ==
  104. bind( m_s, ( SOCKADDR* )&local, sizeof( local ) ) )
  105. {
  106. closesocket( m_s ); // Asserts that m_s can be close rightly. 
  107. m_s = INVALID_SOCKET;
  108. bRet = FALSE;
  109. }
  110. }
  111. */
  112. return bRet;
  113. }
  114. BOOL CClientSocket::ReleaseSocket()
  115. {
  116. BOOL bRet = TRUE;
  117. if ( NULL != m_pS )
  118. {
  119. try
  120. {
  121. m_pS->StopConnections();
  122. }
  123. catch ( ... )
  124. {
  125. bRet = FALSE;
  126. }
  127. }
  128. /*
  129. if ( 0 == closesocket( m_s ) )
  130. {
  131. bRet = TRUE;
  132. }
  133. */
  134. return bRet;
  135. }
  136. BOOL CClientSocket::InitWinSocket()
  137. {
  138. BOOL bRet = TRUE;
  139. WSADATA wsd;
  140. if ( 0 != WSAStartup( MAKEWORD(1,1), &wsd ) )
  141. {
  142. bRet = FALSE;
  143. }
  144. return bRet;
  145. }
  146. BOOL CClientSocket::UninitWinSocket()
  147. {
  148. BOOL bRet = TRUE;
  149. if ( 0 != WSACleanup() )
  150. {
  151. bRet = FALSE;
  152. }
  153. return bRet;
  154. }
  155. BOOL CClientSocket::Start()
  156. {
  157. BOOL bRet = FALSE;
  158. if ( NULL != m_pS )
  159. {
  160. try
  161. {
  162. m_pS->Start();
  163. bRet = TRUE;
  164. }
  165. catch ( ... )
  166. {
  167. bRet = FALSE;
  168. }
  169. }
  170. /*
  171. if ( ( HasValidSocket() )
  172. && ( NULL == m_hServer ) )
  173. {
  174. m_serverParam.s = m_s;
  175. m_serverParam.pS = m_pS;
  176. DWORD dwThreadId;
  177. m_hServer =
  178. CreateThread( 0, 0, CClientSocket::RunServer, &m_serverParam, 0, &dwThreadId );
  179. bRet = TRUE;
  180. }*/
  181. return bRet;
  182. }
  183. BOOL CClientSocket::Stop()
  184. {
  185. BOOL bRet = TRUE;
  186. if ( TRUE == TerminateThread( m_hServer, 0 ) )
  187. {
  188. bRet = CloseHandle( m_hServer );
  189. if ( TRUE == bRet )
  190. {
  191. m_hServer = NULL;
  192. }
  193. }
  194. return bRet;
  195. }
  196. BOOL CClientSocket::RemoteQuery( _PDBLOGINSTRUCT pParam,
  197. CClientSocket::LOGINCALLBACK LoginCallbackFun,
  198. DWORD dwCustomParam,
  199. DWORD dwMilliseconds )
  200. {
  201. BOOL bRet = FALSE;
  202. if ( NULL != pParam )
  203. {
  204. IBYTE iTag = 0;
  205. unsigned long ulSendSize =
  206. pParam->Size + sizeof( iTag ) + sizeof( GUID );
  207. IBYTE* pSendBuf = new IBYTE[ulSendSize];
  208. if ( NULL != pSendBuf )
  209. {
  210. GUID msgId = GUID_NULL;
  211. ::CoCreateGuid( &msgId );
  212. if ( GUID_NULL != msgId )
  213. {
  214. pSendBuf[0] = iTag;
  215. memcpy( &( pSendBuf[1] ), pParam, pParam->Size/*sizeof( _DBLOGINSTRUCT )*/ );
  216. memcpy( &( pSendBuf[1+pParam->Size] ), &msgId, sizeof( GUID ) );
  217. DWORD dwSize = pParam->Size + sizeof( GUID );
  218. memcpy( &( pSendBuf[1] ), &dwSize, sizeof( pParam->Size ) );
  219. unsigned long ulEncodedSize;
  220. if ( TRUE == S3PDBSocketParser::Encode( pSendBuf, ulSendSize,
  221. NULL, ulEncodedSize ) )
  222. {
  223. IBYTE* pEncodedBuf = new IBYTE[ulEncodedSize];
  224. if ( NULL != pEncodedBuf )
  225. {
  226. S3PDBSocketParser::Encode( pSendBuf, ulSendSize,
  227. pEncodedBuf, ulEncodedSize );
  228. try
  229. {
  230. m_pS->Write( pEncodedBuf, ulEncodedSize ); //douhao 调用刘鹏的socket发送
  231. DWORD dwResult =
  232. WaitForSingleObject( m_pS->m_hHasRecvdata, dwMilliseconds );
  233. if ( WAIT_OBJECT_0 == dwResult )
  234. {
  235. ResetEvent( m_pS->m_hHasRecvdata );
  236. S3PDBSocketParser parser;
  237. if ( TRUE == parser.Parse( ( char* )( m_pS->m_pRecvBuf ),
  238. m_pS->m_dwRecvSize ) )
  239. {
  240. GUID revMsgId;
  241. memcpy( &revMsgId,
  242. &( parser.m_lpData[def_DBUSERNAME_MAX_LEN+def_DBPASSWORD_MAX_LEN] ),
  243. sizeof( GUID ) );
  244. if ( revMsgId == msgId )
  245. {
  246. if ( NULL != LoginCallbackFun )
  247. {
  248. LoginCallbackFun( ( DWORD )( m_pS->m_pRecvBuf ),
  249. dwCustomParam );
  250. }
  251. bRet = TRUE;
  252. }
  253. }
  254. }
  255. }
  256. catch ( ... )
  257. {
  258. bRet = FALSE;
  259. }
  260. delete []pEncodedBuf;
  261. pEncodedBuf = NULL;
  262. }
  263. }
  264. delete []pSendBuf;
  265. pSendBuf = NULL;
  266. }
  267. }
  268. }
  269. return bRet;
  270. }
  271. BOOL CClientSocket::SetServerAddr( LPCTSTR lpszIPAddr, short siPort )
  272. {
  273. BOOL bRet = FALSE;
  274. if ( NULL != lpszIPAddr )
  275. {
  276. DWORD dwServerAddr = inet_addr( lpszIPAddr );
  277. if ( INADDR_NONE != dwServerAddr )
  278. {
  279. bRet = SetServerAddr( dwServerAddr, siPort );
  280. }
  281. }
  282. return bRet;
  283. }
  284. BOOL CClientSocket::SetServerAddr( DWORD dwIPAddr, short siPort )
  285. {
  286. BOOL bRet = TRUE;
  287. m_serverAddr.sin_family = AF_INET;
  288. m_serverAddr.sin_port = htons( siPort );
  289. m_serverAddr.sin_addr.s_addr = dwIPAddr;
  290. return bRet;
  291. }
  292. static DWORD WINAPI gRecvfrom( LPVOID lParam )
  293. {
  294. DWORD dwRet = 0;
  295. if ( NULL != lParam )
  296. {
  297. CClientSocket::_PRECVPARAM pParam =
  298. ( CClientSocket::_PRECVPARAM )lParam;
  299. pParam->iResult = recvfrom( pParam->s, pParam->pRecvBuf, pParam->iRecvBufSize,
  300. 0, ( struct sockaddr* )( &pParam->from ), &( pParam->fromlen ) );
  301. }
  302. return dwRet;
  303. }
  304. //-------------------------------------------------------------------------
  305. // Recvfrom:
  306. // Return 0 : successful
  307. //        1 : time out
  308. //        2 : general error
  309. //        3 : socket has been closed gracefully
  310. //        4 : socket error
  311. //-------------------------------------------------------------------------
  312. DWORD CClientSocket::Recvfrom( char FAR* buf, int len, DWORD dwMilliseconds )
  313. {
  314. DWORD dwRet = 0;
  315. DWORD dwThreadID;
  316. m_recvParam.from = m_serverAddr;
  317. m_recvParam.fromlen = sizeof( m_recvParam.from );
  318. m_recvParam.pRecvBuf = buf;
  319. m_recvParam.iRecvBufSize = len;
  320. m_recvParam.s = m_s; // Not used
  321. m_recvParam.pS = m_pS;
  322. HANDLE hThread = CreateThread( 0, 0, gRecvfrom, &m_recvParam, 0, &dwThreadID );
  323. if ( NULL != hThread )
  324. {
  325. DWORD dwResult = WaitForSingleObject( hThread, dwMilliseconds );
  326. if ( WAIT_OBJECT_0 == dwResult )
  327. {
  328. if (  0 == m_recvParam.iResult )
  329. {
  330. dwRet = 3; // socket has been closed gracefully
  331. }
  332. else if ( SOCKET_ERROR == m_recvParam.iResult )
  333. {
  334. dwRet = 4; // socket error
  335. }
  336. else
  337. {
  338. dwRet = 0; // successful
  339. }
  340. }
  341. else if ( WAIT_TIMEOUT == dwResult )
  342. {
  343. dwRet = 1; // time out
  344. }
  345. else// if ( WAIT_ABANDONED == dwResult )
  346. {
  347. dwRet = 2; // wrong
  348. }
  349. CloseHandle( hThread );
  350. }
  351. return dwRet;
  352. }
  353. BOOL CClientSocket::IncludeSomeBitValue( DWORD dwMatrix, DWORD dwSomeBitValue )
  354. {
  355. BOOL bRet = FALSE;
  356. if ( ( dwMatrix & dwSomeBitValue ) == dwSomeBitValue )
  357. {
  358. bRet = TRUE;
  359. }
  360. return bRet;
  361. }
  362. BOOL CClientSocket::Connect( LPCTSTR lpszAddr, short siPort )
  363. {
  364. BOOL bRet = FALSE;
  365. if ( NULL != m_pS )
  366. {
  367. try
  368. {
  369. m_pS->ConnectTo( lpszAddr, siPort );
  370. m_pS->StartConnections();
  371. bRet = TRUE;
  372. }
  373. catch ( ... )
  374. {
  375. bRet = FALSE;
  376. }
  377. }
  378. return bRet;
  379. }