ClientSocket.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. #include "stdafx.h"
  2. #include ".\clientsocket.h"
  3. #include <comdef.h>
  4. #include <atlbase.h>
  5. #include "modbustcp.h"
  6. //#include "Client2SrvType.h"
  7. #pragma warning(push)
  8. #pragma warning(disable:4995)
  9. #pragma warning(pop)
  10. const int AF_IPV4 = 0;
  11. const int AF_IPV6 = 1;
  12. const int SOCK_TCP = SOCK_STREAM-1;
  13. const int SOCK_UDP = SOCK_DGRAM-1;
  14. CClientSocket::CClientSocket(void)
  15. {
  16. m_nMode = AF_IPV4;
  17. m_nSockType = SOCK_TCP;
  18. m_SocketClient.SetInterface(this);
  19. m_bSocket = FALSE;
  20. #if IS_USE_EVENT
  21. MTVERIFY( m_hSemNet = CreateEvent( NULL, TRUE, TRUE, 0 ) );
  22. #endif
  23. MTVERIFY (m_hRunObject = ::CreateEvent(
  24. NULL, /* Security */
  25. TRUE, /* Manual event */
  26. 0, /* Clear on creation */
  27. "modbusTcp::m_hRunObject"));
  28. //InitializeCriticalSection( &m_csWrFinished );
  29. }
  30. CClientSocket::~CClientSocket(void)
  31. {
  32. if( m_hRunObject != NULL )
  33. {
  34. MTVERIFY( CloseHandle( m_hRunObject ) );
  35. m_hRunObject = NULL;
  36. }
  37. #if IS_USE_EVENT
  38. if( m_hSemNet != NULL )
  39. {
  40. MTVERIFY( CloseHandle( m_hSemNet ));
  41. m_hSemNet = NULL;
  42. }
  43. #endif
  44. //DeleteCriticalSection( &m_csWrFinished );
  45. }
  46. bool CClientSocket::GetDestination(SockAddrIn& addrIn) const
  47. {
  48. CString strIPAddress, strPort;
  49. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  50. return addrIn.CreateFrom(strIPAddress, strPort, nFamily);
  51. }
  52. int CClientSocket::ClientSend(char* pMsg, int iLen)
  53. {
  54. if ( m_SocketClient.IsOpen() )
  55. {
  56. if ( pMsg == NULL ) {
  57. return -1;
  58. }
  59. USES_CONVERSION;
  60. if (m_nSockType == SOCK_TCP)
  61. {
  62. return m_SocketClient.Write((const LPBYTE)(pMsg), iLen, NULL);
  63. }
  64. else
  65. {
  66. SockAddrIn sockAddr;
  67. GetDestination(sockAddr);
  68. m_SocketClient.Write((const LPBYTE)(pMsg), iLen, sockAddr);
  69. }
  70. }
  71. else
  72. {
  73. ;//MessageBox(_T("Socket is not connected"));
  74. }
  75. return 0;
  76. }
  77. BOOL CClientSocket::Connection(LPCTSTR strAddr, LPCTSTR strPort)
  78. {
  79. int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
  80. if ( !m_SocketClient.StartClient(NULL, strAddr, strPort, nFamily, (m_nSockType+1) ) )
  81. {
  82. //MessageBox(NULL, _T("连接服务器失败!"), "提示", MB_ICONSTOP);
  83. return FALSE;
  84. }
  85. else
  86. {
  87. CSocketHandle* pSH = (CSocketHandle *)m_SocketClient;
  88. pSH->m_nPendingSize = 0;
  89. memset(pSH->m_PendingBuffer, 0, SOCKET_BUFFSIZE);
  90. SetupMCAST();
  91. return TRUE;
  92. }
  93. }
  94. void CClientSocket::DisConnection()
  95. {
  96. m_SocketClient.Terminate();
  97. }
  98. ///////////////////////////////////////////////////////////////////////////////
  99. // 实现ISocketClientHandler的通信方法
  100. void CClientSocket::OnThreadBegin(CSocketHandle* pSH)
  101. {
  102. ASSERT( pSH == m_SocketClient );
  103. (pSH);
  104. CString strAddr;
  105. SockAddrIn sockAddr;
  106. m_SocketClient->GetSockName(sockAddr);
  107. GetAddress( sockAddr, strAddr );
  108. InitializeCriticalSection(&pSH->m_hClient2SrvSection);
  109. //AppendText( _T("Client Running on: %s\r\n"), strAddr);
  110. }
  111. void CClientSocket::OnThreadExit(CSocketHandle* pSH)
  112. {
  113. ASSERT( pSH == m_SocketClient );
  114. DeleteCriticalSection( &pSH->m_hClient2SrvSection );
  115. (pSH);
  116. }
  117. void CClientSocket::OnDataReceived(CSocketHandle* pSH, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr)
  118. {
  119. ASSERT( pSH == m_SocketClient );
  120. (pSH);
  121. if( !m_SocketClient->IsOpen() ) return;
  122. //ProcessData( pSH, pbData, dwCount );
  123. int nRet;
  124. nRet = OnCmdProcess( (void *)pbData, dwCount);
  125. if( nRet == -1 )
  126. {
  127. TRACE("crc32 error \r\n");
  128. }
  129. }
  130. void CClientSocket::OnConnectionDropped(CSocketHandle* pSH)
  131. {
  132. ASSERT( pSH == m_SocketClient );
  133. (pSH);
  134. TRACE(_T("======连接服务器断开.\r\n"));
  135. m_bSocket = FALSE;
  136. }
  137. void CClientSocket::OnConnectionError(CSocketHandle* pSH, DWORD dwError)
  138. {
  139. ASSERT( pSH == m_SocketClient );
  140. (pSH);
  141. _com_error err(dwError);
  142. m_bSocket = FALSE;
  143. }
  144. bool CClientSocket::SetupMCAST()
  145. {
  146. const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2");
  147. const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address
  148. bool result = false;
  149. if ( m_nSockType == SOCK_UDP )
  150. {
  151. if ( m_nMode == AF_IPV4 ) {
  152. result = m_SocketClient->AddMembership(szIPv4MCAST, NULL);
  153. } else {
  154. result = m_SocketClient->AddMembership(szIPv6MCAST, NULL);
  155. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  156. hr = hr;
  157. }
  158. }
  159. return result;
  160. }
  161. void CClientSocket::GetAddress(const SockAddrIn& addrIn, CString& rString) const
  162. {
  163. TCHAR szIPAddr[MAX_PATH] = { 0 };
  164. CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn);
  165. rString.Format(_T("%s : %d"), szIPAddr, static_cast<int>(static_cast<UINT>(ntohs(addrIn.GetPort()))) );
  166. }
  167. void CClientSocket::ProcessData(CSocketHandle *pSH, const BYTE* pData, DWORD nLen)
  168. {
  169. DWORD nBuffIndex = 0;
  170. EnterCriticalSection( &(pSH->m_hClient2SrvSection) );
  171. while( nBuffIndex < nLen )
  172. {
  173. //ProtocolHeader *pHeader; //当前协议包头
  174. HEADER *pHeader;
  175. int iAllLen = 0;
  176. DWORD nProcessedLen = 0; //当前循环处理了多少个字节
  177. if( pSH->m_nPendingSize > 0 ) // 开始组包
  178. {
  179. pHeader = (HEADER *)pSH->m_PendingBuffer;
  180. iAllLen = htons(pHeader->ByteNum) + 6;
  181. if( pSH->m_nPendingSize < sizeof(HEADER) ) //上一次接收到的长度小于包头
  182. {
  183. DWORD nLinkHeaderLen = sizeof( HEADER ) - pSH->m_nPendingSize;
  184. if( nLinkHeaderLen <= nLen ) //这次可以收完包头
  185. {
  186. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLinkHeaderLen );//这里已经收完Header
  187. nProcessedLen = iAllLen - pSH->m_nPendingSize;
  188. if( nProcessedLen <= nLen ) //如果所需处理的长度小于等于当前包长度
  189. {
  190. memcpy( &pSH->m_PendingBuffer[ sizeof( HEADER ) ],
  191. & ( ( char *) pData )[ nLinkHeaderLen ],
  192. iAllLen - sizeof( HEADER ) );
  193. pSH->m_nPendingSize = 0; // 收完所需的包,置m_nPendingSize为0
  194. }
  195. else
  196. {
  197. int nTemp = nLen - nLinkHeaderLen; //除去头剩余部分的长度
  198. if ( nTemp > 0 ) //刚好是Header的长度,不用拷贝内存,所以这里加了>0的判断
  199. {
  200. memcpy( &pSH->m_PendingBuffer[ sizeof( HEADER ) ],
  201. & ( ( char *) pData )[ nLinkHeaderLen ],
  202. nTemp );
  203. }
  204. pSH->m_nPendingSize += nLen;
  205. }
  206. }
  207. else //这次还是没有收完包头, 继续Pending
  208. {
  209. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
  210. pSH->m_nPendingSize += nLen;
  211. nProcessedLen = nLen;
  212. }
  213. }
  214. else //Header部分已经在阻塞的缓冲区中
  215. {
  216. nProcessedLen = iAllLen - pSH->m_nPendingSize;
  217. if ( nProcessedLen <= nLen ) //如果需要处理的长度小于现有包的长度
  218. {
  219. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nProcessedLen );
  220. pSH->m_nPendingSize = 0;
  221. }
  222. else //否则要继续阻塞
  223. {
  224. memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
  225. pSH->m_nPendingSize += nLen;
  226. }
  227. }
  228. }
  229. else //第一次接包
  230. {
  231. pHeader = (HEADER *)&( (unsigned char *)pData )[nBuffIndex];
  232. iAllLen = htons(pHeader->ByteNum) + 6;
  233. if( nLen - nBuffIndex < sizeof(HEADER) ) // 没有收够包头,先记录当前收到的Buffer
  234. {
  235. //如果第一次接包就没有收够包头,认为是非法包,扔掉,就是说已处理的长度nProcessedLen = 0
  236. pSH->m_nPendingSize = nLen - nBuffIndex;
  237. memcpy(pSH->m_PendingBuffer, pHeader, pSH->m_nPendingSize);
  238. }
  239. else
  240. {
  241. nProcessedLen = iAllLen;
  242. if( iAllLen > (int)(nLen - nBuffIndex) )
  243. {
  244. memcpy(pSH->m_PendingBuffer, pHeader, nLen - nBuffIndex);
  245. //如果第一次接包,pHeader->nLen大于当前包的总长,认为是非法包,扔掉
  246. if( 0 == nBuffIndex )
  247. {
  248. //组包错误,则扔掉当前包
  249. TRACE("iAllLen大于当前包的总长,认为是非法包,扔掉\r\n");
  250. break;
  251. }
  252. pSH->m_nPendingSize = nLen - nBuffIndex;
  253. nProcessedLen = nLen - nBuffIndex;
  254. }
  255. else
  256. {
  257. pSH->m_nPendingSize = 0;
  258. }
  259. }
  260. }
  261. if ( nProcessedLen == 0 )
  262. {
  263. // 没有收够包头,认为是非法包,扔掉
  264. TRACE("没有收够包头,认为是非法包,扔掉\r\n");
  265. break;
  266. }
  267. if ( pSH->m_nPendingSize == 0 )
  268. {
  269. if ( iAllLen > SOCKET_BUFFSIZE )
  270. {
  271. // 包长度超过限制
  272. TRACE("pHeader->nLen超过限制\r\n");
  273. }
  274. if(-1 == OnCmdProcess( pHeader, nLen))
  275. {
  276. //MessageBox( NULL, "Error OnCmdProcess", NULL, MB_OK );
  277. TRACE("crc校验错误!\r\n");
  278. break;
  279. }
  280. }
  281. nBuffIndex += nProcessedLen;
  282. }
  283. LeaveCriticalSection( &(pSH->m_hClient2SrvSection) );
  284. }
  285. int CClientSocket::OnCmdProcess(void *pData, int iDataLen)
  286. {
  287. HEADER TmpHeader = {0};
  288. char *pTmpData = new char[iDataLen];
  289. memcpy(pTmpData, pData, iDataLen);
  290. memcpy(&TmpHeader, pTmpData, sizeof(HEADER));
  291. switch(TmpHeader.FuncCode)
  292. {
  293. case 0x03://读数据应答
  294. ReadDataRes(pTmpData);
  295. break;
  296. case 0x10://写数据应答
  297. WriteDataRes(pTmpData);
  298. break;
  299. case (0x03 + 0x80)://读数据应答异常
  300. ReadDataResError(pTmpData);
  301. break;
  302. case 0x90://写数据应答异常
  303. WriteDataResError(pTmpData);
  304. break;
  305. default://错误的功能包
  306. if( pTmpData )
  307. {
  308. delete[] pTmpData;
  309. pTmpData = NULL;
  310. }
  311. return -1;
  312. }
  313. if( pTmpData )
  314. {
  315. delete[] pTmpData;
  316. pTmpData = NULL;
  317. }
  318. return 0;
  319. }
  320. int CClientSocket::ReadDataRes(char *pTmpData)
  321. {
  322. RESPONSE_STRUCT ResponseStr = {0};
  323. int iHeadLen = sizeof(ResponseStr.Header);
  324. memcpy(&ResponseStr.Header, pTmpData, iHeadLen);
  325. memcpy(&ResponseStr.DataLen, pTmpData + iHeadLen, sizeof(ResponseStr.DataLen));
  326. if (ResponseStr.DataLen > 0)
  327. {
  328. memcpy(&ResponseStr.StrRtnMsg, pTmpData + iHeadLen + 1, ResponseStr.DataLen);
  329. ResponseStr.nReadResult = 1;
  330. m_structResponse = ResponseStr;
  331. //TRACE("DataLen1 = %d\r\n", m_structResponse.DataLen);
  332. }
  333. else
  334. {
  335. ResponseStr.nReadResult = 0;
  336. m_structResponse = ResponseStr;
  337. //TRACE("返回数据长度=%d\r\n", ResponseStr.DataLen);
  338. return -1;
  339. }
  340. int nValue;
  341. WORD wdValue;
  342. memcpy(&wdValue, ResponseStr.StrRtnMsg, sizeof(WORD));
  343. //wdValue = htons(wdValue);
  344. nValue = htons(wdValue);
  345. //TRACE(">>>>>>>>>结束请求,数据内容=%d\r\n", nValue);
  346. #if IS_USE_EVENT
  347. SetEvent( m_hSemNet );
  348. #endif
  349. return 0;
  350. }
  351. int CClientSocket::WriteDataRes(char *pTmpData)
  352. {
  353. memcpy(&m_structWriteResponse, pTmpData, sizeof(WRITESUCCESSRESPONSE));
  354. #if IS_USE_EVENT
  355. SetEvent( m_hSemNet );
  356. #endif
  357. return 0;
  358. }
  359. int CClientSocket::ReadDataResError(char *pTmpData)
  360. {
  361. FAILRESPONSE ResponseStr;
  362. memcpy(&ResponseStr, pTmpData, sizeof(FAILRESPONSE));
  363. TRACE("读数据错误\r\n");
  364. return 0;
  365. }
  366. int CClientSocket::WriteDataResError(char *pTmpData)
  367. {
  368. return 0;
  369. }
  370. int CClientSocket::WorkMain(REQUESTPARAM SetBasePara)
  371. {
  372. if(!m_SocketClient)
  373. {
  374. TRACE("打开端口错误\r\n");
  375. return ERR_CODE_MODBUS_TCP_NET_FAULT; // 端口通信故障
  376. }
  377. int nRet;
  378. nRet = RequestStatus(&SetBasePara, sizeof(REQUESTPARAM));
  379. if( nRet != 0 )
  380. {
  381. return nRet; // 端口忙
  382. }
  383. return nRet;
  384. }
  385. int CClientSocket::Write(REQUESTWRPARAM writeParam)
  386. {
  387. if(!m_SocketClient)
  388. {
  389. TRACE("打开端口错误\r\n");
  390. return ERR_CODE_MODBUS_TCP_NET_FAULT; // 端口通信故障
  391. }
  392. int nRet;
  393. nRet = RequestStatus(&writeParam, sizeof(REQUESTWRPARAM) - sizeof(writeParam.nWriteResult));
  394. if( nRet != 0 )
  395. {
  396. return nRet; // 端口忙
  397. }
  398. return nRet;
  399. }
  400. int CClientSocket::RequestStatus(void *pData, int nLen)
  401. {
  402. //int iLen = sizeof(REQUESTPARAM);
  403. //TRACE("开始请求一个变量数据\r\n");
  404. //TRACE("开始请求寄存器起始地址=%d\r\n", htons(SetBasePara.StartAddr));
  405. #if IS_USE_EVENT
  406. if( WaitForSingleObject( m_hSemNet, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
  407. {
  408. ResetEvent( m_hSemNet );
  409. #endif
  410. int nResult = ClientSend((char *)pData, nLen);
  411. if( nResult == nLen )
  412. {
  413. ;
  414. }
  415. else
  416. {
  417. #if IS_USE_EVENT
  418. SetEvent( m_hSemNet );
  419. #endif
  420. TRACE("发送数据错误\r\n");
  421. return EER_CODE_MODBUS_TCP_NET_WRITE_DATA;
  422. }
  423. #if IS_USE_EVENT
  424. }
  425. else
  426. {
  427. return ERR_CODE_MODBUS_TCP_NET_BUSY;
  428. }
  429. #endif
  430. return 0;
  431. }
  432. DWORD WINAPI CClientSocket::ReConnectSrvThread( void *pData )
  433. {
  434. CClientSocket *pClientSocket = (CClientSocket *)pData;
  435. do
  436. {
  437. if( pClientSocket->m_bSocket == FALSE )
  438. {
  439. if ( pClientSocket->m_SocketClient.IsOpen() )
  440. {
  441. pClientSocket->DisConnection();
  442. }
  443. char chNetPort[8] = {0};
  444. itoa(pClientSocket->m_nNetPort, chNetPort, 10);
  445. if( !pClientSocket->Connection(pClientSocket->m_chIpAddr, chNetPort) )
  446. {
  447. pClientSocket->m_bSocket = FALSE;
  448. }
  449. else
  450. {
  451. pClientSocket->m_bSocket = TRUE;
  452. }
  453. }
  454. }while( WaitForSingleObject( pClientSocket->m_hRunObject, 125L ) == WAIT_TIMEOUT );
  455. return 0;
  456. }