ClientComm.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. // ClientComm.cpp: implementation of the CClientComm class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ErrorCode.h"
  6. #include <WTypes.h>
  7. #ifdef _INCLUDE_SPBASE_
  8. #include "SpBase.h"
  9. #else
  10. #define Dbg
  11. #endif
  12. #include "ClientComm.h"
  13. #include "Package.h"
  14. #include <process.h>
  15. #include <assert.h>
  16. #include <string.h>
  17. DWORD CClientComm::s_dwSessionID =0;
  18. DWORD CClientComm::s_dwTokenHash =0;
  19. BYTE CClientComm::s_arrSessionKey[16] = {0};
  20. //////////////////////////////////////////////////////////////////////
  21. // Construction/Destruction
  22. //////////////////////////////////////////////////////////////////////
  23. #define SafeCallbackOnSocketError() \
  24. try \
  25. { \
  26. int nErrCode = WSAGetLastError(); \
  27. string errMsg = GetSysErrorMsg(nErrCode); \
  28. if (m_pCallback != NULL)\
  29. m_pCallback->OnError(Error_IO, 0, errMsg.c_str()); \
  30. } \
  31. catch(...) {}
  32. #define SafeCallbackOnError(dwSysCode, dwUserCode, pErrMsg) \
  33. try \
  34. { \
  35. if (m_pCallback != NULL)\
  36. m_pCallback->OnError(dwSysCode, dwUserCode, pErrMsg); \
  37. } \
  38. catch(...) {}
  39. #define SafeCallbackOnClose() \
  40. try \
  41. { \
  42. if (m_pCallback != NULL)\
  43. m_pCallback->OnClose();\
  44. } \
  45. catch (...) {}
  46. CClientComm::CClientComm(CSecureClientBase *pCallback)
  47. :SOCKET_RECV_BUF_LEN(8096)
  48. {
  49. assert(pCallback != NULL);
  50. m_pCallback = pCallback;
  51. m_hSocket = INVALID_SOCKET;
  52. m_hWorkThread = 0;
  53. m_eState = State_None;
  54. m_bNeedAuth = true;
  55. m_hRecvEvent = ::CreateEventA(NULL, FALSE, FALSE, NULL);
  56. m_nSyncWaitResult = 0;
  57. m_nRecvBufLen = SOCKET_RECV_BUF_LEN * 100; //800K
  58. m_pRecvBuf = new BYTE[m_nRecvBufLen];
  59. memset(m_pRecvBuf, 0, m_nRecvBufLen);
  60. m_nHasRecvLen =0;
  61. m_dwSessionID =0;
  62. m_dwTokenHash =0;
  63. memset(m_arrSessionKey, 0, 16);
  64. }
  65. CClientComm::~CClientComm()
  66. {
  67. Close();
  68. if (m_hRecvEvent != 0)
  69. {
  70. CloseHandle(m_hRecvEvent);
  71. m_hRecvEvent = 0;
  72. }
  73. delete[] m_pRecvBuf;
  74. m_pRecvBuf = NULL;
  75. m_nRecvBufLen = 0;
  76. }
  77. // 创建连接,@option:1、重新鉴权新建会话密钥;2、通过握手使用缓存会话密钥;
  78. // 3、不使用会话密钥,即非安全通道 4、不协商,直接使用共享会话密钥
  79. bool CClientComm::Connect(const char *pServerAddr, int nPort, int nOption)
  80. {
  81. m_eState = State_Connecting;
  82. m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  83. if (m_hSocket == INVALID_SOCKET)
  84. {
  85. m_eState = State_Error;
  86. SafeCallbackOnSocketError();
  87. return false;
  88. }
  89. //SetSocketOption();
  90. sockaddr_in addr;
  91. ZeroMemory(&addr, sizeof(sockaddr_in));
  92. addr.sin_family = AF_INET;
  93. addr.sin_addr.s_addr = inet_addr(pServerAddr);
  94. addr.sin_port = htons(nPort);
  95. if (connect(m_hSocket, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
  96. {
  97. m_eState = State_Error;
  98. SafeCallbackOnSocketError();
  99. return false;
  100. }
  101. m_bNeedAuth = (nOption != 3);
  102. // 创建接收线程,支持异步模式
  103. UINT nThreadID;
  104. m_hWorkThread = (HANDLE)_beginthreadex(NULL, 0, &RecvThreadFunc, this, 0, &nThreadID);
  105. if (m_hWorkThread == 0)
  106. {
  107. Close();
  108. SafeCallbackOnError(Error_Unexpect, 0, "_beginthreadex() error");
  109. m_eState = State_Error;
  110. return false;
  111. }
  112. bool bSendSuc = false;
  113. if (nOption == 3)
  114. {
  115. // 非鉴权握手
  116. bSendSuc = SendHelloReqPackage();
  117. }
  118. else if (nOption == 4) // 使用共享会话密钥
  119. {
  120. bSendSuc = SendUseSharedSKPackage();
  121. }
  122. else if (nOption == 2 && s_dwSessionID !=0) // 连接成功,如果要重用会话密钥,则发送握手请求
  123. {
  124. bSendSuc = SendShakeReqPackage();
  125. }
  126. else
  127. {
  128. // 重新鉴权
  129. bSendSuc = SendAuthReqPackage();
  130. }
  131. // 同步等待返回
  132. WaitRetPkg:
  133. if (!bSendSuc)
  134. {
  135. SafeCallbackOnError(Error_Unexpect, 0, "send auth pkg fail");
  136. Close();
  137. m_eState = State_Error;
  138. return false;
  139. }
  140. auto pkg = ReceivePackage(10);
  141. if (pkg == NULL)
  142. {
  143. if (m_eState == State_Connecting)
  144. SafeCallbackOnError(Error_TimeOut, 0, "connect timeout");
  145. m_eState = State_Error;
  146. Close();
  147. return false;
  148. }
  149. bool bAuthSuc = false;
  150. if (strcmp(pkg->GetServiceCode().c_str(), "__AUTH__") ==0)
  151. {
  152. bAuthSuc = HandleAuthRetPackage(pkg);
  153. }
  154. else if (strcmp(pkg->GetServiceCode().c_str(), "_SHAKE_") == 0)
  155. {
  156. bAuthSuc = HandleShakeRetPackage(pkg);
  157. if (!bAuthSuc)
  158. {
  159. // 握手失败,重新鉴权
  160. bSendSuc = SendAuthReqPackage();
  161. goto WaitRetPkg;
  162. }
  163. }
  164. else if (strcmp(pkg->GetServiceCode().c_str(), "_USESSK_") == 0)
  165. {
  166. bAuthSuc = HandleUseSharedSKRetPackage(pkg);
  167. if (!bAuthSuc)
  168. {
  169. // 使用共享密钥请求失败,重新鉴权
  170. bSendSuc = SendAuthReqPackage();
  171. goto WaitRetPkg;
  172. }
  173. }
  174. else if (strcmp(pkg->GetServiceCode().c_str(), "_HELLO_") == 0)
  175. {
  176. bAuthSuc = HandleHelloRetPackage(pkg);
  177. }
  178. else
  179. {
  180. // 继续等待
  181. goto WaitRetPkg;
  182. }
  183. if (bAuthSuc)
  184. {
  185. m_eState = State_OK;
  186. // 回调OnAuthPass事件
  187. try
  188. {
  189. m_pCallback->OnAuthPass();
  190. }
  191. catch(...)
  192. {
  193. SafeCallbackOnError(Error_Exception, 0, "OnAuthPass exception");
  194. }
  195. }
  196. else
  197. {
  198. m_eState = State_Error;
  199. }
  200. return bAuthSuc;
  201. }
  202. CSmartPointer<IPackage> CClientComm::CreateNewPackage(const char *pServiceCode)
  203. {
  204. CSmartPointer<IPackage> ptr;
  205. ptr.Attach(new CCommPackage(m_bNeedAuth && m_eState == State_OK ? m_arrSessionKey : NULL, pServiceCode));
  206. return ptr;
  207. }
  208. CSmartPointer<IPackage> CClientComm::CreateReplyPackage(const CSmartPointer<IPackage>& pRecvPkg)
  209. {
  210. CCommPackage* p = dynamic_cast<CCommPackage*>(pRecvPkg.GetRawPointer());
  211. CSmartPointer<IPackage> ptr;
  212. ptr.Attach(new CCommPackage(p));
  213. return ptr;
  214. }
  215. // socket接收线程
  216. UINT CClientComm::RecvThreadFunc(void *pArg)
  217. {
  218. CClientComm *pThis = (CClientComm*) pArg;
  219. assert(pThis != NULL);
  220. while(pThis->m_eState == State_OK || pThis->m_eState == State_Connecting)
  221. {
  222. pThis->RecvThreadProcess();
  223. }
  224. // 清空接收缓存
  225. pThis->m_nHasRecvLen = 0;
  226. // 退出线程
  227. _endthreadex(0);
  228. return 0;
  229. }
  230. bool CClientComm::IsConnectionOK()
  231. {
  232. return m_eState == State_OK ;
  233. }
  234. bool CClientComm::IsSecureConnection()
  235. {
  236. return m_bNeedAuth;
  237. }
  238. void CClientComm::RecvThreadProcess()
  239. {
  240. // 查询状态
  241. fd_set fdsRead;
  242. FD_ZERO(&fdsRead);
  243. FD_SET(m_hSocket, &fdsRead);
  244. timeval waitTime;
  245. waitTime.tv_sec = 0;
  246. waitTime.tv_usec = 100 * 1000;
  247. int rc = select(0, &fdsRead, NULL, NULL, &waitTime);
  248. if (rc >0) // 有数据到达
  249. {
  250. int nLen = recv(m_hSocket, (char *)m_pRecvBuf + m_nHasRecvLen, m_nRecvBufLen - m_nHasRecvLen, 0);
  251. if (nLen ==0)
  252. {
  253. // 连接已中断
  254. if (m_eState == State_OK)
  255. {
  256. m_eState = State_Disconnected;
  257. SafeCallbackOnError(Error_NetBroken, 0, "socket disconnected");
  258. SafeCallbackOnClose();
  259. }
  260. return;
  261. }
  262. else if (nLen <0)
  263. {
  264. bool bCallback = m_eState == State_OK;
  265. m_eState = State_Error;
  266. if (bCallback)
  267. {
  268. SafeCallbackOnSocketError();
  269. SafeCallbackOnClose();
  270. }
  271. m_eState = State_Error;
  272. return;
  273. }
  274. else
  275. {
  276. m_nHasRecvLen += nLen;
  277. // 可能一次收到多个包
  278. while(true)
  279. {
  280. // 检查包头是否完整
  281. if (m_nHasRecvLen < sizeof(CPackageHeader))
  282. return;
  283. // 提取整包长度
  284. int nPackageLen = GetPackageLenFromRecvBuf();
  285. // 重新分配接收缓冲区
  286. if (nPackageLen > m_nRecvBufLen)
  287. {
  288. BYTE *pNewBuf = new BYTE[nPackageLen];
  289. memset(pNewBuf, 0, nPackageLen);
  290. m_nRecvBufLen = nPackageLen;
  291. memcpy(pNewBuf, m_pRecvBuf, m_nHasRecvLen);
  292. delete[] m_pRecvBuf;
  293. m_pRecvBuf = pNewBuf;
  294. return;
  295. }
  296. if (m_nHasRecvLen < nPackageLen)
  297. return;
  298. // 解析整包长度
  299. CCommPackage *p = new CCommPackage(m_bNeedAuth && m_eState==State_OK ? m_arrSessionKey : NULL, NULL);
  300. CSmartPointer<IPackage> ppkg;
  301. ppkg.Attach(p);
  302. string strErrMsg;
  303. if (p->ParseRecvData(m_pRecvBuf, &nPackageLen, strErrMsg))
  304. {
  305. // 从缓冲区删除完整包数据
  306. memmove(m_pRecvBuf, m_pRecvBuf + nPackageLen, m_nHasRecvLen - nPackageLen);
  307. m_nHasRecvLen -= nPackageLen;
  308. // 检查是否底层错误包
  309. if (strcmp(ppkg->GetServiceCode().c_str(), "__ERROR_") ==0)
  310. {
  311. DWORD dwSysCode(0), dwUserCode(0);
  312. string strErrMsg;
  313. if (!ppkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  314. {
  315. dwSysCode = Error_Bug;
  316. strErrMsg = "get comm package error msg fail";
  317. }
  318. SafeCallbackOnError(dwSysCode, dwUserCode, strErrMsg.c_str());
  319. m_eState = State_Error;
  320. if (::InterlockedCompareExchange(&m_nSyncWaitResult, 0, 1) == 1)
  321. ::SetEvent(m_hRecvEvent);
  322. return;
  323. }
  324. // 回调应用处理
  325. if (::InterlockedCompareExchange(&m_nSyncWaitResult, 0, 1) == 1)
  326. {
  327. CAutoLock Lock(&m_LockObject,1000);
  328. m_RecvPackages.push_back(ppkg.Detach());
  329. ::SetEvent(m_hRecvEvent);
  330. }
  331. else
  332. {
  333. // 回调
  334. if (m_pCallback != NULL)
  335. {
  336. try
  337. {
  338. m_pCallback->OnReceivePackage(ppkg);
  339. }
  340. catch (...) {}
  341. }
  342. }
  343. }
  344. else
  345. {
  346. // 丢弃全部接收数据
  347. m_nHasRecvLen = 0;
  348. SafeCallbackOnError(Error_Bug, 0, strErrMsg.c_str());
  349. SafeCallbackOnClose();
  350. m_eState = State_Error;
  351. }
  352. }
  353. }
  354. }
  355. else if (rc ==0) // 超时
  356. {
  357. }
  358. else if (rc == SOCKET_ERROR) // 错误
  359. {
  360. if (m_eState == State_OK)
  361. {
  362. SafeCallbackOnSocketError();
  363. SafeCallbackOnClose();
  364. m_eState = State_Error;
  365. }
  366. }
  367. }
  368. bool CClientComm::SendUseSharedSKPackage()
  369. {
  370. CUseSharedSKReq req;
  371. memset(&req, 0, sizeof(req));
  372. int nSKLen = 16;
  373. int nTNLen = 16;
  374. if (!m_pCallback->OnGetSharedSK(req.m_arrTerminalNo, &nTNLen, m_arrSessionKey, &nSKLen))
  375. {
  376. SafeCallbackOnError(Error_Unexpect, 0, "get shared seesion key fail");
  377. return false;
  378. }
  379. // 生成Hash
  380. BYTE md5[16];
  381. memset(md5, 0, 16);
  382. MD5Hash(m_arrSessionKey, 16, md5);
  383. DWORD dwHash = ((DWORD)md5[0]) << 24 | ((DWORD)md5[1]) << 16 | ((DWORD)md5[2]) << 8 | ((DWORD)md5[3]);
  384. req.m_dwSharedSKHash = dwHash;
  385. CSmartPointer<IPackage> pkg = CreateNewPackage("_USESSK_");
  386. pkg->AddStruct("USESKREQ", false, false, (BYTE*)&req, sizeof(req));
  387. return SendPackage(pkg) != "";
  388. }
  389. bool CClientComm::SendShakeReqPackage()
  390. {
  391. CSessionShakeReq req;
  392. memset(&req, 0, sizeof(req));
  393. //ASSERT(pTerminalNo != NULL);
  394. req.m_dwTokenHash = s_dwTokenHash;
  395. req.m_dwSessionID = s_dwSessionID;
  396. CSmartPointer<IPackage> pkg = CreateNewPackage("_SHAKE_");
  397. pkg->AddStruct("SHAKEREQ", false, false, (BYTE*)&req, sizeof(req));
  398. return SendPackage(pkg) != "";
  399. }
  400. bool CClientComm::SendHelloReqPackage()
  401. {
  402. CSmartPointer<IPackage> pkg = CreateNewPackage("_HELLO_");
  403. return SendPackage(pkg) != "";
  404. }
  405. bool CClientComm::SendAuthReqPackage()
  406. {
  407. CConnAuthReq authReq;
  408. memset(&authReq, 0, sizeof(authReq));
  409. try
  410. {
  411. if (!m_pCallback->OnAuthRequest(&authReq))
  412. {
  413. SafeCallbackOnError(Error_Unexpect, 0, "callback OnAuthRequest() error");
  414. return false;
  415. }
  416. }
  417. catch(...)
  418. {
  419. SafeCallbackOnError(Error_Exception, 0, "callback OnAuthRequest() exception");
  420. return false;
  421. }
  422. // 保存TokenHash
  423. BYTE md5[16];
  424. memset(md5, 0, 16);
  425. MD5Hash(authReq.m_arrVerifyToken, sizeof(authReq.m_arrVerifyToken), md5);
  426. m_dwTokenHash = ((DWORD)md5[0]) << 24 | ((DWORD)md5[1]) << 16 | ((DWORD)md5[2]) << 8 | ((DWORD)md5[3]);
  427. {
  428. CAutoLock lock(&m_LockObject);
  429. s_dwTokenHash = m_dwTokenHash;
  430. }
  431. CSmartPointer<IPackage> ppkg = CreateNewPackage("__AUTH__");
  432. ppkg->AddStruct("AUTH_REQ", false, false, (BYTE*)&authReq, sizeof(authReq));
  433. return SendPackage(ppkg) != "";
  434. }
  435. bool CClientComm::HandleHelloRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  436. {
  437. DWORD dwSysCode(0), dwUserCode(0);
  438. string errMsg;
  439. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  440. {
  441. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  442. return false;
  443. }
  444. return true;
  445. }
  446. bool CClientComm::HandleShakeRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  447. {
  448. // 握手通过
  449. DWORD dwSysCode(0), dwUserCode(0);
  450. string errMsg;
  451. if (!pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  452. {
  453. // 将缓存的Session信息恢复
  454. {
  455. CAutoLock lock(&m_LockObject);
  456. m_dwSessionID = s_dwSessionID;
  457. m_dwTokenHash = s_dwTokenHash;
  458. memcpy(m_arrSessionKey, s_arrSessionKey, 16);
  459. }
  460. return true;
  461. }
  462. // 握手失败,重新鉴权
  463. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  464. return false;
  465. }
  466. bool CClientComm::HandleUseSharedSKRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  467. {
  468. // 握手通过
  469. DWORD dwSysCode(0), dwUserCode(0);
  470. string errMsg;
  471. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  472. {
  473. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  474. return false;
  475. }
  476. return true;
  477. }
  478. bool CClientComm::HandleAuthRetPackage(const CSmartPointer<IPackage> &pRetPkg)
  479. {
  480. DWORD dwSysCode(0), dwUserCode(0);
  481. string errMsg;
  482. if (pRetPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg))
  483. {
  484. SafeCallbackOnError(dwSysCode, dwUserCode, errMsg.c_str());
  485. return false;
  486. }
  487. int nBufLen = pRetPkg->GetStructLen("AUTH_RET");
  488. if (nBufLen != sizeof(CConnAuthRet))
  489. {
  490. char buf[64];
  491. sprintf(buf, "struct length of [AUTH_RET] is invalid: %d", nBufLen);
  492. SafeCallbackOnError(Error_Bug, 0, buf);
  493. return false;
  494. }
  495. CConnAuthRet authRet;
  496. memset(&authRet, 0, sizeof(authRet));
  497. int nArrayNum(0);
  498. bool bRet = pRetPkg->GetStructData("AUTH_RET", (BYTE*)&authRet, &nBufLen, &nArrayNum);
  499. if (!bRet)
  500. {
  501. SafeCallbackOnError(Error_Bug, 0, "get struct data of [AUTH_RET] fail");
  502. return false;
  503. }
  504. // 解密并保存会话密钥
  505. int nLen = 256;
  506. BYTE buf[256];
  507. memset(buf, 0, 256);
  508. try
  509. {
  510. if (!m_pCallback->OnSessionKeyRet(&authRet, buf, &nLen))
  511. {
  512. SafeCallbackOnError(Error_Unexpect, 0, "callback OnSessionKeyRet() error");
  513. return false;
  514. }
  515. }
  516. catch(...)
  517. {
  518. SafeCallbackOnError(Error_Exception, 0, "decrypt return session key exception");
  519. return false;
  520. }
  521. if (nLen == 16)
  522. {
  523. memcpy(m_arrSessionKey, buf, 16);
  524. // 缓存SessionKey
  525. {
  526. CAutoLock lock(&m_LockObject);
  527. memcpy(s_arrSessionKey, m_arrSessionKey, 16);
  528. }
  529. // 生成SessionID并保存
  530. BYTE md5[16];
  531. memset(md5, 0, 16);
  532. MD5Hash(m_arrSessionKey, 16, md5);
  533. m_dwSessionID = ((DWORD)md5[0]) << 24 | ((DWORD)md5[1]) << 16 | ((DWORD)md5[2]) << 8 | ((DWORD)md5[3]);
  534. {
  535. CAutoLock lock(&m_LockObject);
  536. s_dwSessionID = m_dwSessionID;
  537. }
  538. return true;
  539. }
  540. else
  541. {
  542. SafeCallbackOnError(Error_Bug, 0, "decrypted sesseion key length invalid");
  543. return false;
  544. }
  545. }
  546. int CClientComm::GetPackageLenFromRecvBuf()
  547. {
  548. if (m_pRecvBuf == NULL || m_nRecvBufLen < sizeof(CPackageHeader) || m_nHasRecvLen < sizeof(CPackageHeader))
  549. return 0;
  550. CPackageHeader *pHead = (CPackageHeader*) m_pRecvBuf;
  551. return pHead->m_nPackageLen;
  552. }
  553. void CClientComm::SetSocketOption()
  554. {
  555. /*
  556. //Send time out
  557. int timeout = SOCKET_SENDTIMEOUT * 1000;
  558. int rc = setsockopt(nSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
  559. //recieve time out
  560. setsockopt(nSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
  561. // Send keepalives
  562. nSockOptVal = 1;
  563. setsockopt(nSocket, SOL_SOCKET, SO_KEEPALIVE, (const char FAR *)&nSockOptVal, sizeof(nSockOptVal));
  564. //Reuse Port
  565. BOOL bOptVal = TRUE;
  566. setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bOptVal, sizeof(bOptVal));
  567. */
  568. // Enable "hard" close
  569. LINGER LingerOpt;
  570. LingerOpt.l_onoff = 0;
  571. LingerOpt.l_linger = 0;
  572. setsockopt(m_hSocket, SOL_SOCKET, SO_LINGER, (const char FAR *)&LingerOpt, sizeof(LingerOpt));
  573. // set recv buf lenght
  574. setsockopt(m_hSocket, SOL_SOCKET, SO_RCVBUF, (const char *) SOCKET_RECV_BUF_LEN, sizeof(int));
  575. }
  576. // 返回序列号
  577. string CClientComm::SendPackage(const CSmartPointer<IPackage>& pSendPkg)
  578. {
  579. CCommPackage *pkg = dynamic_cast<CCommPackage*>(pSendPkg.GetRawPointer());
  580. assert(pkg != NULL);
  581. if (m_bNeedAuth && m_eState != State_OK
  582. && pkg->GetServiceCode().compare("__AUTH__") != 0
  583. && pkg->GetServiceCode().compare("_HELLO_") != 0
  584. && pkg->GetServiceCode().compare("_USESSK_") != 0
  585. && pkg->GetServiceCode().compare("_SHAKE_") != 0)
  586. {
  587. SafeCallbackOnError(Error_Bug, 0, "conn auth first");
  588. return "";
  589. }
  590. //Dbg("begin send package: [%s]", pSendPkg->GetServiceCode().c_str());
  591. int nBufLen = pkg->GetPackageLen();
  592. BYTE *pBuf = new BYTE[nBufLen];
  593. memset(pBuf, 0, nBufLen);
  594. pkg->GenerateSendData(pBuf, &nBufLen);
  595. int nTotalSend =0;
  596. while (nTotalSend < nBufLen)
  597. {
  598. int nSendLen = send(m_hSocket, (const char *)pBuf + nTotalSend, nBufLen - nTotalSend, 0);
  599. if (nSendLen == SOCKET_ERROR)
  600. break;
  601. nTotalSend += nSendLen;
  602. }
  603. delete[] pBuf;
  604. #ifdef _INCLUDE_SPBASE_
  605. if (nTotalSend < nBufLen)
  606. LogError(Severity_Low, Error_NetBroken, 0, (const char*)CSimpleStringA::Format("send package [%s] fail, socket error: [%d]",
  607. pSendPkg->GetServiceCode().c_str(), WSAGetLastError()));
  608. //else
  609. //Dbg("send package [%s] succeed, total [%d] bytes", pSendPkg->GetServiceCode().c_str(), nTotalSend);
  610. #endif
  611. return nTotalSend == nBufLen ? pkg->GetPackageReqID() : "";
  612. }
  613. CSmartPointer<IPackage> CClientComm::ReceivePackage(int nWaitSecond)
  614. {
  615. if (m_eState != State_OK && m_eState != State_Connecting)
  616. {
  617. SafeCallbackOnError(Error_Bug, 0, "connection not ok!");
  618. return NULL;
  619. }
  620. DWORD dwWaitResult = WAIT_OBJECT_0;
  621. ResetEvent(m_hRecvEvent);
  622. ::InterlockedExchange(&m_nSyncWaitResult, 1);
  623. if (m_RecvPackages.size() == 0)
  624. {
  625. dwWaitResult = WaitForSingleObject(m_hRecvEvent, nWaitSecond * 1000);
  626. }
  627. if (dwWaitResult == WAIT_OBJECT_0 && (m_eState == State_OK || m_eState == State_Connecting))
  628. {
  629. assert(m_RecvPackages.size() >0);
  630. CAutoLock lock(&m_LockObject, 1000);
  631. CSmartPointer<IPackage> ptr;
  632. ptr.Attach(m_RecvPackages.back());
  633. m_RecvPackages.pop_back();
  634. return ptr;
  635. }
  636. return NULL;
  637. }
  638. void CClientComm::Close()
  639. {
  640. if (m_eState == State_OK)
  641. m_eState = State_Closed;
  642. if (m_hWorkThread != 0)
  643. {
  644. CloseHandle(m_hWorkThread);
  645. m_hWorkThread = 0;
  646. }
  647. if (m_hSocket != INVALID_SOCKET)
  648. {
  649. shutdown(m_hSocket, SD_BOTH);
  650. closesocket(m_hSocket);
  651. m_hSocket = INVALID_SOCKET;
  652. }
  653. }