123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- #include "stdafx.h"
- #include ".\clientsocket.h"
- #include <comdef.h>
- #include <atlbase.h>
- #include "modbustcp.h"
- //#include "Client2SrvType.h"
- #pragma warning(push)
- #pragma warning(disable:4995)
- #pragma warning(pop)
- const int AF_IPV4 = 0;
- const int AF_IPV6 = 1;
- const int SOCK_TCP = SOCK_STREAM-1;
- const int SOCK_UDP = SOCK_DGRAM-1;
- CClientSocket::CClientSocket(void)
- {
- m_nMode = AF_IPV4;
- m_nSockType = SOCK_TCP;
- m_SocketClient.SetInterface(this);
- m_bSocket = FALSE;
- InitializeCriticalSection( &m_csReadFinished );
- //InitializeCriticalSection( &m_csWrFinished );
- MTVERIFY( m_hSemNet = CreateEvent( NULL, TRUE, TRUE, "ModbusAscNet" ) );
- }
- CClientSocket::~CClientSocket(void)
- {
- DeleteCriticalSection( &m_csReadFinished );
- //DeleteCriticalSection( &m_csWrFinished );
- MTVERIFY( CloseHandle( m_hSemNet ));
- }
- bool CClientSocket::GetDestination(SockAddrIn& addrIn) const
- {
- CString strIPAddress, strPort;
- int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
- return addrIn.CreateFrom(strIPAddress, strPort, nFamily);
- }
- int CClientSocket::ClientSend(char* pMsg, int iLen)
- {
- if ( m_SocketClient.IsOpen() )
- {
- if ( pMsg == NULL ) {
- return -1;
- }
- USES_CONVERSION;
- if (m_nSockType == SOCK_TCP)
- {
- return m_SocketClient.Write((const LPBYTE)(pMsg), iLen, NULL);
- }
- else
- {
- SockAddrIn sockAddr;
- GetDestination(sockAddr);
- m_SocketClient.Write((const LPBYTE)(pMsg), iLen, sockAddr);
- }
- }
- else
- {
- ;//MessageBox(_T("Socket is not connected"));
- }
- return 0;
- }
- BOOL CClientSocket::Connection(LPCTSTR strAddr, LPCTSTR strPort)
- {
- int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
- if ( !m_SocketClient.StartClient(NULL, strAddr, strPort, nFamily, (m_nSockType+1) ) )
- {
- //MessageBox(NULL, _T("连接服务器失败!"), "提示", MB_ICONSTOP);
- return FALSE;
- }
- else
- {
- CSocketHandle* pSH = (CSocketHandle *)m_SocketClient;
- InitializeCriticalSection(&pSH->m_hClient2SrvSection);
- pSH->m_nPendingSize = 0;
- memset(pSH->m_PendingBuffer, 0, SOCKET_BUFFSIZE);
- SetupMCAST();
- return TRUE;
- }
- }
- void CClientSocket::DisConnection()
- {
- #if 0
- if( m_bSocket == TRUE )
- {
- m_bSocket = FALSE;
- CSocketHandle* pSH = (CSocketHandle *)m_SocketClient;
- m_SocketClient.Terminate();
- }
- #endif
- m_SocketClient.Terminate();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // 实现ISocketClientHandler的通信方法
- void CClientSocket::OnThreadBegin(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketClient );
- (pSH);
- CString strAddr;
- SockAddrIn sockAddr;
- m_SocketClient->GetSockName(sockAddr);
- GetAddress( sockAddr, strAddr );
- //AppendText( _T("Client Running on: %s\r\n"), strAddr);
- }
- void CClientSocket::OnThreadExit(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketClient );
- (pSH);
- }
- void CClientSocket::OnDataReceived(CSocketHandle* pSH, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr)
- {
- ASSERT( pSH == m_SocketClient );
- (pSH);
- //if( !m_SocketClient->IsOpen() ) return;
- // ProcessData( pSH, pbData, dwCount );
- int nRet;
- nRet = OnCmdProcess( (void *)pbData, dwCount);
- if( nRet == -1 )
- {
- TRACE("crc32 error \r\n");
- }
- }
- void CClientSocket::OnConnectionDropped(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketClient );
- (pSH);
- TRACE(_T("======连接服务器断开.\r\n"));
-
- #if 0
- if( m_bSocket == TRUE )
- {
- m_SocketClient.Terminate();
- m_bSocket = FALSE;
- }
- #endif
- m_bSocket = FALSE;
- }
- void CClientSocket::OnConnectionError(CSocketHandle* pSH, DWORD dwError)
- {
- ASSERT( pSH == m_SocketClient );
- (pSH);
- _com_error err(dwError);
-
- #if 0
- if( m_bSocket == TRUE )
- {
- m_SocketClient.Terminate();
- m_bSocket = FALSE;
- }
- #endif
- m_bSocket = FALSE;
- }
- bool CClientSocket::SetupMCAST()
- {
- const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2");
- const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address
- bool result = false;
- if ( m_nSockType == SOCK_UDP )
- {
- if ( m_nMode == AF_IPV4 ) {
- result = m_SocketClient->AddMembership(szIPv4MCAST, NULL);
- } else {
- result = m_SocketClient->AddMembership(szIPv6MCAST, NULL);
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- hr = hr;
- }
- }
- return result;
- }
- void CClientSocket::GetAddress(const SockAddrIn& addrIn, CString& rString) const
- {
- TCHAR szIPAddr[MAX_PATH] = { 0 };
- CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn);
- rString.Format(_T("%s : %d"), szIPAddr, static_cast<int>(static_cast<UINT>(ntohs(addrIn.GetPort()))) );
- }
- void CClientSocket::ProcessData(CSocketHandle *pSH, const BYTE* pData, DWORD nLen)
- {
- DWORD nBuffIndex = 0;
- EnterCriticalSection( &(pSH->m_hClient2SrvSection) );
- while( nBuffIndex < nLen )
- {
- //ProtocolHeader *pHeader; //当前协议包头
- HEADER *pHeader;
- int iAllLen = 0;
- DWORD nProcessedLen = 0; //当前循环处理了多少个字节
- if( pSH->m_nPendingSize > 0 ) // 开始组包
- {
- pHeader = (HEADER *)pSH->m_PendingBuffer;
- iAllLen = htons(pHeader->ByteNum) + 6;
- if( pSH->m_nPendingSize < sizeof(HEADER) ) //上一次接收到的长度小于包头
- {
- DWORD nLinkHeaderLen = sizeof( HEADER ) - pSH->m_nPendingSize;
- if( nLinkHeaderLen <= nLen ) //这次可以收完包头
- {
- memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLinkHeaderLen );//这里已经收完Header
- nProcessedLen = iAllLen - pSH->m_nPendingSize;
- if( nProcessedLen <= nLen ) //如果所需处理的长度小于等于当前包长度
- {
- memcpy( &pSH->m_PendingBuffer[ sizeof( HEADER ) ],
- & ( ( char *) pData )[ nLinkHeaderLen ],
- iAllLen - sizeof( HEADER ) );
- pSH->m_nPendingSize = 0; // 收完所需的包,置m_nPendingSize为0
- }
- else
- {
- int nTemp = nLen - nLinkHeaderLen; //除去头剩余部分的长度
- if ( nTemp > 0 ) //刚好是Header的长度,不用拷贝内存,所以这里加了>0的判断
- {
- memcpy( &pSH->m_PendingBuffer[ sizeof( HEADER ) ],
- & ( ( char *) pData )[ nLinkHeaderLen ],
- nTemp );
- }
- pSH->m_nPendingSize += nLen;
- }
- }
- else //这次还是没有收完包头, 继续Pending
- {
- memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
- pSH->m_nPendingSize += nLen;
- nProcessedLen = nLen;
- }
- }
- else //Header部分已经在阻塞的缓冲区中
- {
- nProcessedLen = iAllLen - pSH->m_nPendingSize;
- if ( nProcessedLen <= nLen ) //如果需要处理的长度小于现有包的长度
- {
- memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nProcessedLen );
- pSH->m_nPendingSize = 0;
- }
- else //否则要继续阻塞
- {
- memcpy( &pSH->m_PendingBuffer[ pSH->m_nPendingSize ], pData, nLen );
- pSH->m_nPendingSize += nLen;
- }
- }
- }
- else //第一次接包
- {
- pHeader = (HEADER *)&( (unsigned char *)pData )[nBuffIndex];
- iAllLen = htons(pHeader->ByteNum) + 6;
- if( nLen - nBuffIndex < sizeof(HEADER) ) // 没有收够包头,先记录当前收到的Buffer
- {
- //如果第一次接包就没有收够包头,认为是非法包,扔掉,就是说已处理的长度nProcessedLen = 0
- pSH->m_nPendingSize = nLen - nBuffIndex;
- memcpy(pSH->m_PendingBuffer, pHeader, pSH->m_nPendingSize);
- }
- else
- {
- nProcessedLen = iAllLen;
- if( (int)iAllLen > nLen - nBuffIndex )
- {
- memcpy(pSH->m_PendingBuffer, pHeader, nLen - nBuffIndex);
- //如果第一次接包,pHeader->nLen大于当前包的总长,认为是非法包,扔掉
- if( 0 == nBuffIndex )
- {
- //组包错误,则扔掉当前包
- TRACE("iAllLen大于当前包的总长,认为是非法包,扔掉\r\n");
- break;
- }
- pSH->m_nPendingSize = nLen - nBuffIndex;
- nProcessedLen = nLen - nBuffIndex;
- }
- else
- {
- pSH->m_nPendingSize = 0;
- }
- }
- }
- if ( nProcessedLen == 0 )
- {
- // 没有收够包头,认为是非法包,扔掉
- TRACE("没有收够包头,认为是非法包,扔掉\r\n");
- break;
- }
- if ( pSH->m_nPendingSize == 0 )
- {
- if ( iAllLen > SOCKET_BUFFSIZE )
- {
- // 包长度超过限制
- TRACE("pHeader->nLen超过限制\r\n");
- }
- if(-1 == OnCmdProcess( pHeader, nLen))
- {
- //MessageBox( NULL, "Error OnCmdProcess", NULL, MB_OK );
- TRACE("crc校验错误!\r\n");
- break;
- }
- }
- nBuffIndex += nProcessedLen;
- }
- LeaveCriticalSection( &(pSH->m_hClient2SrvSection) );
- }
- int CClientSocket::OnCmdProcess(void *pData, int iDataLen)
- {
- HEADER TmpHeader = {0};
- char *pTmpData = new char[iDataLen];
- memcpy(pTmpData, pData, iDataLen);
- memcpy(&TmpHeader, pTmpData, sizeof(HEADER));
- switch(TmpHeader.FuncCode)
- {
- case 0x03://读数据应答
- ReadDataRes(pTmpData);
- break;
- case 0x10://写数据应答
- WriteDataRes(pTmpData);
- break;
-
- case (0x03 + 0x80)://读数据应答异常
- ReadDataResError(pTmpData);
- break;
- case 0x90://写数据应答异常
- WriteDataResError(pTmpData);
- break;
- default://错误的功能包
- return -1;
- }
- return 0;
- }
- int CClientSocket::ReadDataRes(char *pTmpData)
- {
- //EnterCriticalSection( &m_csReadFinished );
- RESPONSE_STRUCT ResponseStr = {0};
- int iHeadLen = sizeof(ResponseStr.Header);
- memcpy(&ResponseStr.Header, pTmpData, iHeadLen);
- memcpy(&ResponseStr.DataLen, pTmpData + iHeadLen, sizeof(ResponseStr.DataLen));
- if (ResponseStr.DataLen > 0)
- memcpy(&ResponseStr.StrRtnMsg, pTmpData + iHeadLen + 1, ResponseStr.DataLen);
- else
- return -1;
-
- ResponseStr.iVarlid = m_structResponse.iVarlid;
- m_structResponse = ResponseStr;
- //LeaveCriticalSection(&m_csReadFinished );
- SetEvent( m_hSemNet );
- return 0;
- }
- int CClientSocket::WriteDataRes(char *pTmpData)
- {
- return 0;
- }
- int CClientSocket::ReadDataResError(char *pTmpData)
- {
- FAILRESPONSE ResponseStr;
- memcpy(&ResponseStr, pTmpData, sizeof(FAILRESPONSE));
- return 0;
- }
- int CClientSocket::WriteDataResError(char *pTmpData)
- {
- return 0;
- }
- int CClientSocket::WorkMain(REQUESTPARAM SetBasePara, int iVarID)
- {
- if(!m_SocketClient)
- return ERR_CODE_MODBUS_TCP_NET_FAULT; // 端口通信故障
- int nRet;
- nRet = RequestStatus(SetBasePara,iVarID);
- if( nRet != 0 )
- {
- return nRet; // 端口忙
- }
- return nRet;
- }
- int CClientSocket::RequestStatus(REQUESTPARAM SetBasePara, int iVarID)
- {
- char TmpBuffer[32] = {0};
- int iLen = sizeof(REQUESTPARAM);
- memcpy(TmpBuffer, (char*)&SetBasePara, sizeof(REQUESTPARAM));
- if( WaitForSingleObject( m_hSemNet, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
- {
- ResetEvent( m_hSemNet );
- int nResult = ClientSend(TmpBuffer, sizeof(REQUESTPARAM));
-
- if( nResult == iLen )
- {
- ;
- }
- else
- {
- SetEvent( m_hSemNet );
- return EER_CODE_MODBUS_TCP_NET_WRITE_DATA;
- }
- }
- else
- {
- return ERR_CODE_MODBUS_TCP_NET_BUSY;
- }
- return 0;
- }
|