




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
使用C+ Builder封装Tuxedo客户端调用本文主要介绍如何使用C+ Builder把Tuxedo客户端的调用封装成一个独立的类CTuxCall,最大程度的方便用户调用tuxedo,并给出相应的例子,以供参考.由于是第一次发表这样的文章,其中不足之处,还望大家予以批评指正。 类CTuxCall的特点 封装后的类CTuxCall有如下一些特点,能够最大程度的满足用户的需求,方便用户的调用. (1) 可以自定义连接方式,长连接,短连接和混合连接(由用户自定义连接次数,当实际的连接次数超过自定义的连接次数,则自动断开连接,然后重连); (2) 可以自动切换连接地址,目前提供了5个备用地址,只要其中有一个地址上的服务是正常的,则Tuxedo的连接就是正常的; (3) 能够方便的设置客户端的信息,如操作员名称,操作员IP地址,或者操作员当前操作状态; (4) 调用方式简单,灵活,可扩充性好. 类CTuxCall函数说明 (1) 设置客户端信息,在这里你可以设置操作员或者终端,甚至是一些操作状态的信息: void SetClientInfo(char* username,char* ctlname); 使用该函数后,在服务器的管理平台,使用pclt命令,就会显示客户端的相关 信息,如: LMID User Name Client Name Time Status Bgn/Cmmt/Abrt - - - - - - szx1app tuxedo WSH 21:54:08 IDLE 0/0/0 szx1app oper01 192.168.1.114 0:18:15 IDLE/W 0/0/0 (2) 设置连接方式: bool SetConnectType(int contype); (3) 设置监听地址: bool SetWSNAddr(char* addrlist); 参数格式如下: /ip1:port1;/ip2:port2;.;/ip5:port5 ,最多支持5个IP地址. (4) 服务调用: Invoke();在客户端编写代码,只要调用这个函数即可.关于这个函数 有几个不同的函数原形,具体如下: bool Invoke(char * OpCode,.); 指定操作码,调用确省服务,参数个数不定,至于如何把传入的参数一定的格式 写入到发送缓冲去,需要调用自定义的函数进行打包. bool Invoke(char* SrvName,char* OpCode,.); 大体内容同上,只是调用的是指定的服务,而不是确省的服务. bool Invoke(char* SrvName,long InLen,long &OutLen); 在使用此函数之前,必须保证先调用SetSendBuf()函数填充发送缓冲区. bool Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr, long &OutLen,int flag = 0); 调用指定服务,输入参数和返回结果都由用户自定. (5) 填充发送缓冲区:int SetSendBuf(char *szFormat,.); 该函数用法同c语言的printf()函数,只是发送缓冲区的长度有限制,最好不要超过1024*10个字节. 源码分析 类CTuxCall的源码 TuxCall头文件 /- #ifndef TuxCallH #define TuxCallH /- #if defined(_BORLANDC_)&!defined(SOCKET_CONNECT) /#pragma comment (lib,libtux.lib) /#pragma comment (lib,libbuft.lib) /#pragma comment (lib,libfml.lib) /#pragma comment (lib,libfml32.lib) /#pragma comment (lib,libengine.lib) #endif #define TRANSMITER TRANSMIT class CTuxCall private: char * m_RecBuff; char * m_SendBuff; char ErrMsg1024; void ClearBuffer(); int m_Errno; bool m_bBeginTrans; int m_ConnectionType; /连接方式:0:长连接,1:短连接;m(m10):m次调用后自动断开连接,并自动重连 int m_ConCount; /服务调用计数器 char m_UserName64; char m_CtrName64; char m_WSNAddrList564; char m_CurWSNADDR64; bool m_bInConnection; /是否正处在连接之中 bool CheckWSNADDRValid(char* ipstr,char* port); char * GetErrMsg(char * ATitle,char * AMsg=); bool AllocSrc(int size); bool AllocDest(int size); char m_EscapeFlag; int m_Col; /返回结果每条记录的字段数 long m_Row; /返回结果的记录数 char m_ColSep5; / 字段间的分隔符 char m_RowSep5; / 记录间的分隔符 public: CTuxCall(); CTuxCall(); void SetClientInfo(char* username,char* ctlname); bool SetConnectType(int contype); bool SetWSNAddr(char* addrlist); / addrlist=/ip1:port1;/ip2:port2;.;/ip5:port5 最多支持5个IP地址. void Disconnect(); bool Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr, long &OutLen,int flag = 0); bool Invoke(char * OpCode,.); bool Invoke(char* SrvName,char* OpCode,.); bool Invoke(char* SrvName,long InLen,long &OutLen); bool BeginTransaction(unsigned long timeout=120); bool Rollback(); bool Commit(); bool TuxInit(); bool TuxTerm(); char *GetErrorMessage(); char *GetCurWSNAddr(); char *GetResultData(); int SetSendBuf(char *szFormat,.); /总字符串的长度不超过1024*10个字节. ; #endif CTuxCall的实现 #pragma hdrstop #include TuxCall.h #ifndef _TM_WIN #define _TM_WIN #endif #include atmi.h #include stdio.h #include #include #ifndef _NOAUTOLIB #ifndef _NOAUTOMSG #pragma message( Will automatically link with libbuft.lib ) #endif #pragma comment(lib, libbuft.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libnwi.lib ) #endif #pragma comment(lib, libnwi.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libnws.lib ) #endif #pragma comment(lib, libnws.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libwsc.lib ) #endif #pragma comment(lib, libwsc.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libfml.lib ) #endif #pragma comment(lib, libfml.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libfml32.lib ) #endif #pragma comment(lib, libfml32.lib) #ifndef _NOAUTOMSG #pragma message( Will automatically link with libgp.lib ) #endif #pragma comment(lib, libgp.lib) #endif /- CTuxCall:CTuxCall() m_bBeginTrans = false; m_ConnectionType = 0; m_ConCount = 0; m_bInConnection = false; memset(m_WSNAddrList,0,sizeof(m_WSNAddrList); m_RecBuff=NULL; m_SendBuff=NULL; m_Row =0; m_Col =0; m_EscapeFlag = ; memset(m_ColSep,0,sizeof(m_ColSep); strcpy(m_ColSep,#); memset(m_RowSep,0,sizeof(m_ColSep); strcpy(m_RowSep,); CTuxCall:CTuxCall() if(m_RecBuff) tpfree(m_RecBuff); if(m_SendBuff) tpfree(m_SendBuff); tpterm(); m_RecBuff = NULL; m_SendBuff = NULL; char * CTuxCall:GetErrMsg(char * ATitle,char * AMsg) if(strlen(AMsg)!=0) sprintf(ErrMsg,%sn错误代码:%dn错误信息:%s,ATitle,m_Errno,AMsg); else sprintf(ErrMsg,%sn错误代码:%dn错误信息:%s,ATitle,tperrno,tpstrerror(tperrno); return ErrMsg; bool CTuxCall:SetWSNAddr(char* addrlist) /addrlist的格式: /IP1:PORT1;/IP2:PORT2;/IP3:PORT3;. char tmpAddr64*5=0; char ipstr32=0; char port16=0; int nPos = 0; int iPos = 0; char *ptr=NULL; memset(m_WSNAddrList,0,sizeof(m_WSNAddrList); memset(tmpAddr,0,sizeof(tmpAddr); strncpy(tmpAddr, addrlist,64*5); int i=0; while (iusrname,m_UserName); strcpy(tpinitbuf-cltname,m_CtrName); int i=1; while (i m_ConnectionType) tpterm(); m_ConCount =0; else return false; m_bInConnection = false; return true; bool CTuxCall:AllocDest(int size) m_RecBuff=tpalloc(CARRAY, NULL, size+1); if(m_RecBuff=NULL) m_Errno = tperrno; GetErrMsg(分配内存出错,可能是申请的空间太大,没有足够的内存可以使用.); return false; return true; bool CTuxCall:AllocSrc(int size) m_SendBuff=tpalloc(CARRAY, NULL, size+1); if(m_SendBuff=NULL) m_Errno = tperrno; GetErrMsg(分配内存出错,可能是申请的空间太大,系统内存不足!); return false; return true; int CTuxCall:SetSendBuf(char *szFormat,.) va_list ap; char *arg=NULL; int len = 0; va_start(ap,szFormat); char tmpStr1024*10=0; vsprintf(tmpStr,szFormat, ap); va_end(ap); len = strlen(tmpStr); if(m_SendBuff) tpfree(m_SendBuff); m_SendBuff=NULL; if (!AllocSrc(len+1) return -1; memcpy(m_SendBuff,tmpStr,len); return len; /直接使用该服务之前,必须保证m_SendBuff中的内容是正确的, /可以调用SetSendBuf()函数设置m_SendBuff的内容. bool CTuxCall:Invoke(char* SrvName,long InLen,long &OutLen) if(m_RecBuff) tpfree(m_RecBuff); m_RecBuff=NULL; if (!AllocDest(1) return false; if (!TuxInit() return false; if(tpcall(SrvName,m_SendBuff,InLen,&m_RecBuff,&OutLen,0)=-1) if(!m_bBeginTrans) tpterm(); m_bInConnection = false; char tmp256; sprintf(tmp,调用服务 %s 出错,SrvName); m_Errno = tperrno; GetErrMsg(严重错误,tmp); return false; if (m_ConnectionType0) m_ConCount+; if(!m_bBeginTrans) TuxTerm(); return true; bool CTuxCall:Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr,long &OutLen, int flag) /首先清除Buffer,有效防止内存泄漏 ClearBuffer(); if (!AllocSrc(InLen) return false; memcpy(m_SendBuff,InStr,InLen); if (!AllocDest(1) return false; if (!TuxInit() return false; if(tpcall(SrvName,m_SendBuff,InLen,&m_RecBuff,&OutLen,0)=-1) if(!m_bBeginTrans) tpterm(); m_bInConnection = false; char tmp256; sprintf(tmp,调用服务 %s 出错,SrvName); m_Errno = tperrno; GetErrMsg(严重错误,tmp); return false; if (m_ConnectionType0) m_ConCount+; if(!m_bBeginTrans) TuxTerm(); OutStr=m_RecBuff; return true; /* * 默认Invoke,默认服务名为TRANSMIT */ bool CTuxCall:Invoke(char * OpCode,.) va_list ap; va_start(ap, OpCode); /序列化输入参数 va_end(ap); long nOutLen; char* pOutBuf; int nInLen = 0; char* pInBuf = NULL; /需要对输入的参数进行组合整理 bool ret; try ret = Invoke(TRANSMITER,pInBuf,nInLen,pOutBuf,nOutLen); catch(.) delete pInBuf; return false; delete pInBuf; return ret; /* * 指定服务名Invoke */ bool CTuxCall:Invoke(char* SrvName,char* OpCode,.) va_list ap; va_start(ap, OpCode); /序列化输入参数 m_Col = 0; /* while (arg =va_arg(ap,char*) != 0) /至于如何把传入的参数组合成一个二进制字符串, /大家可以用自己的方法去处理, /这里涉及的是其他方面的技术,跟tuxedo无关,所以不跟帖. */ va_end(ap); long nOutLen; char* pOutBuf; int nInLen = 0; char* pInBuf = NULL; bool ret = false; try ret = Invoke(SrvName,pInBuf,nInLen,pOutBuf,nOutLen); catch(.) delete pInBuf; return false; delete pInBuf; return ret; bool CTuxCall:BeginTransaction(unsigned long timeout) TuxInit(); if(tpbegin(timeout,0)=-1) tpterm(); m_bInConnection = false; m_Errno = tperrno; GetErrMsg(事务失败,无法开始事务); return false; m_bBeginTrans = true; return true; bool CTuxCall:Rollback() if(!m_bBeginTrans) m_Errno = -101; GetErrMsg(事务失败,回滚之前应先开始一个事务!); return false; m_bBeginTrans = false; if(tpabort(0)=-1) tpterm(); m_bInConnection = false; m_Errno = tperrno; GetErrMsg(回滚事务失败,调用tpabort()函数失败!); return false; TuxTerm(); return true; bool CTuxCall:Commit() if(!m_bBeginTrans) m_Errno = -102; GetErrMsg(事务失败,提交之前应先开始一个事务!); return false; m_bBeginTrans = false; if(tpcommit(0)=-1) tpterm(); m_bInConnection = false; m_Errno = tperrno; GetErrMsg(提交事务失败,调用tpcommit()失败!); return false; TuxTerm(); return true; void CTuxCall:Disconnect() tpterm(); void CTuxCall:ClearBuffer() if(m_RecBuff) tpfree(m_RecBuff); if(m_SendBuff) tpfree(m_SendBuff); m_RecBuff=NULL; m_SendBuff=NULL; void CTuxCall:SetClientInfo(char* username,char* ctlname) strncpy(m_UserName,username,64); m_UserName63=0; strncpy(m_CtrName,ctlname,64); m_CtrName63=0; bool CTuxCall:SetConnectType(int contype) if (contype=0|contype=1|contype=10) m_ConnectionType = contype; return false; else m_Errno = -34; GetErrMsg(参数设置错误,连接只能是0(长连接),1(短连接)和大于10的整数.); return false; bool CTuxCall:CheckWSNADDRValid(char* ipstr,char* port) int iplen = strlen(ipstr); if (iplen 15) return false; int count = 0; char ipstrSubs4=0; int iPos=0,i=0; while (i if (ipstri=0&ipstri3) return false; ipstrSubsiPos=ipstri; iPos+; if (i=iplen-1) ipstrSubsiPos=0; iPos = 0; else if (ipstri=.) if (iPos3) return false; ipstrSubsiPos=0; count+; iPos = 0; else return false; if (iPos=0) if (atoi(ipstrSubs)255) return false; memset(ipstrSubs,0,4); i+; if (count!=3) return false; memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR); strcpy(m_CurWSNADDR,WSNADDR=/); strcat(m_CurWSNADDR,ipstr); strcat(m_CurWSNADDR,:); if (atoi(port)1024) strcat(m_CurWSNADDR,port); else return false; return true; char* CTuxCall:GetErrorMessage() return ErrMsg; char* CTuxCall:GetCurWSNAddr() return m_CurWSNADDR; char * CTuxCall:GetResultData() return m_RecBuff; 测试程序 服务程序 #include #include transmit.h #include int tpsvrinit(int argc,char* argv) userlog(服务转发器transmitsrv启动成功.rn); printf(服务转发器transmitsrv启动成功.rn); return 0; void tpsvrdone() userlog(服务转发器transmitsrv关闭成功.rn); printf(服务转发器transmitsrv关闭成功.rn); char* UpperCase(char* str) int i = 0; while(str!=0) str = toupper(str); i+; return str; char* LowerCase(char* str) int i = 0; while(str!=0) str = tolower(str); i+; return str; char * TrimStr(char * str,int size) if(!str) return ; for(int i=size-1;i=0;i-) if(str= ) str=0; else return str; return str; char* ltrim(char* str) if(str = NULL) return str; int len = strlen(str); for(int i=0; i if(str != ) memmove(str,&str,len-i); strlen-i = 0; break; else if(i = len-1) str0 = 0; break; return str; char* rtrim(char* str) if(str = NULL) return str; int len = strlen(str); for(int i=len-1; i=0; i-) if(str!= ) stri+1 = 0; break; return str; char *trimstr(char *str) rtrim(str); ltrim(str); return str; /服务函数/ /= TRANSMIT 服务处理= /ProcessTRANSMIT函数负责解析客户端传递的参数,并决定该调用哪一个服务. #if defined(_STDC_) | defined(_cplusplus) void ProcessTRANSMIT(TPSVCINFO *rqst,long len,char* sname) #else void ProcessTRANSMIT(*rqst,&len,*sname) TPSVCINFO *rqst; long len; char* sname; #endif /服务. /TRANSMIT:服务转发器,客户端的程序统一调用TRANSMIT,然后由TRANSMIT服务 /根据opcode调用相应的服务. #if defined(_STDC_) | defined(_cplusplus) void TRANSMIT(TPSVCINFO *rqst) #else void TRANSMIT(*rqst) TPSVCINFO *rqst; #endif char sname32+10; long len=0; ProcessTRANSMIT(rqst,len,sname); tpforward(sname,rqst-data,rqst-len,0); tpreturn(TPSUCCESS,0,rqst-data,len,0); /=TRANSMIT 服务处理结束= /= 测试用的服务 HelloWord = #if defined(_STDC_) | defined(_cplusplus) void HelloWord(TPSVCINFO *rqst) #else void HelloWord(*rqst) TPSVCINFO *rqst; #endif /数据格式:操作码(16位)用户名(32) char opcode17=0; char username33=0; char* pBuf; int len; char retMsg1024=0; int retFlag = 0; printf(HelloWord: The Service HelloWord get request !rn); memset(opcode,0,sizeof(opcode); memset(username,0,sizeof(username); memset(retMsg,0,sizeof(retMsg); strncpy(opcode,rqst-data,16); strncpy(userna
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中国盖板玻璃、基板项目商业计划书
- 大一法治考试题及答案
- 房屋租赁三方协议书
- 文言文知识点梳理(3篇)人教统编版九年级语文上册
- 中国生物醇油项目创业投资方案
- 计量法考试试题及答案
- 中国合成液晶高分子项目商业计划书
- 2025年中国酸度调节剂项目创业计划书
- 中国太阳能碳化硅微粉项目创业投资方案
- 合资办学协议书
- 2025-2030中国肌肉松弛药行业市场现状供需分析及投资评估规划分析研究报告
- 《财税基础(AI+慕课版)》全套教学课件
- 《农机安全生产重大事故隐患判定标准(试行)》解读与培训
- 客服基础考试试题及答案
- 2025电力变压器声纹监测与诊断技术
- 军队文职招聘(中医学)笔试题库(全真题库)
- 公司员工职业素养培训
- 医学资料 急诊医学科开展ECMO与ECPR 学习课件
- 跃然纸上平面的标高投影课件
- GB 45189-2025氰化物安全生产管理规范
- 透析患者贫血治疗
评论
0/150
提交评论