收藏 分享(赏)

使用C++ Builder封装Tuxedo客户端调用.docx

上传人:hyngb9260 文档编号:7191580 上传时间:2019-05-09 格式:DOCX 页数:20 大小:24.37KB
下载 相关 举报
使用C++ Builder封装Tuxedo客户端调用.docx_第1页
第1页 / 共20页
使用C++ Builder封装Tuxedo客户端调用.docx_第2页
第2页 / 共20页
使用C++ Builder封装Tuxedo客户端调用.docx_第3页
第3页 / 共20页
使用C++ Builder封装Tuxedo客户端调用.docx_第4页
第4页 / 共20页
使用C++ Builder封装Tuxedo客户端调用.docx_第5页
第5页 / 共20页
点击查看更多>>
资源描述

1、使用 C+ Builder 封装 Tuxedo 客户端调用本文主要介绍如何使用 C+ Builder 把 Tuxedo 客户端的调用封装成一个独立的类 CTuxCall,最大程度的方便用户调用 tuxedo,并给出相应的例子,以供参考.由于是第一次发表这样的文章,其中不足之处,还望大家予以批评指正。 类 CTuxCall 的特点 封装后的类 CTuxCall 有如下一些特点,能够最大程度的满足用户的需求 ,方便用户的调用. (1) 可以自定义连接方式,长连接 ,短连接和混合连接( 由用户自定义连接次数,当实际的连接次数超过自定义的连接次数,则自动断开连接,然后重连); (2) 可以自动切换连接

2、地址,目前提供了 5 个备用地址,只要其中有一个地址上的服务是正常的,则 Tuxedo 的连接就是正常的; (3) 能够方便的设置客户端的信息,如操作员名称,操作员 IP 地址,或者操作员当前操作状态; (4) 调用方式简单,灵活,可扩充性好. 类 CTuxCall 函数说明 (1) 设置客户端信息,在这里你可以设置操作员或者终端,甚至是一些操作状态的信息 : void SetClientInfo(char* username,char* ctlname); 使用该函数后,在服务器的管理平台,使用 pclt 命令,就会显示客户端的相关 信息,如: LMID User Name Client N

3、ame 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(

4、); 在客户端编写代码 ,只要调用这个函数即可.关于这个函数 有几个不同的函数原形,具体如下: bool Invoke(char * OpCode,.); 指定操作码,调用确省服务,参数个数不定,至于如何把传入的参数一定的格式 写入到发送缓冲去,需要调用自定义的函数进行打包. bool Invoke(char* SrvName,char* OpCode,.); 大体内容同上,只是调用的是指定的服务,而不是确省的服务. bool Invoke(char* SrvName,long InLen,long 在使用此函数之前,必须保证先调用 SetSendBuf()函数填充发送缓冲区. bool In

5、voke(char * SrvName,char * InStr,long InLen, char * 调用指定服务,输入参数和返回结果都由用户自定. (5) 填充发送缓冲区:int SetSendBuf(char *szFormat,.); 该函数用法同 c 语言的 printf()函数,只是发送缓冲区的长度有限制 ,最好不要超过 1024*10个字节. 源码分析 类 CTuxCall 的源码 TuxCall 头文件 /- #ifndef TuxCallH #define TuxCallH /- #if defined(_BORLANDC_) char * m_SendBuff; char

6、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*

7、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

8、,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 * bool Invoke(char * OpCode,.); bool Invoke(char* SrvName,char* OpCode,.); boo

9、l Invoke(char* SrvName,long InLen,long 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

10、 的实现 #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 #p

11、ragma 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“

12、 ) #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

13、 _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_SendBuf

14、f=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

15、* 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

16、;/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

17、 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 t

18、rue; 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); cha

19、r 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

20、:Invoke(char* SrvName,long InLen,long m_RecBuff=NULL; if (!AllocDest(1) return false; if (!TuxInit() return false; if(tpcall(SrvName,m_SendBuff,InLen, m_bInConnection = false; char tmp256; sprintf(tmp,“调用服务 %s 出错“,SrvName); m_Errno = tperrno; GetErrMsg(“严重错误“,tmp); return false; if (m_ConnectionType

21、0) m_ConCount+; if(!m_bBeginTrans) TuxTerm(); return true; bool CTuxCall:Invoke(char * SrvName,char * InStr,long InLen, char * 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_bInConn

22、ection = 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;

23、 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:Invo

24、ke(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; tr

25、y 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

26、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

27、; 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(); retur

28、n 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

29、,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

30、 iplen = strlen(ipstr); if (iplen 15) return false; int count = 0; char ipstrSubs4=0; int iPos=0,i=0; while (i if (ipstri=“0“ 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;

31、 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 f

32、alse; 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(“

33、服务转发器 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+; retur

34、n 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, strlen-i = 0; break; else if(i = len-1) str0 = 0;

35、 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

36、defined(_STDC_) | defined(_cplusplus) void ProcessTRANSMIT(TPSVCINFO *rqst,long len,char* sname) #else void ProcessTRANSMIT(*rqst, long len; char* sname; #endif /服务. /TRANSMIT:服务转发器 ,客户端的程序统一调用 TRANSMIT,然后由 TRANSMIT 服务 /根据 opcode 调用相应的服务. #if defined(_STDC_) | defined(_cplusplus) void TRANSMIT(TPSVC

37、INFO *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

38、(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,size

39、of(username); memset(retMsg,0,sizeof(retMsg); strncpy(opcode,rqst-data,16); strncpy(username,rqst-data+16,32); printf(“HelloWord: %srn“,rqst-data); printf(“HelloWord: opcode = %s, UserName= %srn“,trimstr(opcode),trimstr(username); if (!strcmp(opcode,“GetTime“) time_t timer; struct tm *tblock; /* get

40、s time of day */ timer = time(NULL); /* converts date/time to a structure */ tblock = localtime( printf(“Local time is: %s“, asctime(tblock); sprintf(retMsg,“Now, Local time is: %s“,asctime(tblock); retFlag = 1; else if (!strcmp(opcode,“Hello“) printf(“%s: First thanks. And welcome to use tuxedo .rn

41、“,username); sprintf(retMsg,“%s: First thanks. And welcome to use tuxedo .rn“,username); retFlag = 1; else sprintf(retMsg,“%s %s“,opcode,“无效的操作码!“); len = strlen(retMsg) + 1; pBuf = tpalloc(“CARRAY“,NULL,len); if(pBuf = 0) tpreturn(TPFAIL,0,0,0,0); else strcpy(pBuf,retMsg); if (retFlag=1) tpreturn(T

42、PSUCCESS,0,pBuf,len,0); else tpreturn(TPFAIL,0,pBuf,len,0); / HelloWorld 结束 / 客户端测试 gTuxCall.SetClientInfo(“zlwen“,“Test-GetTime“); if (gTuxCall.SetWSNAddr(“/192.168.1.7:44321“) ShowMessage(gTuxCall.GetCurWSNAddr(); else ShowMessage(gTuxCall.GetErrorMessage(); int inLen = gTuxCall.SetSendBuf(“%-32s%-16s“,“GetTime“,“TestName“); /SetSendBuf 的使用方法通 printf(). int outLen = 0; if (gTuxCall.Invoke(“HelloWord“,inLen,outLen) ShowMessage(gTuxCall.GetResultData(); else ShowMessage(gTuxCall.GetErrorMessage(); 总结 本程序在 C+ Builder 5.0 上通过测试 .有什么问题欢迎通过邮件联系 .

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报