服务端代码:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <atmi.h>
#include <userlog.h> static void trim(char *strIn, char *strOut){ char *start, *end, *temp; temp = strIn;
while (*temp == ' ')
{
++temp;
} start = temp; temp = strIn + strlen(strIn) - ; while (*temp == ' '){
--temp;
} end = temp; for (strIn = start; strIn <= end;){
*strOut++ = *strIn++;
} *strOut = '\0'; } // return 1 is true , 0 is false
static int isDigit(const char* str, int len)
{
int i;
if (len == )
{
return ;
}
for (i = ; i < len; ++i)
{
if (i == && str[i] == '-') continue; if (!isdigit(str[i]))
{
return ;
}
}
return ;
} static int extractErrorCodeTagValue(const char* source)
{
char tagBeginStr[] = { };
char tagEndStr[] = { };
char errorCodeStr[] = { };
char errorCodeStrOut[] = { };
const char *beginPos = NULL;
const char *endPos = NULL;
const char* ERROR_CODE_TAG = "ERRORCODE"; char *workPtr = NULL;
int i = ; if (source == NULL || strlen(source) == )
{
return -;
} sprintf(tagBeginStr, "<%s>", ERROR_CODE_TAG);
sprintf(tagEndStr, "</%s>", ERROR_CODE_TAG); beginPos = strstr(source, tagBeginStr);
endPos = strstr(source, tagEndStr); if (beginPos == NULL || endPos == NULL)
{
return -;
} for (workPtr = (char*)beginPos + strlen(tagBeginStr); workPtr != endPos; workPtr++,i++)
{
errorCodeStr[i] = *workPtr;
} if (strlen(errorCodeStr) == )
{
return -;
} trim(errorCodeStr, errorCodeStrOut); if (!isDigit(errorCodeStrOut, strlen(errorCodeStrOut)))
{
return -;
} return atoi(errorCodeStrOut); } EXEC SQL INCLUDE sqlca; EXEC SQL BEGIN DECLARE SECTION;
char result_out[] = "";
char* requestData = NULL;
long requestDataLen = ;
char* resultData = NULL;
int retErrorCode = ;
EXEC SQL VAR result_out IS STRING();
EXEC SQL END DECLARE SECTION; TEST(TPSVCINFO *rqst) { requestData = rqst->data;
requestDataLen = rqst->len; userlog("Request Data is:%s", requestData); userlog("Request Data Length is:%d", requestDataLen); EXEC SQL EXECUTE
DECLARE
result_out_sql varchar2();
BEGIN
result_out_sql := '';
prc_K_testJsdQuery(:requestData,result_out_sql);
:result_out := result_out_sql;
END;
END-EXEC; userlog("result_out is: %s",result_out); retErrorCode = extractErrorCodeTagValue(result_out);
userlog("ret Error Code is: %d",retErrorCode);
if(retErrorCode != )
{
EXEC SQL ROLLBACK;
userlog("executed rollback");
}
else
{
EXEC SQL COMMIT;
userlog("executed commit");
} resultData = (char *)tpalloc("STRING",NULL, + );
if(resultData)
{
memset(resultData,, + );
strncpy(resultData,result_out,);
userlog("result Data is: %s",resultData);
userlog("result Data Length is: %d",strlen(resultData));
tpreturn(TPSUCCESS,,resultData,strlen(resultData),);
tpfree(resultData);
}
else
{
tpreturn(TPFAIL,,NULL,,);
} }

以上代码内嵌了SQL,采用了Oracle的Pro*C/C++ 编程方式,需要运行以下命令生成相应的可以编译的server_test.c文件:

proc USERID=[数据库账户名]/[数据库密码]@si2000 sqlcheck=SEMANTICS ireclen=512 iname=server_test.pc
 
然后再编译生成好的server_test.c文件:
buildserver -o server_test -f server_test.c -r Oracle_XA -s TEST
 
以上命令有个-s的参数是服务端代码里面Service Routine的名字,其实就是提供服务的函数名了。
 
因为Tuxedo是交易中间件,银行里面大量使用了这个。所以服务端的代码不可能不涉及分布式事务,所以需要运行以下命令行生成对应数据库的事务管理服务器(TMS):
buildtms -o TMS_ORA10G -r Oracle_XA
 
-o参数就是生成的TMS的exe文件名,这个文件的名称需要在TUXCONFIG文件中配置引用,这样启动的tuxedo服务才能使用事务。
 
然后配置TUXCONFIG文件,配置完成用tmloadcf命令生成加密后的二进制配置文件。
 
生成完成二进制配置文件之后暂时还不能启动Tuxedo服务,因为服务可能会使用事务。所以需要进入tmadmin命令中配置事务日志:
tmadmin
crdl -b [block_num] -z D:\oracle\product\10.2.0\db_2\tuxedo12.1.3.0.0_VS2010\samples\atmi\connect-database-test\TLOG
crlog -m [master_node_name]
 
block_num一定要比TUXCONFIG文件中的TLOGSIZE大20-30%
master_node_name 其实就是TUXCONFIG文件中的MASTER 配置项的值,主节点的逻辑ID
 
以上命令都成功了以后,就可以使用tmboot命令启动Tuxedo服务了。服务端已经完美运行并连接数据库。下面来写客户端代码:
 
 /*功能:调用TUXEDO服务端的服务TEST,取EMPNO=1000所对应的ENAME的值,并显示出来*/
#include <stdio.h>
#include "atmi.h"
main(argc,argv)
{ long reqlen=;
char *sendbuf;
char *rcvbuf; char *wsaddrEnv = tuxgetenv("WSNADDR");
if(wsaddrEnv)
{
fprintf(stderr,"wsnaddr is:%s\n",wsaddrEnv);
}
/* 与TUXEDO服务端建立连接 */
if (tpinit((TPINIT *) NULL) == -)
{
(void) fprintf(stderr,"Tpinit failedn");
exit();
} /* 分配发送缓冲区*/ sendbuf = (char *)tpalloc("STRING",NULL,reqlen); if ( sendbuf == (char *)NULL) { printf("tpalloc failedn"); tpterm(); } /* 分配接受缓冲区*/
rcvbuf = (char *)tpalloc("STRING",NULL,reqlen); if ( rcvbuf == (char *)NULL) { printf("tpalloc failedn"); tpterm(); } strcpy(sendbuf,"<AKC190>L2017262210000651420</AKC190><YYBM>0080</YYBM>"); /*调用TUXEDO的服务TEST*/ if (tpcall("TEST", (char *)sendbuf, 0L, (char **)&rcvbuf, (long *)&reqlen, < ) )
/*tpcall("TOUPPER", (char *)sendbuf, 0, (char **)&rcvbuf, &rcvlen, (long)0))*/
{ printf("tpcall failed,tperrno=%ld,tperrtext=%s\n",tperrno,tpstrerror(tperrno)); tpfree(rcvbuf); tpterm(); exit(); } printf("name=%s\n",rcvbuf); tpfree(rcvbuf); tpfree(sendbuf); tpterm(); return(); }

然后以上代码用以下命令行来编译:

buildclient -o client_test -f client_test.c -w
 
-w参数必须加上,因为是远程客户端连接Tuxedo服务(客户端和服务端不在一台物理机上),如果是本地客户端连接Tuxedo服务(客户端和服务端在一台物理机上),就不用加-w
 
 
references:
http://blog.163.com/lover_j_j/blog/static/1682474472007101591059797/
https://docs.oracle.com/cd/B14117_01/appdev.101/a97269/pc_01int.htm#sthref50
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/adfns/xa.html#GUID-22284B0A-C63F-471A-96ED-AEA195068944
https://wenku.baidu.com/view/ef4b38c5580216fc710afdcf.html
http://blog.csdn.net/cemer815/article/details/5493081
http://stevenos.iteye.com/blog/362630

Oracle Tuxedo工作站客户端与服务端的样例程序的更多相关文章

  1. Tuxedo安装、配置、以及演示样例程序 (学习网址)

    Tuxedo安装.配置.以及演示样例程序 (学习网址): 1.http://liu9403.iteye.com/blog/1415684 2.http://www.cnblogs.com/fnng/a ...

  2. aiohttp web服务端(server)样例 (非client)

    python版本 python3.6 (其他版本需要小改,版本>python3.4) 参考网址:https://www.cnblogs.com/ameile/p/5589808.html  as ...

  3. 同一台电脑同时装Oracle客户端和服务端

    1.如果之前安装过Oracle,Win+R输入Services.msc,关掉以Oracle开头的服务(卸载Oracle服务端和客户端步骤一样,见另外一篇帖子) 2.Win+R输入regedit打开注册 ...

  4. 安装_oracle11G_客户端_服务端_链接_oracle

    在开始之前呢,有一些注细节需要注意,oracle11G_客户端_和_服务端, 分为两种   一种是  开发者使用    一种是  BDA  自己使用(同时也需要根据自己 PC 的系统来做_win7_与 ...

  5. TCP学习之五:客户端、服务端异步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...

  6. TCP学习之三:客户端、服务端同步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...

  7. 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)

    当客户端向服务端传输特殊字符时报错,错误信息如下图:

  8. [Java]Hessian客户端和服务端代码例子

    简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...

  9. SignalR 实现web浏览器客户端与服务端的推送功能

    SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...

随机推荐

  1. tensorflow 卷积/反卷积-池化/反池化操作详解

    Plese see this answer for a detailed example of how tf.nn.conv2d_backprop_input and tf.nn.conv2d_bac ...

  2. Create an Android library

    官方文档 创建 Android 库 [Create an Android library] Android 库在结构上与 Android app module 相同.它可以提供构建应用所需的一切内容, ...

  3. Linux服务器安装zabbix监控平台

    zabbix是基于web界面的开源分布式监控平台,可以监控各种服务器的配置参数,支持自定义配置和自定义告警,并且可以实现邮件.短信等方式的告警,zabbix基本组件如下: zabbix_server: ...

  4. Shark简介、部署及编译小结

    http://blog.csdn.net/pelick/article/details/11964291 Shark简介 Shark即Hive on Spark,本质上是通过Hive的HQL解析,把H ...

  5. 转: wireshark的使用说明

    原创者:http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html from:  https://mp.weixin.qq.com/ ...

  6. 【摘录】在Windows平台上使用Objective-C

    虽然到目前为止最好的Objective-C 编码平台来自苹果公司,但它们绝不仅适用于苹果公司的平台.Objective-C 在Linux.BSD 甚至Windows 等其他平台都有相当久远的历史.根据 ...

  7. Code faster with Intellij IDEA live templates

    Intellij IDEA – in my opinion the most productive IDE for Java – comes with bunch of features helpin ...

  8. Git 常用命令 思维导图(转)

    Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势. 本来想着只把最有用.最常用的 Git 命令记下来,但是总觉得这个也挺有用.那个也用 ...

  9. 看见上帝的 10 个公式……

    原文 Top Ten Greatest Equations Ever 本文内容 No.1 麦克斯韦方程组 No.2 欧拉方程 No.3 牛顿第二定律 No.4 毕达哥拉斯定理 No.5 薛定谔方程 N ...

  10. VS2017安装或卸载错误1303

    为添加一个Python开发环境,运行Visual Studio Installer安装报错,下面是日志: 问题日志 安装出现问题. 可通过以下方式排查包故障问题: 1. 使用以下搜索 URL 来搜索针 ...