升龙物业 老版本 ocx IPO, 加密狗 转值班电话

ClientContainer.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. #include "StdAfx.h"
  2. #include "ClientContainer.h"
  3. #include "NetClient.h"
  4. CClientContainer::CClientContainer(void)
  5. {
  6. }
  7. CClientContainer::~CClientContainer(void)
  8. {
  9. release();
  10. }
  11. /*****************************************************************
  12. **【函数名称】 __add2List
  13. **【函数功能】 客户端添加到指定队列中
  14. **【参数】
  15. **【返回值】
  16. ****************************************************************/
  17. void CClientContainer::__add2List( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
  18. {
  19. CSingleLock Lock(a_pCs);
  20. Lock.Lock();
  21. a_list.AddTail(a_pClient);
  22. }
  23. /*****************************************************************
  24. **【函数名称】 __onConnFailedProc
  25. **【函数功能】 客户端连接断开/失败的后续处理
  26. **【参数】 a_pClient: 连接断开/失败的客户端
  27. **【返回值】
  28. ****************************************************************/
  29. void CClientContainer::__onConnFailedProc( CNetClient* a_pClient )
  30. {
  31. // 连接类型处理不同
  32. if(a_pClient->linkType() == PDU_LINK_TYPE_CLIENT)
  33. {
  34. __add2List(a_pClient, m_listConnecting, &m_CS4Connecting);
  35. }
  36. else
  37. {
  38. __deleteClient(a_pClient);
  39. } // end if
  40. }
  41. /*****************************************************************
  42. **【函数名称】 __deleteClient
  43. **【函数功能】 删除指定的连接
  44. **【参数】
  45. **【返回值】
  46. ****************************************************************/
  47. void CClientContainer::__deleteClient( CNetClient* a_pClient )
  48. {
  49. ASSERT(a_pClient != NULL);
  50. a_pClient->drop();
  51. __add2List(a_pClient, m_ListDeleted, &m_Cs4Deleted);
  52. }
  53. /*****************************************************************
  54. **【函数名称】 __removeClient
  55. **【函数功能】 从LIST中移出指定的连接(不是删除)
  56. **【参数】
  57. **【返回值】
  58. ****************************************************************/
  59. bool CClientContainer::__removeClient( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
  60. {
  61. ASSERT(a_pClient != NULL);
  62. CSingleLock Locker(a_pCs);
  63. Locker.Lock();
  64. POSITION Pos = a_list.Find(a_pClient);
  65. if(Pos != NULL)
  66. {
  67. a_list.RemoveAt(Pos);
  68. return true;
  69. }
  70. else
  71. return false;
  72. }
  73. /*****************************************************************
  74. **【函数名称】 __lookup
  75. **【函数功能】 从LIST中查找指定的连接
  76. **【参数】 a_nFarType 对端设备类型
  77. a_nFarId 对端设备ID
  78. **【返回值】
  79. ****************************************************************/
  80. CNetClient* CClientContainer::__lookup( PDU_DEV_TYPE a_nFarType, int a_nFarId, ListClient& a_list, CCriticalSection* a_pCs )
  81. {
  82. CSingleLock Locker(a_pCs);
  83. Locker.Lock();
  84. POSITION pos = a_list.GetHeadPosition();
  85. PDU_DEV_TYPE nType = PDU_DEV_TYPE_UNKNOWN;
  86. int nId = -1;
  87. while(pos != NULL)
  88. {
  89. CNetClient* pClient = a_list.GetNext(pos);
  90. ASSERT(pClient != NULL);
  91. pClient->getFarDevInfo(nType, nId);
  92. if(nType == a_nFarType && nId == a_nFarId)
  93. return pClient;
  94. } // end while
  95. return NULL;
  96. }
  97. /*****************************************************************
  98. **【函数名称】 __lookup
  99. **【函数功能】 从LIST中查找指定的连接
  100. **【参数】 a_hSocket SOCKET句柄
  101. **【返回值】
  102. ****************************************************************/
  103. CNetClient* CClientContainer::__lookup( SOCKET a_hSocket, ListClient& a_list, CCriticalSection* a_pCs )
  104. {
  105. CSingleLock Locker(a_pCs);
  106. Locker.Lock();
  107. POSITION pos = a_list.GetHeadPosition();
  108. while(pos != NULL)
  109. {
  110. CNetClient* pClient = a_list.GetNext(pos);
  111. ASSERT(pClient != NULL);
  112. if(pClient->assoSocket() == a_hSocket)
  113. return pClient;
  114. } // end while
  115. return NULL;
  116. }
  117. /*****************************************************************
  118. **【函数名称】 __lookup
  119. **【函数功能】 从LIST中查找指定的连接
  120. **【参数】
  121. **【返回值】
  122. ****************************************************************/
  123. CNetClient* CClientContainer::__lookup( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
  124. {
  125. CSingleLock Locker(a_pCs);
  126. Locker.Lock();
  127. POSITION Pos = a_list.Find(a_pClient);
  128. if(Pos != NULL)
  129. return a_pClient;
  130. else
  131. return NULL;
  132. }
  133. /*****************************************************************
  134. **【函数名称】 __lookup4Delete
  135. **【函数功能】 从LIST中查找指定的连接并删除
  136. **【参数】
  137. **【返回值】
  138. ****************************************************************/
  139. bool CClientContainer::__lookup4Delete( PDU_DEV_TYPE a_nFarType, int a_nFarId, ListClient& a_list, CCriticalSection* a_pCs )
  140. {
  141. CSingleLock Locker(a_pCs);
  142. Locker.Lock();
  143. PDU_DEV_TYPE nType = PDU_DEV_TYPE_UNKNOWN;
  144. int nId = -1;
  145. POSITION pos = a_list.GetHeadPosition();
  146. while(pos != NULL)
  147. {
  148. POSITION posPrev = pos;
  149. CNetClient* pClient = a_list.GetNext(pos);
  150. ASSERT(pClient != NULL);
  151. pClient->getFarDevInfo(nType, nId);
  152. if(nType == a_nFarType && nId == a_nFarId)
  153. {
  154. a_list.RemoveAt(posPrev);
  155. // 删除
  156. __deleteClient(pClient);
  157. return true;
  158. }
  159. } // end while
  160. return false;
  161. }
  162. /*****************************************************************
  163. **【函数名称】 __lookup4Delete
  164. **【函数功能】 从LIST中查找指定的连接并删除
  165. **【参数】
  166. **【返回值】
  167. ****************************************************************/
  168. bool CClientContainer::__lookup4Delete( SOCKET a_hSocket, ListClient& a_list, CCriticalSection* a_pCs )
  169. {
  170. CSingleLock Locker(a_pCs);
  171. Locker.Lock();
  172. POSITION pos = a_list.GetHeadPosition();
  173. while(pos != NULL)
  174. {
  175. POSITION posPrev = pos;
  176. CNetClient* pClient = a_list.GetNext(pos);
  177. ASSERT(pClient != NULL);
  178. if(pClient->assoSocket() == a_hSocket)
  179. {
  180. a_list.RemoveAt(posPrev);
  181. // 删除
  182. __deleteClient(pClient);;
  183. return true;
  184. }
  185. } // end while
  186. return false;
  187. }
  188. /*****************************************************************
  189. **【函数名称】 insertSocket
  190. **【函数功能】 添加一个新的连接
  191. **【参数】 a_pSocket 要添加的连接
  192. **【返回值】
  193. ****************************************************************/
  194. void CClientContainer::insertClient( CNetClient* a_pClient )
  195. {
  196. __add2List(a_pClient, m_listConnecting, &m_CS4Connecting);
  197. }
  198. /*****************************************************************
  199. **【函数名称】 removeClient
  200. **【函数功能】 删除一个连接
  201. **【参数】
  202. **【返回值】
  203. ****************************************************************/
  204. bool CClientContainer::removeClient( PDU_DEV_TYPE a_nFarType, int a_nFarId )
  205. {
  206. // 注意此处的查找顺序:会影响到座席的重复签入控制
  207. // 已注册的客户端
  208. if(__lookup4Delete(a_nFarType, a_nFarId, m_listRegisted, &m_CS4Registed))
  209. return true;
  210. // 已连接的客户端
  211. if(__lookup4Delete(a_nFarType, a_nFarId, m_listConnected, &m_CS4Connected))
  212. return true;
  213. // 正在连接的客户端
  214. if(__lookup4Delete(a_nFarType, a_nFarId, m_listConnecting, &m_CS4Connecting))
  215. return true;
  216. return false;
  217. }
  218. /*****************************************************************
  219. **【函数名称】 removeClient
  220. **【函数功能】 删除一个连接
  221. **【参数】
  222. **【返回值】
  223. ****************************************************************/
  224. bool CClientContainer::removeClient( SOCKET a_hSocket )
  225. {
  226. // 已注册的客户端
  227. if(__lookup4Delete(a_hSocket, m_listRegisted, &m_CS4Registed))
  228. return true;
  229. // 已连接的客户端
  230. if(__lookup4Delete(a_hSocket, m_listConnected, &m_CS4Connected))
  231. return true;
  232. // 正在连接的客户端
  233. if(__lookup4Delete(a_hSocket, m_listConnecting, &m_CS4Connecting))
  234. return true;
  235. return false;
  236. }
  237. /*****************************************************************
  238. **【函数名称】 getClient
  239. **【函数功能】 根据对端设备类型、ID查找指定连接
  240. **【参数】 a_nFarType 对端设备类型
  241. a_nFarId 对端设备ID
  242. **【返回值】
  243. ****************************************************************/
  244. CNetClient* CClientContainer::getClient( PDU_DEV_TYPE a_nFarType, int a_nFarId )
  245. {
  246. // 已注册的SOCKET
  247. CNetClient* pCLient = __lookup(a_nFarType, a_nFarId, m_listRegisted, &m_CS4Registed);
  248. if(pCLient != NULL) return pCLient;
  249. // 已连接的SOCKET
  250. pCLient = __lookup(a_nFarType, a_nFarId, m_listConnected, &m_CS4Connected);
  251. if(pCLient != NULL) return pCLient;
  252. // 正在连接的SOCKET
  253. pCLient = __lookup(a_nFarType, a_nFarId, m_listConnecting, &m_CS4Connecting);
  254. if(pCLient != NULL) return pCLient;
  255. return NULL;
  256. }
  257. /*****************************************************************
  258. **【函数名称】 getClient
  259. **【函数功能】 根据SOCKET句柄查找指定连接
  260. **【参数】 a_hSocket SOCKET句柄
  261. **【返回值】
  262. ****************************************************************/
  263. CNetClient* CClientContainer::getClient( SOCKET a_hSocket )
  264. {
  265. CNetClient* pClient = NULL;
  266. pClient = __lookup(a_hSocket, m_listConnecting, &m_CS4Connecting);
  267. if(pClient != NULL) return pClient;
  268. pClient = __lookup(a_hSocket, m_listConnected, &m_CS4Connected);
  269. if(pClient != NULL) return pClient;
  270. pClient = __lookup(a_hSocket, m_listRegisted, &m_CS4Registed);
  271. if(pClient != NULL) return pClient;
  272. return NULL;
  273. }
  274. /*****************************************************************
  275. **【函数名称】 getClient
  276. **【函数功能】 根据SOCKET句柄查找指定连接
  277. **【参数】
  278. **【返回值】
  279. ****************************************************************/
  280. CNetClient* CClientContainer::getClient( CNetClient* a_pClient )
  281. {
  282. CNetClient* pClient = NULL;
  283. pClient = __lookup(a_pClient, m_listRegisted, &m_CS4Registed);
  284. if(pClient != NULL) return pClient;
  285. pClient = __lookup(a_pClient, m_listConnecting, &m_CS4Connecting);
  286. if(pClient != NULL) return pClient;
  287. pClient = __lookup(a_pClient, m_listConnected, &m_CS4Connected);
  288. if(pClient != NULL) return pClient;
  289. return NULL;
  290. }
  291. /*****************************************************************
  292. **【函数名称】 send2All
  293. **【函数功能】 向所有注册过的客户端发送PDU
  294. **【参数】
  295. **【返回值】
  296. ****************************************************************/
  297. void CClientContainer::send2All( CPduEntity* a_pPdu )
  298. {
  299. ASSERT(a_pPdu != NULL);
  300. CSingleLock Locker(&m_CS4Registed);
  301. Locker.Lock();
  302. POSITION pos = m_listRegisted.GetHeadPosition();
  303. while(pos != NULL)
  304. {
  305. CNetClient* pClient = m_listRegisted.GetNext(pos);
  306. ASSERT(pClient != NULL);
  307. pClient->sendPdu(a_pPdu);
  308. } // end while
  309. }
  310. /*****************************************************************
  311. **【函数名称】 release
  312. **【函数功能】 释放资源
  313. **【参数】
  314. **【返回值】
  315. ****************************************************************/
  316. void CClientContainer::release( void )
  317. {
  318. while(m_ListDeleted.GetCount() > 0)
  319. {
  320. delete m_ListDeleted.RemoveHead();
  321. }
  322. while(m_listConnecting.GetCount() > 0)
  323. {
  324. delete m_listConnecting.RemoveHead();
  325. }
  326. while(m_listConnected.GetCount() > 0)
  327. {
  328. delete m_listConnected.RemoveHead();
  329. }
  330. while(m_listRegisted.GetCount() > 0)
  331. {
  332. delete m_listRegisted.RemoveHead();
  333. }
  334. }
  335. /*****************************************************************
  336. **【函数名称】 clearClientDeleted
  337. **【函数功能】 清理缓存的已删除客户端
  338. **【参数】
  339. **【返回值】
  340. ****************************************************************/
  341. void CClientContainer::clearClientDeleted( void )
  342. {
  343. m_Cs4Deleted.Lock();
  344. while(m_ListDeleted.GetCount() > 0)
  345. delete m_ListDeleted.RemoveHead();
  346. m_Cs4Deleted.Unlock();
  347. }
  348. /*****************************************************************
  349. **【函数名称】 onConnEstablished
  350. **【函数功能】 连接建立事件处理
  351. **【参数】 a_pClient 已建立连接的客户端
  352. **【返回值】
  353. ****************************************************************/
  354. PDU_LINK_STATE CClientContainer::onConnEstablished( CNetClient* a_pClient )
  355. {
  356. PDU_LINK_STATE nLinkState = PDU_LINK_STATE_UNKNOWN; // 未知
  357. if(a_pClient->linkType() == PDU_LINK_TYPE_SERVER) // SERVER端
  358. {
  359. __add2List(a_pClient, m_listConnected, &m_CS4Connected);
  360. nLinkState = PDU_LINK_STATE_ACCEPTED;
  361. }
  362. else // CLIENT端
  363. {
  364. __removeClient(a_pClient, m_listConnecting, &m_CS4Connecting);
  365. __add2List(a_pClient, m_listConnected, &m_CS4Connected);
  366. nLinkState = PDU_LINK_STATE_SUCCESSED;
  367. } // end if
  368. return nLinkState;
  369. }
  370. /*****************************************************************
  371. **【函数名称】 onConnFailed
  372. **【函数功能】 连接失败/断开事件处理
  373. **【参数】 a_pClient 已建立连接的客户端
  374. **【返回值】
  375. ****************************************************************/
  376. PDU_LINK_STATE CClientContainer::onConnFailed( CNetClient* a_pClient )
  377. {
  378. PDU_LINK_STATE nLinkState = PDU_LINK_STATE_UNKNOWN; // 未知
  379. if(__removeClient(a_pClient, m_listRegisted, &m_CS4Registed)) // 正在进行通讯
  380. {
  381. nLinkState = PDU_LINK_STATE_DISCONNECTED;
  382. __onConnFailedProc(a_pClient); // 后续处理
  383. }
  384. else if(__removeClient(a_pClient, m_listConnected, &m_CS4Connected)) // 未握手
  385. {
  386. nLinkState = PDU_LINK_STATE_DISCONNECTED;
  387. __onConnFailedProc(a_pClient); // 后续处理
  388. }
  389. else if(__lookup(a_pClient->assoSocket(), m_listConnecting, &m_CS4Connecting) != NULL) // 初次连接/重连
  390. {
  391. nLinkState = PDU_LINK_STATE_FAILED;
  392. }
  393. else
  394. {
  395. nLinkState = PDU_LINK_STATE_FAILED;
  396. } // end if
  397. return nLinkState;
  398. }
  399. /*****************************************************************
  400. **【函数名称】 onConnRegistOK
  401. **【函数功能】 连接注册成功事件处理
  402. **【参数】 a_pClient 已注册成功的客户端
  403. **【返回值】
  404. ****************************************************************/
  405. PDU_LINK_STATE CClientContainer::onConnRegistOK( CNetClient* a_pClient )
  406. {
  407. __removeClient(a_pClient, m_listConnected, &m_CS4Connected);
  408. __add2List(a_pClient, m_listRegisted, &m_CS4Registed);
  409. return PDU_LINK_STATE_REG_OK;
  410. }
  411. /*****************************************************************
  412. **【函数名称】 onConnRegistFailed
  413. **【函数功能】 连接注册失败事件处理
  414. **【参数】 a_pClient 已注册失败的客户端
  415. **【返回值】
  416. ****************************************************************/
  417. PDU_LINK_STATE CClientContainer::onConnRegistFailed( CNetClient* a_pClient )
  418. {
  419. return PDU_LINK_STATE_REG_FAILED;
  420. }