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

模拟服务器

开发平台:

C/C++

  1. // NetClient.cpp: implementation of the CNetClient class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Global.h"
  6. #include "NetClient.h"
  7. #include "NetCenter.h"
  8. #include "S3Relay.h"
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. CNetClientDup::CNetClientDup(const CNetClient& netclient)
  13. : m_pClient(netclient.GetClient()), m_SvrIP(netclient.GetSvrIP())
  14. {
  15. _SafeAddRef(m_pClient);
  16. }
  17. BOOL CNetClientDup::SendPackage(const void* pData, size_t size) const
  18. {
  19. dTRACKSENDDATA(pData, size);
  20. if(!m_pClient)
  21. return FALSE;
  22. m_pClient->SendPackToServer(pData, size);
  23. return TRUE;
  24. }
  25. CNetClientDup& CNetClientDup::operator =(const CNetClient& src)
  26. {
  27. _SafeRelease(m_pClient);
  28. m_pClient = src.GetClient();
  29. _SafeAddRef(m_pClient);
  30. m_SvrIP = src.GetSvrIP();
  31. return *this;
  32. }
  33. CNetClient::CNetClient(CNetCenter* pNetCenter, BOOL bAutoFree)
  34. : m_pClient(NULL), m_ready(FALSE), m_pNetCenter(pNetCenter), m_bAutoFree(bAutoFree),
  35. m_SvrIP(0), m_SvrPort(0), m_hOver(NULL), m_bReqDisconn(FALSE), m_shutdown(0L)
  36. {
  37. assert(m_pNetCenter);
  38. }
  39. CNetClient::~CNetClient()
  40. {
  41. //assert(m_pClient);
  42. //_SafeRelease(m_pClient);
  43. }
  44. void CNetClient::DirectClearup()
  45. {
  46. if (m_hStop)
  47. {
  48. ::CloseHandle(m_hStop);
  49. m_hStop = NULL;
  50. }
  51. if (!m_bBlockSD)
  52. {
  53. if (m_hProcessor)
  54. {
  55. m_hProcessor = NULL;
  56. ::CloseHandle(m_hProcessor);
  57. }
  58. }
  59. if (m_pClient)
  60. {
  61. try
  62. {
  63. if (m_bReqDisconn)
  64. {
  65. m_pClient->Shutdown();
  66. m_pClient->Cleanup();
  67. }
  68. m_pClient->Release();
  69. }
  70. catch (...)
  71. {
  72. //assert(FALSE);
  73. }
  74. m_pClient = NULL;
  75. }
  76. if (m_hOver)
  77. {
  78. ::CloseHandle(m_hOver);
  79. m_hOver = NULL;
  80. }
  81. m_SvrAddr.resize(0);
  82. m_SvrIP = 0;
  83. m_SvrPort = 0;
  84. m_bReqDisconn = FALSE;
  85. m_bBlockSD = FALSE;
  86. }
  87. void CNetClient::InterShutdown()
  88. {
  89. m_ready = FALSE;
  90. assert(m_pClient);
  91. m_bBlockSD = FALSE;
  92. m_bReqDisconn = TRUE;
  93. #ifdef _WORKMODE_SINGLETHREAD
  94. DirectClearup();
  95. TryFreeThis();
  96. #else
  97. assert(m_hStop);
  98. ::SetEvent(m_hStop); //clearup at thread terminate
  99. #endif
  100. }
  101. DWORD CNetClient::Main(LPVOID lpParam)
  102. {
  103. HRESULT hr = m_pClient->ConnectTo(m_SvrAddr.c_str(), m_SvrPort);
  104. if (FAILED(hr))
  105. {
  106. m_pClient->Shutdown();
  107. m_pClient->Cleanup();
  108. m_pClient->Release();
  109. m_pClient = NULL;
  110. OnStartupFail();
  111. if (m_hOver)
  112. ::SetEvent(m_hOver); //the Startup() do Clearup
  113. else
  114. {
  115. DirectClearup();
  116. TryFreeThis();
  117. }
  118. return -1;
  119. }
  120. //SetEvent(m_hOver); //unblock in OnCreate
  121. #ifdef _WORKMODE_SINGLETHREAD
  122. return 0;
  123. #endif
  124. #ifndef _WORKMODE_SINGLETHREAD
  125. EnterLoop();
  126. #endif
  127. while (!IsAskingStop())
  128. {
  129. assert(m_pClient);
  130. DoRoute();
  131. ::Sleep(breathe_interval);
  132. }
  133. #ifndef _WORKMODE_SINGLETHREAD
  134. LeaveLoop();
  135. #endif
  136. //final clearup
  137. DirectClearup();
  138. if (!m_bBlockSD)
  139. TryFreeThis();
  140. return 0;
  141. }
  142. //static
  143. void __stdcall CNetClient::ClientEventNotify (
  144. LPVOID lpParam,
  145. const unsigned long &ulnEventType)
  146. {
  147. CNetClient* pThis = (CNetClient*)lpParam;
  148. assert(pThis);
  149. switch(ulnEventType)
  150. {
  151. case enumServerConnectCreate:
  152. pThis->_NotifyServerEventCreate();
  153. break;
  154. case enumServerConnectClose:
  155. pThis->_NotifyServerEventClose();
  156. break;
  157. }
  158. }
  159. BOOL CNetClient::Startup(size_t maxFreeBuffers, size_t bufferSize, const char * pAddressToConnectServer, unsigned short usPortToConnectServer, BOOL block/* = TRUE*/)
  160. {
  161. if (m_pClient) //already startup !!!
  162. return FALSE;
  163. BOOL started = FALSE;
  164. assert(!m_ready);
  165. m_ready = FALSE;
  166. m_shutdown = 0L;
  167. IClientFactory* pClientFactory = NULL;
  168. if (FAILED(g_libRainbow.CreateInterface(IID_IClientFactory, reinterpret_cast< void ** >(&pClientFactory))))
  169. goto on_fail;
  170. pClientFactory->SetEnvironment(bufferSize);
  171. pClientFactory->CreateClientInterface(IID_IESClient, reinterpret_cast< void ** >(&m_pClient));
  172. pClientFactory->Release();
  173. if (FAILED(m_pClient->Startup()))
  174. goto on_fail;
  175. m_pClient->RegisterMsgFilter((LPVOID)this, ClientEventNotify);
  176. m_SvrAddr = pAddressToConnectServer;
  177. m_SvrIP = _a2ip(pAddressToConnectServer);
  178. m_SvrPort = usPortToConnectServer;
  179. m_bBlockSD = FALSE;
  180. m_bReqDisconn = FALSE;
  181. #ifdef _WORKMODE_SINGLETHREAD
  182. if (block)
  183. {
  184. HRESULT hr = m_pClient->ConnectTo(m_SvrAddr.c_str(), m_SvrPort);
  185. if (FAILED(hr))
  186. {
  187. //m_pClient->Shutdown();
  188. m_pClient->Cleanup();
  189. m_pClient->Release();
  190. m_pClient = NULL;
  191. OnStartupFail();
  192. goto on_fail;
  193. }
  194. }
  195. else
  196. {
  197. if (!Start())
  198. goto on_fail;
  199. started = TRUE;
  200. ::WaitForSingleObject(m_hProcessor, INFINITE);
  201. if (!m_pClient)
  202. goto on_fail;
  203. }
  204. #else
  205. assert(!m_hOver);
  206. if (block)
  207. {
  208. m_hOver = ::CreateEvent(NULL, TRUE, FALSE, NULL);
  209. if (!m_hOver)
  210. goto on_fail;
  211. }
  212. if (!Start())
  213. goto on_fail;
  214. started = TRUE;
  215. if (block)
  216. {
  217. ::WaitForSingleObject(m_hOver, INFINITE);
  218. if (m_pClient == NULL)
  219. {
  220. ::WaitForSingleObject(m_hProcessor, INFINITE);
  221. goto on_fail;
  222. }
  223. }
  224. #endif
  225. return TRUE;
  226. on_fail:
  227. try
  228. {
  229. if (started)
  230. Stop();
  231. DirectClearup();
  232. TryFreeThis();
  233. }
  234. catch (...)
  235. {
  236. assert(FALSE);
  237. }
  238. return FALSE;
  239. }
  240. BOOL CNetClient::Shutdown()
  241. {
  242. m_ready = FALSE;
  243. if (m_pClient)
  244. {
  245. #ifdef _WORKMODE_SINGLETHREAD
  246. m_bBlockSD = TRUE;
  247. m_bReqDisconn = TRUE;
  248. DirectClearup();
  249. #else
  250. m_bBlockSD = TRUE;
  251. m_bReqDisconn = TRUE;
  252. Stop(); //clearup at thread terminate
  253. #endif
  254. TryFreeThis();
  255. }
  256. return TRUE;
  257. }
  258. void CNetClient::_NotifyServerEventCreate()
  259. {
  260. m_ready = TRUE;
  261. m_pNetCenter->_NotifyServerEventCreate(this);
  262. OnServerEventCreate();
  263. //free block
  264. if (m_hOver)
  265. ::SetEvent(m_hOver);
  266. }
  267. void CNetClient::_NotifyServerEventClose()
  268. {
  269. if (m_shutdown)
  270. return;
  271. ++ m_shutdown;
  272. m_ready = FALSE;
  273. OnServerEventClose();
  274. m_pNetCenter->_NotifyServerEventClose(this);
  275. //clearup at thread terminate if necessary
  276. if (!m_bReqDisconn)
  277. {
  278. #ifdef _WORKMODE_SINGLETHREAD
  279. gConsignClientSD(m_pClient);
  280. m_pClient->Release();
  281. m_pClient = NULL;
  282. DirectClearup();
  283. TryFreeThis();
  284. #else
  285. InterShutdown();
  286. #endif
  287. }
  288. -- m_shutdown;
  289. }
  290. BOOL CNetClient::SendPackage(const void* pData, size_t size)
  291. {
  292. if (!m_ready || m_pClient == NULL)
  293. return FALSE;
  294. dTRACKSENDDATA(pData, size);
  295. m_pClient->SendPackToServer(pData, size);
  296. return TRUE;
  297. }
  298. BOOL CNetClient::DoRoute()
  299. {
  300. if (!m_ready || m_pClient == NULL)
  301. return FALSE;
  302. BeginRoute();
  303. for ( ; ; )
  304. {
  305. size_t size = 0;
  306. const void* pData = m_pClient->GetPackFromServer(size);
  307. if (!pData || size <= 0)
  308. break;
  309. dTRACKRECVDATA(pData, size);
  310. RecvPackage(pData, size);
  311. }
  312. EndRoute();
  313. return TRUE;
  314. }
  315. BOOL CNetClient::Route()
  316. {
  317. return DoRoute();
  318. }