#include "StdAfx.h" #include "CellSocket.h" #include "IvrFlow.h" #include "FlowDataProvider.h" #include "MarkupSTL.h" using namespace std; IMPLEMENT_CELL_AUTOCREATE(CCellSocket, CELL_NAME_SOCKET) CCellSocket::CCellSocket(void) : m_FarPort(0), m_TimeOut(0), m_SuccessPos(0), m_FailPos(0) { } CCellSocket::CCellSocket( CCellSocket & cellSocket ) : CCellBase(cellSocket) { POSITION pos = cellSocket.m_InputVarList.GetHeadPosition(); while(pos != NULL) { InputVarInfo *pVarInfo = cellSocket.m_InputVarList.GetNext(pos); ASSERT(pVarInfo != NULL); InputVarInfo *pVarInfoTmp = new InputVarInfo(*pVarInfo); ASSERT(pVarInfoTmp != NULL); m_InputVarList.AddTail(pVarInfoTmp); } for (int i = 0; i < cellSocket.m_OutputVarList.GetSize(); ++i) { ASSERT(cellSocket.m_OutputVarList[i].GetLength() != 0); m_OutputVarList.Add(cellSocket.m_OutputVarList[i]); } m_OpType = cellSocket.m_OpType; m_FarAddr = cellSocket.m_FarAddr; m_FarPort = cellSocket.m_FarPort; m_TimeOut = cellSocket.m_TimeOut; m_SuccessPos = cellSocket.m_SuccessPos; m_FailPos = cellSocket.m_FailPos; } CCellSocket::~CCellSocket(void) { __release(); } /***************************************************************** **【函数名称】 __release **【函数功能】 释放资源 **【参数】 **【返回值】 ****************************************************************/ void CCellSocket::__release( void ) { while(!m_InputVarList.IsEmpty()) delete m_InputVarList.RemoveHead(); } /***************************************************************** **【函数名称】 __formatInputVar **【函数功能】 格式化输入字符串 **【参数】 **【返回值】 ****************************************************************/ int CCellSocket::__formatInputVar( char* InputText ) { CMarkupSTL XmlInput; XmlInput.AddElem(SOCKET_INPUT_PREFIX); XmlInput.AddAttrib(SOCKET_INPUT_OP_TYPE, m_OpType); int i = 1; CString VarName; CString VarValue; POSITION Pos = m_InputVarList.GetHeadPosition(); while(Pos != NULL) { InputVarInfo* pVarInfo = m_InputVarList.GetNext(Pos); ASSERT(pVarInfo != NULL); if(pVarInfo->VarType == CELL_DATA_VAR) { if(!m_pIvrFlow->findVarValue(pVarInfo->szVarValue, VarValue)) { CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错,变量[%s]未找到对应值"), Info, pVarInfo->szVarValue); } } else { VarValue = pVarInfo->szVarValue; } VarName.Format(_T("%s%d"), SOCKET_VAR_PREFIX, i++); XmlInput.AddChildElem(VarName, VarValue); } lstrcpy(InputText, XmlInput.GetDoc().c_str()); return XmlInput.GetDoc().length(); } /***************************************************************** **【函数名称】 __analyzeOutputVar **【函数功能】 解析输出字符串 **【参数】 **【返回值】 ****************************************************************/ bool CCellSocket::__analyzeOutputVar( char* OutputText ) { CMarkupSTL XmlOutput; if(!XmlOutput.SetDoc(OutputText)) { CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错,无法加载网络返回数据, Data = %s"), Info, OutputText); return false; } if(!XmlOutput.FindElem(SOCKET_OUTPUT_PREFIX)) { CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错,无法解析网络返回数据, Data = %s"), Info, OutputText); return false; } CString Element; Element = XmlOutput.GetAttrib(SOCKET_INPUT_OP_TYPE).c_str(); if(Element != m_OpType) { CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错,网络返回的操作类型[%s]与当前类型[%s]不匹配"), Info, Element, m_OpType); return false; } for(int i = 0; i < m_OutputVarList.GetSize(); ++i) { Element.Format(_T("%s%d"), SOCKET_VAR_PREFIX, i + 1); if(XmlOutput.FindChildElem(Element)) { XmlOutput.IntoElem(); m_pIvrFlow->addVar(m_OutputVarList[i], XmlOutput.GetData().c_str()); XmlOutput.OutOfElem(); } else { CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错,无法在网络数据中定位字段[%s], Data = %s"), Info, Element, OutputText); return false; } } return true; } /***************************************************************** **【函数名称】 __wait4Recv **【函数功能】 等候接收网络数据 **【参数】 **【返回值】 ****************************************************************/ bool CCellSocket::__wait4Recv(SOCKET Sock) { struct timeval tv; fd_set fds; FD_ZERO(&fds); FD_SET(Sock, &fds); tv.tv_sec = m_TimeOut; tv.tv_usec = 0; int res = select(0, &fds, NULL, NULL, &tv); if(res > 0) return FD_ISSET(Sock, &fds) > 0 ? true : false; else return false; } /***************************************************************** **【函数名称】 addInputVar **【函数功能】 添加输入变量 **【参数】 **【返回值】 ****************************************************************/ void CCellSocket::addInputVar( int VarType, const CString& VarVal ) { InputVarInfo *pInputVar = new InputVarInfo(VarType, VarVal); ASSERT(pInputVar != NULL); m_InputVarList.AddTail(pInputVar); } /***************************************************************** **【函数名称】 Operate **【函数功能】 节点执行函数 **【参数】 **【返回值】 下一个节点编号 ****************************************************************/ int CCellSocket::operate( void ) { if(m_pIvrFlow == NULL) return CELL_OP_ERROR; CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 开始执行[%s]"), Info); SOCKET Sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(Sock == INVALID_SOCKET) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 初始化套接字失败"), Info); return m_FailPos; } CHAR Buffer[VAR_LEN] = { 0 }; int Len = __formatInputVar(Buffer); SOCKADDR_IN AddrFar; AddrFar.sin_family = AF_INET; AddrFar.sin_port = htons(m_FarPort); inet_pton(AF_INET, m_FarAddr, &(AddrFar.sin_addr)); if(AddrFar.sin_addr.s_addr == INADDR_NONE) { hostent* pHost = gethostbyname(m_FarAddr); if(pHost == NULL) { closesocket(Sock); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 远端地址异常, FarAddr = %s"), Info, m_FarAddr); return m_FailPos; } memcpy((char*)&AddrFar.sin_addr, pHost->h_addr, pHost->h_length); } int AddrLen = sizeof(SOCKADDR); Len = sendto(Sock, Buffer, Len, 0, (SOCKADDR*)&AddrFar, AddrLen) ; if(Len == SOCKET_ERROR) { closesocket(Sock); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 发送通讯数据失败, ErrCode = %d"), Info, WSAGetLastError()); return m_FailPos; } if(!__wait4Recv(Sock)) { closesocket(Sock); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 接收数据超时"), Info); return m_FailPos; } ZeroMemory(Buffer, VAR_LEN); ZeroMemory(&AddrFar, sizeof(AddrFar)); Len = recvfrom(Sock, Buffer, VAR_LEN, 0, (SOCKADDR*)&AddrFar, &AddrLen); if(Len <= 0) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 接收数据失败, ErrCode = %d"), Info, WSAGetLastError()); closesocket(Sock); return m_FailPos; } closesocket(Sock); Buffer[Len] = 0; if(!__analyzeOutputVar(Buffer)) return m_FailPos; else return m_SuccessPos; } /***************************************************************** **【函数名称】 copy **【函数功能】 拷贝自身 **【参数】 **【返回值】 拷贝副本 ****************************************************************/ CCellBase * CCellSocket::copy( void ) { CCellBase *pCellBase = new CCellSocket(*this); return pCellBase; } /***************************************************************** **【函数名称】 fillData **【函数功能】 节点解析,填充数据 **【参数】 Provider:数据提供器 **【返回值】 成功true,失败false ****************************************************************/ bool CCellSocket::fillData( IFlowDataProvider& Provider ) { CString Data; do { if(!Provider.getData(CELL_ATTRIBUTE_POS, Data)) { Data = _T("节点号"); break; } else { sscanf_s(Data, _T("%d"), &m_Pos); if(m_Pos < 1) { Data = _T("节点号"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_OP_TYPE, m_OpType)) { Data = _T("操作类型标识"); break; } if(!Provider.getData(CELL_ATTRIBUTE_FAR_IP, m_FarAddr)) { Data = _T("远端IP"); break; } if(!Provider.getData(CELL_ATTRIBUTE_FAR_PORT, Data)) { Data = _T("远端端口"); break; } else { sscanf_s(Data, _T("%d"), &m_FarPort); if(m_FarPort <= 0) { Data = _T("远端端口"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_RECV_TIME_OUT, Data)) { Data = _T("接收超时"); break; } else { sscanf_s(Data, _T("%d"), &m_TimeOut); if(m_TimeOut <= 0) { Data = _T("接收超时"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_SUCCESS_POS, Data)) { Data = _T("成功跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_SuccessPos); if(m_SuccessPos < 0) { Data = _T("成功跳转节点"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_FAIL_POS, Data)) { Data = _T("失败跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_FailPos); if(m_FailPos < 0) { Data = _T("失败跳转节点"); break; } } Data.Format(_T("%s[@%s='%d']/%s"), XPATH_CELL, CELL_ATTRIBUTE_POS, m_Pos, FLOW_SUB_NODE_SOCK_INPUT); if(!Provider.getFlowSocketInputVar(Data, *this)) { Data = _T("输入变量"); break; } Data.Format(_T("%s[@%s='%d']/%s"), XPATH_CELL, CELL_ATTRIBUTE_POS, m_Pos, FLOW_SUB_NODE_SOCK_OUTPUT); if(!Provider.getDataSet(Data, CELL_ATTRIBUTE_VAR, m_OutputVarList)) { Data = _T("输出变量"); break; } Provider.getData(CELL_ATTRIBUTE_NOTE, m_Note); return true; } while (false); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Cell}: 节点[%s]解析失败, '%s'错误"), CELL_NAME_SOCKET, Data); return false; }