ClientProcess.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #include "StdAfx.h"
  2. #include "ClientProcess.h"
  3. #include <comdef.h>
  4. #include <atlbase.h>
  5. const int AF_IPV4 = 0;
  6. const int AF_IPV6 = 1;
  7. const int SOCK_TCP = SOCK_STREAM-1;
  8. const int SOCK_UDP = SOCK_DGRAM-1;
  9. //CClientProcess* CClientProcess::m_pTcpClient[TCPCLIENTNUM] = {NULL};
  10. void GetFileName(IN const TCHAR *pFullName,OUT TCHAR *pFileName)
  11. {
  12. TCHAR szExt[_MAX_EXT];
  13. _tsplitpath(pFullName, NULL, NULL, pFileName, szExt);
  14. _tcscat(pFileName, szExt);
  15. }
  16. CClientProcess::CClientProcess():m_nMode(AF_IPV4),m_nSockType(SOCK_TCP)
  17. {
  18. m_bSocket = FALSE;
  19. m_bStopbeat = FALSE;
  20. m_hRunObject = NULL;
  21. m_bRecevie = TRUE;
  22. m_hReConnectSrvThreadHandle = NULL;
  23. m_dwSumRecive = 0;
  24. m_dwCurRecive = 0;
  25. m_SocketClient.SetInterface(this);
  26. }
  27. CClientProcess::~CClientProcess()
  28. {
  29. //m_SocketClient.Terminate();
  30. net_CloseSocket();
  31. }
  32. BOOL CClientProcess::SolveError()
  33. {
  34. DWORD dwWSAError = WSAGetLastError();
  35. if ( dwWSAError != 0 )
  36. {
  37. //LOG4C_NO_FILENUM((LOG_NOTICE,"dwWSAError = %d~",dwWSAError));
  38. }
  39. switch(dwWSAError)
  40. {
  41. case WSAENOTSOCK:
  42. case WSAENETDOWN:
  43. case WSAENETUNREACH:
  44. case WSAENETRESET:
  45. case WSAECONNABORTED:
  46. case WSAECONNRESET:
  47. case WSAESHUTDOWN:
  48. case WSAEHOSTDOWN:
  49. case WSAEHOSTUNREACH:
  50. TRACE("-----------------WSAError = %d\n",dwWSAError);
  51. //LOG4C_NO_FILENUM((LOG_NOTICE,"dwWSAError = %d~",dwWSAError));
  52. m_bSocket = FALSE;
  53. break;
  54. default:
  55. break;
  56. }
  57. return TRUE;
  58. }
  59. void CClientProcess::GetAddress(const SockAddrIn& addrIn, CString& rString) const
  60. {
  61. TCHAR szIPAddr[MAX_PATH] = { 0 };
  62. CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn);
  63. rString.Format(_T("%s : %d"), szIPAddr, static_cast<int>(static_cast<UINT>(ntohs(addrIn.GetPort()))) );
  64. }
  65. void CClientProcess::AppendText(LPCTSTR lpszFormat, ...)
  66. {
  67. // if ( !::IsWindow(m_ctlMsgList.GetSafeHwnd()) ) return;
  68. // TCHAR szBuffer[512];
  69. // HWND hWnd = m_ctlMsgList.GetSafeHwnd();
  70. // DWORD dwResult = 0;
  71. // if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, 0, SMTO_NORMAL, 500L, &dwResult) != 0)
  72. // {
  73. // int nLen = (int) dwResult;
  74. // if (SendMessageTimeout(hWnd, EM_SETSEL, nLen, nLen, SMTO_NORMAL, 500L, &dwResult) != 0)
  75. // {
  76. // size_t cb = 0;
  77. // va_list args;
  78. // va_start(args, lpszFormat);
  79. // ::StringCchVPrintfEx(szBuffer, 512, NULL, &cb, 0, lpszFormat, args);
  80. // va_end(args);
  81. // SendMessageTimeout(hWnd, EM_REPLACESEL, FALSE, reinterpret_cast<LPARAM>(szBuffer), SMTO_NORMAL, 500L, &dwResult);
  82. // }
  83. // }
  84. }
  85. bool CClientProcess::GetDestination(SockAddrIn& addrIn) const
  86. {
  87. CString strPort;
  88. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  89. return addrIn.CreateFrom(NULL, strPort, nFamily);
  90. }
  91. bool CClientProcess::SetupMCAST()
  92. {
  93. const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2");
  94. const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address
  95. bool result = false;
  96. if ( m_nSockType == SOCK_UDP )
  97. {
  98. if ( m_nMode == AF_IPV4 ) {
  99. result = m_SocketClient->AddMembership(szIPv4MCAST, NULL);
  100. } else {
  101. result = m_SocketClient->AddMembership(szIPv6MCAST, NULL);
  102. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  103. hr = hr;
  104. }
  105. }
  106. return result;
  107. }
  108. ///////////////////////////////////////////////////////////////////////////////
  109. void CClientProcess::OnThreadBegin(CSocketHandle* pSH)
  110. {
  111. ASSERT( pSH == m_SocketClient );
  112. (pSH);
  113. CString strAddr;
  114. SockAddrIn sockAddr;
  115. m_SocketClient->GetSockName(sockAddr);
  116. GetAddress( sockAddr, strAddr );
  117. }
  118. void CClientProcess::OnThreadExit(CSocketHandle* pSH)
  119. {
  120. ASSERT( pSH == m_SocketClient );
  121. (pSH);
  122. }
  123. void CClientProcess::OnConnectionDropped(CSocketHandle* pSH)
  124. {
  125. ASSERT( pSH == m_SocketClient );
  126. m_bSocket = FALSE;
  127. AppendText( _T("Connection lost with client.\r\n") );
  128. }
  129. void CClientProcess::OnConnectionError(CSocketHandle* pSH, DWORD dwError)
  130. {
  131. ASSERT( pSH == m_SocketClient );
  132. (pSH);
  133. _com_error err(dwError);
  134. AppendText( _T("Communication Error:\r\n%s\r\n"), err.ErrorMessage() );
  135. }
  136. /************************************************************************/
  137. /* 函数:OnDataReceived[3/21/2016 IT];
  138. /* 描述:;
  139. /* 参数:;
  140. /* [IN] pSH: 客户端实例对象;
  141. /* [IN] pbData: 客户端本次接收到的数据;
  142. /* [IN] dwCount: 客户端本次接收到的数据长度;
  143. /* [IN] addr: 服务端地址;
  144. /* 返回:void;
  145. /* 注意:;
  146. /* 示例:;
  147. /*
  148. /* 修改:;
  149. /* 日期:;
  150. /* 内容:;
  151. /************************************************************************/
  152. void CClientProcess::OnDataReceived(CSocketHandle* pSockHandle, const BYTE* pReceivebuf, DWORD dwReceiveSize, const SockAddrIn& addr)
  153. {
  154. ASSERT( pSockHandle == m_SocketClient );
  155. if( !m_SocketClient->IsOpen() ) return;
  156. if (NULL == pReceivebuf) return;
  157. DWORD dwIndexOfProcessed = 0; // 当前接收的包被处理的长度;
  158. DWORD dwOnceProcessedLen = 0; // 循环一次处理了多少当前包;
  159. TheProhead *ptphead;
  160. while( dwIndexOfProcessed < dwReceiveSize)
  161. {
  162. ptphead = NULL;
  163. dwOnceProcessedLen = 0;
  164. if ( m_dwPendingSize == 0) //----------------------------------------------// 1.第一次接收或完整组包后接收剩余包;
  165. {
  166. if( dwReceiveSize - dwIndexOfProcessed < sizeof(TheProhead) ) // 1.1.第一次接收或剩余数据不足一个包头;
  167. {
  168. // 如果第一次接包就没有收够包头;
  169. m_dwPendingSize = dwReceiveSize - dwIndexOfProcessed;
  170. //memcpy(pSockHandle->m_szpendingbuf, pstProtocolheader, pSockHandle->m_npendingSize);
  171. memcpy(m_byPendingbuf, &pReceivebuf[dwIndexOfProcessed], m_dwPendingSize);
  172. dwOnceProcessedLen = dwReceiveSize - dwIndexOfProcessed;
  173. }
  174. else // 1.2.第一次接收或剩余数据大于一个包头;
  175. {
  176. ptphead = (TheProhead *)&((unsigned char *)pReceivebuf)[dwIndexOfProcessed];
  177. if( (int)ptphead->nDataLen > dwReceiveSize - dwIndexOfProcessed ) // 1.2.1.第一次接收或剩余数据不足一个完整的协议包;
  178. {
  179. //memcpy(pSockHandle->m_szpendingbuf, pstProtocolheader, dwReceiveSize - dwIndexOfProcessed);
  180. memcpy(m_byPendingbuf, &pReceivebuf[dwIndexOfProcessed], dwReceiveSize - dwIndexOfProcessed);
  181. m_dwPendingSize = dwReceiveSize - dwIndexOfProcessed;
  182. dwOnceProcessedLen = dwReceiveSize - dwIndexOfProcessed; // 该次处理的数据长度;
  183. }
  184. else // ---------------------------------------------------------------------// 1.2.2.第一次接收或剩余数据大于一个完整的协议包;
  185. {
  186. //LOG4C((LOG_NOTICE, "正常包"));
  187. m_dwPendingSize = 0;
  188. dwOnceProcessedLen = ptphead->nDataLen; // 该次处理的数据长度;
  189. }
  190. }
  191. }
  192. else //------------------------------------------------------------------------------// 2.第n+1次接收数据包;
  193. {
  194. if( m_dwPendingSize < sizeof(TheProhead) ) // 2.1.pengingbuf数据小于包头
  195. {
  196. DWORD dwRestheader = sizeof(TheProhead) - m_dwPendingSize;
  197. if( dwRestheader < dwReceiveSize ) // 2.1.1.当前包大小 > 剩下包头长度,可以组成一个完整包头;
  198. {
  199. // -1.先收完一个完整的包头;
  200. memcpy( &m_byPendingbuf[m_dwPendingSize], pReceivebuf, dwRestheader);
  201. // -2.处理剩余数据;
  202. ptphead = (TheProhead *)m_byPendingbuf;
  203. //memcpy(ptphead, m_byPendingbuf,m_dwPendingSize);
  204. dwOnceProcessedLen = ptphead->nDataLen - m_dwPendingSize;
  205. if( dwOnceProcessedLen <= dwReceiveSize ) // 可以组成一个完整的协议包;
  206. {
  207. memcpy( &m_byPendingbuf[sizeof(TheProhead)],
  208. &((char *)pReceivebuf)[dwRestheader],
  209. ptphead->nDataLen - sizeof(TheProhead));
  210. m_dwPendingSize = 0;
  211. }
  212. else // 未能组成一个完整的协议包,断续接收等待;
  213. {
  214. //int nTemp = dwReceiveSize - dwRestheader; //除去头剩余部分的长度
  215. //if ( nTemp > 0 ) //刚好是Header的长度,不用拷贝内存,所以这里加了>0的判断
  216. //{
  217. //memcpy( &pSockHandle->m_szpendingbuf[sizeof(STProtocolheader)],&((char *)pReceivebuf)[dwRestheader],nTemp );
  218. //}
  219. memcpy( &m_byPendingbuf[sizeof(TheProhead)],&((char *)pReceivebuf)[dwRestheader],dwReceiveSize - dwRestheader);
  220. m_dwPendingSize += dwReceiveSize;
  221. }
  222. }
  223. else //------------------------------------------------------// 2.1.2.当前包大小 <= 剩下包头长度,未能或刚好组成一个完整的包头;
  224. {
  225. memcpy( &m_byPendingbuf[m_dwPendingSize], pReceivebuf, dwReceiveSize );
  226. m_dwPendingSize += dwReceiveSize;
  227. dwOnceProcessedLen = dwReceiveSize;
  228. }
  229. }
  230. else // --------------------------------------------------------// 2.2.pengingbuf数据大于包头;
  231. {
  232. ptphead = (TheProhead *)m_byPendingbuf;
  233. dwOnceProcessedLen = ptphead->nDataLen - m_dwPendingSize;
  234. if ( dwOnceProcessedLen <= dwReceiveSize ) // 可以组成一个完整的协议包;
  235. {
  236. memcpy( &m_byPendingbuf[m_dwPendingSize], pReceivebuf, dwOnceProcessedLen );
  237. m_dwPendingSize = 0;
  238. }
  239. else // 未能组成一个完整协议包;
  240. {
  241. memcpy( &m_byPendingbuf[m_dwPendingSize], pReceivebuf, dwReceiveSize );
  242. m_dwPendingSize += dwReceiveSize;
  243. }
  244. }
  245. }
  246. if ( dwOnceProcessedLen == 0 )
  247. {
  248. // 没有收够包头,认为是非法包,扔掉
  249. // LOG4C((LOG_NOTICE, "没有收够包头,认为是非法包,扔掉"));
  250. break;
  251. }
  252. if ( m_dwPendingSize == 0 )
  253. {
  254. if ( ptphead->nDataLen > SOCKET_BUFFSIZE )
  255. {
  256. // 包长度超过限制,暂时不处理;
  257. // LOG4C((LOG_NOTICE, "pstProtocolheader->nDataLen超过限制"));
  258. }
  259. //if(-1 == OnIntegrityPacket(pSockHandle, ptphead))
  260. // {
  261. // // LOG4C((LOG_NOTICE, "Error OnIntegrityPacket"));
  262. // break;
  263. //}
  264. }
  265. dwIndexOfProcessed += dwOnceProcessedLen;
  266. }
  267. }
  268. BOOL CClientProcess::Initialize()
  269. {
  270. TCHAR szIPAddr[MAX_PATH] = { 0 };
  271. CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET);
  272. AppendText(_T("Local Address (IPv4): %s\r\n"), szIPAddr);
  273. CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET6);
  274. AppendText(_T("Local Address (IPv6): %s\r\n"), szIPAddr);
  275. return TRUE;
  276. }
  277. void CClientProcess::StartReConnectSrvThread()
  278. {
  279. // Jeff.启用重连服务端线程.-------------------
  280. m_hRunObject = CreateEvent( NULL, TRUE, FALSE, _T("ClientThreadRun") );
  281. if ( m_hRunObject == NULL )
  282. {
  283. //LOG4C((LOG_NOTICE,"创建事件失败"));
  284. }
  285. m_hReConnectSrvThreadHandle = CreateThread(NULL,0,ReConnectSrvThread,this,0,NULL);
  286. if ( m_hReConnectSrvThreadHandle == NULL )
  287. {
  288. //LOG4C((LOG_NOTICE,"创建线程失败"));
  289. }
  290. }
  291. BOOL CClientProcess::ConnectServer(LPCTSTR strAddr, LPCTSTR strPort)
  292. {
  293. _stprintf_s(m_SvrAddr, MAX_PATH, _T("%s"),strAddr);
  294. _stprintf_s(m_SvrPort, MAX_PATH, _T("%s"),strPort);
  295. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  296. if ( !m_SocketClient.StartClient(NULL, strAddr, strPort, nFamily, (m_nSockType+1) ) )
  297. {
  298. m_bSocket = FALSE;
  299. return FALSE;
  300. }
  301. return TRUE;
  302. }
  303. void CClientProcess::net_CloseSocket()
  304. {
  305. if(m_hRunObject)
  306. SetEvent(m_hRunObject);
  307. if( m_hReConnectSrvThreadHandle )
  308. {
  309. if (WaitForSingleObject(m_hReConnectSrvThreadHandle,INFINITE) != WAIT_FAILED)
  310. {
  311. CloseHandle(m_hReConnectSrvThreadHandle);
  312. m_hReConnectSrvThreadHandle = NULL;
  313. }
  314. }
  315. if(m_hRunObject)
  316. CloseHandle( m_hRunObject );
  317. m_hRunObject = NULL;
  318. m_SocketClient.Terminate();
  319. }
  320. void CClientProcess::SendMsg(void *pMsg,const int nLen)
  321. {
  322. if ( m_SocketClient.IsOpen() )
  323. {
  324. USES_CONVERSION;
  325. if (m_nSockType == SOCK_TCP)
  326. {
  327. m_SocketClient.Write((const LPBYTE)(pMsg), nLen, NULL, 30000);
  328. }
  329. else
  330. {
  331. SockAddrIn sockAddr;
  332. GetDestination(sockAddr);
  333. m_SocketClient.Write((const LPBYTE)(pMsg), nLen, sockAddr, 30000);
  334. }
  335. }
  336. else
  337. {
  338. AfxMessageBox(_T("Socket is not connected"));
  339. }
  340. }
  341. DWORD WINAPI CClientProcess::ReConnectSrvThread(LPVOID pInstance)
  342. {
  343. CClientProcess *pClientImpl = (CClientProcess*)pInstance;
  344. do
  345. {
  346. // 检测连接状态;
  347. if ( pClientImpl->m_bSocket == FALSE )
  348. {
  349. if ( pClientImpl->m_SocketClient->IsOpen() == TRUE )
  350. {
  351. pClientImpl->m_SocketClient.Terminate();
  352. }
  353. pClientImpl->m_bSocket = pClientImpl->ConnectServer(pClientImpl->m_SvrAddr,pClientImpl->m_SvrPort);
  354. }
  355. } while( WaitForSingleObject(pClientImpl->m_hRunObject,200L) == WAIT_TIMEOUT );
  356. //LOG4C_NO_FILENUM((LOG_NOTICE,"重连服务器线程退出"));
  357. return 0;
  358. }
  359. INT CClientProcess::Send(IN TheProbody& tpbody, IN const int& nTimeout)
  360. {
  361. return m_SocketClient->Write((LPBYTE)&tpbody, sizeof(TheProhead) + tpbody.tphead.nDataLen, NULL, nTimeout);
  362. }