ClientSocket.cpp 11 KB

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