| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- // ..\..\..\Public\PduLink\PduSocket.cpp : 实现文件
- //
- #include "StdAfx.h"
- #include "PduSocket.h"
- #include "PduSocketMonitor.h"
- #include "PduMain.h"
- #include "PduEntity.h"
- #include "PduEntityHead.h"
- // CPduSocket
- CPduSocket::CPduSocket(CPduMain* a_pParent, PDU_LINK_TYPE a_nLinkType, bool IsAutoReconnect)
- {
- // 初始化监控信息
- m_pSocketMonitor = new CPduSocketMonitor(IsAutoReconnect);
- m_pSocketMonitor->SetLinkType(a_nLinkType); // 连接方式
- m_pParent = a_pParent;
- // 清空SOCKET数据缓冲区
- __InitData();
- }
- CPduSocket::~CPduSocket()
- {
- if(m_pSocketMonitor != NULL) delete m_pSocketMonitor;
- }
- /*****************************************************************
- **【函数名称】 __InitData
- **【函数功能】 清空SOCKET数据缓冲区
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::__InitData()
- {
- m_nHasRead = 0; // 已读取的数据缓冲区长度
- memset(m_szPdu, 0, PDU_HEAD_LEN + PDU_MAX_DATA_LEN); // 已读取的缓冲区内容
- }
- /*****************************************************************
- **【函数名称】 GetPeerLinkInfo
- **【函数功能】 读取SOCKET连接信息
- **【参数】
- **【返回值】 a_strIp SOCKET对端IP
- a_nPort SOCKET对端PORT
- ****************************************************************/
- void CPduSocket::GetPeerLinkInfo(CString& a_strIp, int& a_nPort)
- {
- m_pSocketMonitor->GetPeerLinkInfo(a_strIp, a_nPort);
- }
- /*****************************************************************
- **【函数名称】 GetLinkType
- **【函数功能】 得到连接类型
- **【参数】
- **【返回值】
- ****************************************************************/
- PDU_LINK_TYPE CPduSocket::GetLinkType()
- {
- return m_pSocketMonitor->GetLinkType();
- }
- /*****************************************************************
- **【函数名称】 GetPeerDevInfo
- **【函数功能】 读取对端设备信息
- **【参数】
- **【返回值】 a_nDevType 对端设备类型
- a_nDevId 对端设备ID
- ****************************************************************/
- void CPduSocket::GetPeerDevInfo(PDU_DEV_TYPE& a_nDevType, int& a_nDevId)
- {
- m_pSocketMonitor->GetPeerDevInfo(a_nDevType, a_nDevId);
- }
- /*****************************************************************
- **【函数名称】 SetPeerDevInfo
- **【函数功能】 设置对端设备信息
- **【参数】 a_nDevType 对端设备类型
- a_nDevId 对端设备ID
- **【返回值】
- ****************************************************************/
- void CPduSocket::SetPeerDevInfo(PDU_DEV_TYPE a_nDevType, int a_nDevId)
- {
- m_pSocketMonitor->SetPeerDevInfo(a_nDevType, a_nDevId);
- }
- /*****************************************************************
- **【函数名称】 GetLocalInfo
- **【函数功能】 设置本端设备信息
- **【参数】 a_nDevType 本端设备类型
- a_nDevId 本端设备ID
- **【返回值】
- ****************************************************************/
- void CPduSocket::GetLocalInfo(PDU_DEV_TYPE& a_nDevType, int& a_nDevId)
- {
- m_pParent->GetLocalInfo(a_nDevType,a_nDevId);
- }
- /*****************************************************************
- **【函数名称】 ConnectToServer
- **【函数功能】 连接到SERVER端
- **【参数】
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::ConnectToServer(const CString& a_strFarIp, int a_nFarPort, PDU_DEV_TYPE a_nFarType, int a_nFarId)
- {
- if(!Create()) return FALSE;
- // 设置监控信息
- m_pSocketMonitor->SetPeerLinkInfo(a_strFarIp, a_nFarPort);
- m_pSocketMonitor->SetPeerDevInfo(a_nFarType, a_nFarId);
- // 开始连接
- if(Connect(a_strFarIp, a_nFarPort) == 0)
- {
- return TRUE;
- }
- return FALSE;
- }
- /*****************************************************************
- **【函数名称】 Regist
- **【函数功能】 注册SOCKET连接
- **【参数】
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::Regist( void )
- {
- // 生成注册命令
- CPduEntity reg(PDU_CMD_REG);
- PDU_DEV_TYPE DevType = PDU_DEV_TYPE_UNKNOWN;
- int DevId = -1;
- m_pSocketMonitor->GetPeerDevInfo(DevType, DevId);
- reg.SetPeerDevInfo(DevType, DevId); // 填充接收方信息
- m_pParent->GetLocalInfo(DevType, DevId);
- reg.SetLocalDevInfo(DevType, DevId); // 填充发送方信息
- // 发送注册命令
- return SendDirectly(®);
- }
- /*****************************************************************
- **【函数名称】 Monitor
- **【函数功能】 发送心跳监听
- **【参数】
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::Monitor( void )
- {
- CPduEntity Monitor(PDU_CMD_LISTEN);
- PDU_DEV_TYPE DevType = PDU_DEV_TYPE_UNKNOWN;
- int DevId = -1;
- m_pSocketMonitor->GetPeerDevInfo(DevType, DevId);
- Monitor.SetPeerDevInfo(DevType, DevId); // 填充接收方信息
- m_pParent->GetLocalInfo(DevType, DevId);
- Monitor.SetLocalDevInfo(DevType, DevId); // 填充发送方信息
- // 发送心跳监听
- return SendDirectly(&Monitor);
- }
- /*****************************************************************
- **【函数名称】 SendDirectly
- **【函数功能】 发送PDU命令
- **【参数】 a_pCmd 要发送的命令实体
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::SendDirectly(CPduEntity* a_pCmd)
- {
- // 生成要发送的数据缓冲区
- UCHAR szBuf[PDU_HEAD_LEN + PDU_MAX_DATA_LEN];
- ZeroMemory(szBuf, PDU_HEAD_LEN + PDU_MAX_DATA_LEN);
- int nLen = a_pCmd->CreatePackge(szBuf);
- // 发送
- return __SendBuf(szBuf, nLen);
- }
- /*****************************************************************
- **【函数名称】 SendPdu
- **【函数功能】 发送PDU命令
- **【参数】 a_pCmd 要发送的命令实体
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::SendPdu( CPduEntity* a_pCmd )
- {
- PDU_DEV_TYPE DevType;
- int DevId;
- m_pSocketMonitor->GetPeerDevInfo(DevType, DevId);
- a_pCmd->SetPeerDevInfo(DevType, DevId);
- return SendDirectly(a_pCmd);
- }
- /*****************************************************************
- **【函数名称】 OnConnect
- **【函数功能】 连接状态事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnConnect(int nErrorCode)
- {
- if(nErrorCode == 0) // 连接建立
- {
- m_pParent->OnConnEstablished(this);
- }
- else // 连接失败
- {
- __InitData(); // 清空SOCKET数据缓冲区
- m_pParent->OnConnFailed(this);
- } // end if
- CAsyncSocket::OnConnect(nErrorCode);
- }
- /*****************************************************************
- **【函数名称】 OnClose
- **【函数功能】 关闭事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnClose(int nErrorCode)
- {
- // 必要操作
- Close();
- Create();
- // 清空SOCKET数据缓冲区
- __InitData();
- m_pParent->OnConnFailed(this); // 连接断开
- CAsyncSocket::OnClose(nErrorCode);
- }
- /*****************************************************************
- **【函数名称】 OnReceive
- **【函数功能】 消息接收事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnReceive(int nErrorCode)
- {
- // 读数据
- int nRead = Receive(&m_szPdu[m_nHasRead], PDU_HEAD_LEN + PDU_MAX_DATA_LEN - m_nHasRead);
- if(nRead == SOCKET_ERROR) return;
- // 对接收的数据进行处理
- m_nHasRead += nRead;
- // 如果已经接收到完整的包头
- while(m_nHasRead > PDU_HEAD_LEN) // 有可能一次接收到多个完整命令
- {
- CPduEntityHead pduHead;
- // 解析PDU数据包头
- if(!pduHead.Decode(m_szPdu))
- {
- __InitData(); // 如果解析失败,清除缓冲区
- break;
- } // end if
- // 如果数据包完整(HEAD + DATA)
- if(m_nHasRead >= (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_szPdu, PDU_HEAD_LEN + pduHead.GetDataLen());
- // 清除已处理的数据(数据前移)
- m_nHasRead = m_nHasRead - (PDU_HEAD_LEN + pduHead.GetDataLen());
- memcpy(m_szPdu, &m_szPdu[PDU_HEAD_LEN + pduHead.GetDataLen()], m_nHasRead);
- memset(&m_szPdu[m_nHasRead], 0, (PDU_HEAD_LEN + PDU_MAX_DATA_LEN - m_nHasRead));
- // 对数据进行处理
- CPduEntity pduEntity(&pduHead, &szTmpBuf[PDU_HEAD_LEN]);
- pduEntity.SetAssoSocket(m_hSocket);
- m_pParent->OnRecvCommand(&pduEntity);
- }
- else
- {
- break; // 如果当前数据不是一个完整数据包,退出循环
- } // end if
- } // end while
- CAsyncSocket::OnReceive(nErrorCode);
- }
- /*****************************************************************
- **【函数名称】 OnSend
- **【函数功能】 消息发送事件
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnSend(int nErrorCode)
- {
- // TODO: 在此添加专用代码和/或调用基类
- CAsyncSocket::OnSend(nErrorCode);
- }
- /*****************************************************************
- **【函数名称】 __SendBuf
- **【函数功能】 发送数据缓冲区
- **【参数】 a_szBuf[] 内容
- a_nBufLen 长度
- **【返回值】
- ****************************************************************/
- BOOL CPduSocket::__SendBuf(UCHAR a_szBuf[], UINT a_nBufLen)
- {
- UINT nHasSend = 0;
- while(nHasSend < a_nBufLen)
- {
- int nSend = Send(&a_szBuf[nHasSend], a_nBufLen - nHasSend);
- if(nSend > 0)
- {
- nHasSend += nSend;
- }
- else
- {
- if(GetLastError() == WSAEWOULDBLOCK) // 阻塞
- Sleep(10);
- else
- return FALSE;
- }
- }
- return TRUE;
- }
- /*****************************************************************
- **【函数名称】 OnConnEstablisthed
- **【函数功能】 SOCKET连接建立事件处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnConnEstablished()
- {
- return m_pSocketMonitor->OnConnEstablisthed(this);
- }
- /*****************************************************************
- **【函数名称】 OnConnFailed
- **【函数功能】 SOCKET连接断开/失败事件处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnConnFailed()
- {
- return m_pSocketMonitor->OnConnFailed(this);
- }
- /*****************************************************************
- **【函数名称】 OnConnRegistOK
- **【函数功能】 SOCKET连接注册成功事件处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnConnRegistOK()
- {
- return m_pSocketMonitor->OnConnRegistOK(this);
- }
- /*****************************************************************
- **【函数名称】 OnConnRegistFailed
- **【函数功能】 SOCKET连接注册失败事件处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CPduSocket::OnConnRegistFailed()
- {
- return m_pSocketMonitor->OnConnRegistFailed(this);
- }
|