| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #include "stdafx.h"
- #include "NetLinkClient.h"
- #include "PduEntity.h"
- #include "PduEntityHead.h"
- #include "NetLinkMgr.h"
- CNetLinkClient::CNetLinkClient(CNetLinkMgr* a_pParent) : m_IsMainClient(false), m_pParent(a_pParent),m_FarEndIp(_T("")), m_FarEndPort(0)
- {
- // 清空SOCKET数据缓冲区
- __initBuffer();
- }
- CNetLinkClient::~CNetLinkClient( void )
- {
- Close();
- }
- // CNetLinkClient 成员函数
- /*****************************************************************
- **【函数名称】 __initBuffer
- **【函数功能】 清空SOCKET数据缓冲区
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetLinkClient::__initBuffer( void )
- {
- m_HasRead = 0; // 已读取的数据缓冲区长度
- memset(m_ReadBuffer, 0, PDU_HEAD_LEN + PDU_MAX_DATA_LEN); // 已读取的缓冲区内容
- }
- /*****************************************************************
- **【函数名称】 __sendBuffer
- **【函数功能】 发送数据缓冲区
- **【参数】 a_Buf[]: 内容
- a_BufLen: 长度
- **【返回值】
- ****************************************************************/
- bool CNetLinkClient::__sendBuffer( UCHAR a_Buf[], UINT a_BufLen )
- {
- UINT HasSend = 0;
- while(HasSend < a_BufLen)
- {
- int len = Send(&a_Buf[HasSend], a_BufLen - HasSend);
- switch(len)
- {
- case 0: // 连接已断开
- return false;
- case SOCKET_ERROR: // 发送失败
- if(GetLastError() != WSAEWOULDBLOCK)
- {
- return false;
- }
- Sleep(10); // 阻塞
- break;
- default:
- HasSend += len;
- break;
- } // end switch
- } // end while
- return true;
- }
- /*****************************************************************
- **【函数名称】 OnReceive
- **【函数功能】 消息接收事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetLinkClient::OnReceive( int ErrorCode )
- {
- // 读数据
- int nRead = Receive(&m_ReadBuffer[m_HasRead], PDU_HEAD_LEN + PDU_MAX_DATA_LEN - m_HasRead);
- if(nRead == SOCKET_ERROR)
- return;
- // 对接收的数据进行处理
- m_HasRead += nRead;
- // 如果已经接收到完整的包头
- while(m_HasRead > PDU_HEAD_LEN) // 有可能一次接收到多个完整命令
- {
- CPduEntityHead pduHead;
- // 解析PDU数据包头
- if(!pduHead.Decode(m_ReadBuffer))
- {
- __initBuffer(); // 如果解析失败,清除缓冲区
- break;
- } // end if
- // 如果数据包完整(HEAD + DATA)
- if(m_HasRead >= (PDU_HEAD_LEN + pduHead.GetDataLen()))
- {
- // 拷贝当前要处理的数据到临时缓冲区
- UCHAR szTmpBuf[PDU_MAX_DATA_LEN];
- ZeroMemory(szTmpBuf, PDU_MAX_DATA_LEN);
- memcpy_s(szTmpBuf, PDU_MAX_DATA_LEN, m_ReadBuffer, PDU_HEAD_LEN + pduHead.GetDataLen());
- // 清除已处理的数据(数据前移)
- m_HasRead = m_HasRead - (PDU_HEAD_LEN + pduHead.GetDataLen());
- memcpy(m_ReadBuffer, &m_ReadBuffer[PDU_HEAD_LEN + pduHead.GetDataLen()], m_HasRead);
- memset(&m_ReadBuffer[m_HasRead], 0, (PDU_HEAD_LEN + PDU_MAX_DATA_LEN - m_HasRead));
- // 对数据进行处理
- CPduEntity pduEntity(&pduHead, &szTmpBuf[PDU_HEAD_LEN]);
- pduEntity.assoClient() = this;
- ASSERT(m_pParent != NULL);
- m_pParent->onCmdRequest(this, &pduEntity);
- }
- else
- {
- break; // 如果当前数据不是一个完整数据包,退出循环
- } // end if
- } // end while
- CAsyncSocket::OnReceive(ErrorCode);
- }
- /*****************************************************************
- **【函数名称】 OnConnect
- **【函数功能】 消息连接事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetLinkClient::OnConnect( int ErrorCode )
- {
- GetPeerName(m_FarEndIp, m_FarEndPort);
- }
- /*****************************************************************
- **【函数名称】 OnClose
- **【函数功能】 关闭事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetLinkClient::OnClose( int ErrorCode )
- {
- // 必要操作
- Close();
- ASSERT(m_pParent != NULL);
- m_pParent->onClientDisconnect(this); // 连接断开
- CAsyncSocket::OnClose(ErrorCode);
- }
- /*****************************************************************
- **【函数名称】 send
- **【函数功能】 发送PDU命令
- **【参数】 a_Pdu: 要发送的命令
- **【返回值】
- ****************************************************************/
- bool CNetLinkClient::send( CPduEntity& a_Pdu )
- {
- a_Pdu.SetPeerDevInfo(m_PeerType, m_PeerId); // 填充接收方信息
- // 生成要发送的数据缓冲区
- UCHAR Buf[PDU_HEAD_LEN + PDU_MAX_DATA_LEN];
- ZeroMemory(Buf, PDU_HEAD_LEN + PDU_MAX_DATA_LEN);
- int nLen = a_Pdu.CreatePackge(Buf);
- // 发送
- return __sendBuffer(Buf, nLen);
- }
- /*****************************************************************
- **【函数名称】 setPeerInfo
- **【函数功能】 设置对端类型信息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetLinkClient::setPeerInfo( PDU_DEV_TYPE a_DevType, int a_DevId )
- {
- m_PeerType = a_DevType;
- m_PeerId = a_DevId;
- }
|