TwoShipperSocket.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. #include "stdafx.h"
  2. #include <atlbase.h>
  3. //#include "Client2SrvType.h"
  4. #include "Global.h"
  5. #include "TwoShipperSocket.h"
  6. #include "crc32.h"
  7. #pragma warning(push)
  8. #pragma warning(disable:4995)
  9. #pragma warning(pop)
  10. //---------------------------------------------- CTwoShipperSocket ----
  11. CTwoShipperSocket::CTwoShipperSocket()
  12. {
  13. m_bIsServer = false;
  14. m_hHeartHandle = NULL;
  15. m_bHeartExit = false;
  16. m_bClientLoginServerSuccess = false;
  17. m_dwServiceOnlineTick = 0;
  18. CString sTemp;
  19. DllC_GetAddressInfo( sTemp,m_sLocalGateway );
  20. }
  21. CTwoShipperSocket::CTwoShipperSocket(int nIsInSlave)
  22. {
  23. m_bIsServer = nIsInSlave;
  24. m_hHeartHandle = NULL;
  25. m_bHeartExit = false;
  26. m_bClientLoginServerSuccess = false;
  27. m_dwServiceOnlineTick = 0;
  28. }
  29. CTwoShipperSocket::~CTwoShipperSocket()
  30. {
  31. if( m_hHeartHandle )
  32. {
  33. m_bHeartExit = true;
  34. delete m_hHeartHandle;
  35. m_hHeartHandle = NULL;
  36. }
  37. //DllC_LogoutServer();
  38. }
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // 实现ISocketClientHandler的通信方法
  41. void CTwoShipperSocket::DllS_ThreadBegin(CString sServerIP)
  42. {
  43. CString show;
  44. show.Format("#%s开始线程",sServerIP );
  45. LOG4C((LOG_INFO, show));
  46. }
  47. void CTwoShipperSocket::DllS_ThreadExit(CString sServerIP)
  48. {
  49. CString show;
  50. show.Format("#%s离开线程",sServerIP );
  51. LOG4C((LOG_INFO, show));
  52. }
  53. void CTwoShipperSocket::DllS_DataReceived(CString sServerIP,const BYTE* pbData, DWORD dwCount, CString sClientIP)
  54. {
  55. //LOG4C_HEX_DUMP( (LOG_INFO,(const char *)pbData,dwCount));
  56. //if( !m_SocketClient->IsOpen() ) return;
  57. //ProcessData( pSH, pbData, dwCount );
  58. CString show;
  59. show.Format("#%s接收到%s的数据",sServerIP,sClientIP );
  60. LOG4C((LOG_INFO, show));
  61. OnCmdProcess( (void *)pbData );
  62. }
  63. void CTwoShipperSocket::DllS_ConnectionDropped(CString sServerIP,CString sClientIP)
  64. {
  65. CString show;
  66. show.Format("#客户端%s掉线",sClientIP );
  67. LOG4C((LOG_INFO, show));
  68. }
  69. void CTwoShipperSocket::DllS_ConnectionError(CString sServerIP,DWORD dwError)
  70. {
  71. CString show;
  72. show.Format("#连接%s失败,错误码为%d",sServerIP,dwError );
  73. LOG4C((LOG_INFO, show));
  74. }
  75. void CTwoShipperSocket::DllS_ConnectionFailure(CString sServerIP,CString sClientIP)
  76. {
  77. CString show;
  78. show.Format("#%s连接%s失败",sClientIP,sServerIP );
  79. LOG4C((LOG_INFO, show));
  80. }
  81. void CTwoShipperSocket::DllS_AddConnection(CString sServerIP,CString sClientIP)
  82. {
  83. m_sClientIP = sClientIP;
  84. CString show;
  85. show.Format("#%s增加新的连接%s",sServerIP,sClientIP );
  86. LOG4C((LOG_INFO, show));
  87. if( m_bIsServer && m_hHeartHandle == NULL )
  88. {
  89. LOG4C_FUN( ("Server Creat CheckHeartProc" ));
  90. m_dwServiceOnlineTick = GetTickCount();
  91. m_hHeartHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CheckHeartProc, this, 0, 0);
  92. m_bHeartExit = false;
  93. }
  94. }
  95. void CTwoShipperSocket::DllC_ThreadBegin(CString sLocalIP)
  96. {
  97. //InitializeCriticalSection(&pSH->m_hClient2SrvSection);
  98. if( !m_bIsServer && m_hHeartHandle == NULL )
  99. {
  100. LOG4C_FUN( ("Client Creat SendHeartProc" ));
  101. m_hHeartHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendHeartProc, this, 0, 0);
  102. m_bHeartExit = false;
  103. }
  104. CString show;
  105. show.Format("#%s开始线程",sLocalIP );
  106. LOG4C((LOG_INFO, show));
  107. }
  108. void CTwoShipperSocket::DllC_ThreadExit(CString sLocalIP)
  109. {
  110. CString show;
  111. show.Format("#%s退出线程",sLocalIP );
  112. LOG4C((LOG_INFO, show));
  113. }
  114. void CTwoShipperSocket::DllC_DataReceived( CString sLocalIP,const BYTE* pbData, DWORD dwCount, CString sServerIP)
  115. {
  116. CString show;
  117. show.Format("#收到%s的数据",sServerIP );
  118. LOG4C((LOG_INFO, show));
  119. }
  120. void CTwoShipperSocket::DllC_ConnectionDropped(CString sLocalIP, CString sServerIP)
  121. {
  122. CString show;
  123. show.Format("#%s掉线",sServerIP );
  124. LOG4C((LOG_INFO, show));
  125. m_bClientLoginServerSuccess = false;
  126. }
  127. void CTwoShipperSocket::DllC_ConnectionError( CString sLocalIP,DWORD dwError)
  128. {
  129. CString show;
  130. show.Format("#%s连接错误,错误码为%d",sLocalIP,dwError );
  131. LOG4C((LOG_INFO, show));
  132. }
  133. unsigned int CTwoShipperSocket::CalcCheckSum( void *pData, unsigned int nSize )
  134. {
  135. unsigned int checksum = 0;
  136. if ( nSize < sizeof( ProtocolHeader ) )
  137. {
  138. return 0;
  139. }
  140. unsigned char *pBody = &( ( unsigned char* )pData )[ sizeof( ProtocolHeader ) ];
  141. nSize -= sizeof( ProtocolHeader );
  142. checksum = crc32( 0, pBody, nSize );
  143. return checksum;
  144. }
  145. void CTwoShipperSocket::ProcessHeart(void *pData, int nLen)
  146. {
  147. //m_SocketClient->Write((const LPBYTE)pData, nLen, NULL);
  148. //ProtocolHeader *pHeader = (ProtocolHeader *)pData;
  149. //if( pHeader != NULL )
  150. //{
  151. // if( pHeader->nCmdType >= 0 && pHeader->nCmdType < MAX_DllS__TYPE )
  152. // {
  153. // g_dwServiceOnlineTick[pHeader->nCmdType] = GetTickCount();
  154. // //CString str;
  155. // //str.Format("动态库类型=%d, 收到心跳包", pHeader->nCmdType);
  156. // //LogEvent(str);
  157. // }
  158. //}
  159. //LogEvent("收到心跳包");
  160. }
  161. int CTwoShipperSocket::OnCmdProcess(void *pData)
  162. {
  163. ProtocolHeader *pHeader = (ProtocolHeader *)pData;
  164. if( pHeader == NULL ) return -1;
  165. if( pHeader->nLen < 0 || pHeader->nLen > 65535 ) return -1;
  166. switch( pHeader->nCmd )
  167. {
  168. case CMD_TWOSHIPPER_HEART:
  169. {
  170. //LOG4C_FUN(( "*********心跳包**********"));
  171. m_dwServiceOnlineTick = GetTickCount();
  172. }
  173. break;
  174. }
  175. return 0;
  176. }
  177. void CTwoShipperSocket::ProcessData(CSocketHandle *pSH, const BYTE* pData, DWORD nLen)
  178. {
  179. DWORD nBuffIndex = 0;
  180. EnterCriticalSection( &(pSH->m_hClient2SrvSection) );
  181. while( nBuffIndex < nLen )
  182. {
  183. ProtocolHeader *pHeader; //当前协议包头
  184. DWORD nProcessedLen = 0; //当前循环处理了多少个字节
  185. if( pSH->m_nPendingSize > 0 ) // 开始组包
  186. {
  187. pHeader = (ProtocolHeader *)pSH->m_PendingBuffer;
  188. if( pSH->m_nPendingSize < sizeof(ProtocolHeader) ) //上一次接收到的长度小于包头
  189. {
  190. DWORD nLinkHeaderLen = sizeof( ProtocolHeader ) - pSH->m_nPendingSize;
  191. if( nLinkHeaderLen <= nLen ) //这次可以收完包头
  192. {
  193. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLinkHeaderLen ); //这里已经收完Header
  194. nProcessedLen = pHeader->nLen - pSH->m_nPendingSize;
  195. if( nProcessedLen <= nLen ) //如果所需处理的长度小于等于当前包长度
  196. {
  197. memcpy( &pSH->m_PendingBuffer[ sizeof( ProtocolHeader ) ],
  198. & ( ( char *) pData )[ nLinkHeaderLen ],
  199. pHeader->nLen - sizeof( ProtocolHeader ) );
  200. pSH->m_nPendingSize = 0; // 收完所需的包,置m_nPendingSize为0
  201. }
  202. else
  203. {
  204. int nTemp = nLen - nLinkHeaderLen; //除去头剩余部分的长度
  205. if ( nTemp > 0 ) //刚好是Header的长度,不用拷贝内存,所以这里加了>0的判断
  206. {
  207. memcpy( &pSH->m_PendingBuffer[ sizeof( ProtocolHeader ) ],
  208. & ( ( char *) pData )[ nLinkHeaderLen ],
  209. nTemp );
  210. }
  211. pSH->m_nPendingSize += nLen;
  212. }
  213. }
  214. else //这次还是没有收完包头, 继续Pending
  215. {
  216. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
  217. pSH->m_nPendingSize += nLen;
  218. nProcessedLen = nLen;
  219. }
  220. }
  221. else //Header部分已经在阻塞的缓冲区中
  222. {
  223. nProcessedLen = pHeader->nLen - pSH->m_nPendingSize;
  224. if ( nProcessedLen <= nLen ) //如果需要处理的长度小于现有包的长度
  225. {
  226. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nProcessedLen );
  227. pSH->m_nPendingSize = 0;
  228. }
  229. else //否则要继续阻塞
  230. {
  231. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
  232. pSH->m_nPendingSize += nLen;
  233. }
  234. }
  235. }
  236. else //第一次接包
  237. {
  238. pHeader = (ProtocolHeader *)&( (unsigned char *)pData )[nBuffIndex];
  239. if( nLen - nBuffIndex < sizeof(ProtocolHeader) ) // 没有收够包头,先记录当前收到的Buffer
  240. {
  241. //如果第一次接包就没有收够包头,认为是非法包,扔掉,就是说已处理的长度nProcessedLen = 0
  242. pSH->m_nPendingSize = nLen - nBuffIndex;
  243. memcpy(pSH->m_PendingBuffer, pHeader, pSH->m_nPendingSize);
  244. }
  245. else
  246. {
  247. nProcessedLen = pHeader->nLen;
  248. if( (int)pHeader->nLen > nLen - nBuffIndex )
  249. {
  250. memcpy(pSH->m_PendingBuffer, pHeader, nLen - nBuffIndex);
  251. //如果第一次接包,pHeader->nLen大于当前包的总长,认为是非法包,扔掉
  252. if( nBuffIndex == 0 )
  253. {
  254. //组包错误,则扔掉当前包
  255. TRACE("pHeader->nLen大于当前包的总长,认为是非法包,扔掉\r\n");
  256. break;
  257. }
  258. pSH->m_nPendingSize = nLen - nBuffIndex;
  259. nProcessedLen = nLen - nBuffIndex;
  260. }
  261. else
  262. {
  263. pSH->m_nPendingSize = 0;
  264. }
  265. }
  266. }
  267. if ( nProcessedLen == 0 )
  268. {
  269. // 没有收够包头,认为是非法包,扔掉
  270. TRACE("没有收够包头,认为是非法包,扔掉\r\n");
  271. break;
  272. }
  273. if ( pSH->m_nPendingSize == 0 )
  274. {
  275. if ( pHeader->nLen > SOCKET_BUFFSIZE )
  276. {
  277. // 包长度超过限制
  278. TRACE("pHeader->nLen超过限制\r\n");
  279. }
  280. if(-1 == OnCmdProcess( pHeader ))
  281. {
  282. //MessageBox( NULL, "Error OnCmdProcess", NULL, MB_OK );
  283. TRACE("crc校验错误!\r\n");
  284. break;
  285. }
  286. }
  287. nBuffIndex += nProcessedLen;
  288. }
  289. LeaveCriticalSection( &(pSH->m_hClient2SrvSection) );
  290. }
  291. //客户端调用
  292. DWORD WINAPI CTwoShipperSocket::SendHeartProc( CTwoShipperSocket *pWatchServer )
  293. {
  294. while((!pWatchServer->m_bHeartExit ))
  295. {
  296. ProtocolHeader PH;
  297. PH.nLen = 16;
  298. PH.nCmd = CMD_TWOSHIPPER_HEART;
  299. PH.nCmdType = 0;
  300. PH.Verify = pWatchServer->CalcCheckSum( (void *)&PH,16 );
  301. pWatchServer->DllC_SendDateToServer( (BYTE *)&PH,16 );
  302. Sleep(5000);
  303. }
  304. return 0;
  305. }
  306. //服务器调用
  307. DWORD WINAPI CTwoShipperSocket::CheckHeartProc( CTwoShipperSocket *pWatchServer )
  308. {
  309. while((!pWatchServer->m_bHeartExit ))
  310. {
  311. if( GetTickCount() - pWatchServer->m_dwServiceOnlineTick > 1 * 60 * 1000 ) //大于两分钟没有心跳包,认为已断线
  312. {
  313. if( pWatchServer->DllS_Ping( pWatchServer->m_sLocalGateway ) )
  314. {
  315. g_nRunModeForIOServer = 1;
  316. LOG4C_FUN( ("Start IOServer" ));
  317. }
  318. pWatchServer->m_dwServiceOnlineTick = GetTickCount();
  319. }
  320. Sleep(5000);
  321. }
  322. return 0;
  323. }