服务端代码:

 #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. maven-shade-plugin 入门指南

    1. Why? 通过 maven-shade-plugin 生成一个 uber-jar,它包含所有的依赖 jar 包. 2. Goals Goal Description shade:help Dis ...

  2. Go语言之进阶篇爬百度贴吧并发版

    1.爬百度贴吧并发版 示例: package main import ( "fmt" "net/http" "os" "strco ...

  3. Cesium原理篇:3D Tiles(1)渲染调度【转】

    Cesium在2016年3月份左右推出3D Tiles数据规范,在glTF基础上提供了LOD能力,定位就是Web环境下海量三维模型数据.虽然目前3D Tiles还是Beta阶段,有不少硬伤,但3D T ...

  4. "Your computer could not be joined to the domain. You have exceeded the maximum number of computer accounts you are allowed to create in this domain. Contact your system administrator to have this limit reset or increased."

    用一个普通的域帐号玩私有云的时候,遇到了如下的报错. "Your computer could not be joined to the domain. You have exceeded ...

  5. [PowerShell Utils] Create a list of virtual machines based on configuration read from a CSV file in Hyper-V

    Hello everyone, this is the third post of the series. .   Background =============== In my solution, ...

  6. WPF中使用流文档

    转载自:http://www.cnblogs.com/zlgcool/archive/2008/11/17/1335456.html WPF面向的是UI展现,而文本显示无疑是UI层中的重要功能之一.W ...

  7. jquery ajax 的 $.get()用法详解

    js文件 $(document).ready(function(){ $("form").submit(function(event) {event.preventDefault( ...

  8. 利用vue-cropper做的关于图片裁剪、压缩、上传、预览等做的一个公共组件

    公共组件: <template> <div> <div class="upload-box"> <div class="imag ...

  9. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十三)kafka+spark streaming打包好的程序提交时提示虚拟内存不足(Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical memory used; 2.2 GB of 2.1 G)

    异常问题:Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical mem ...

  10. (转)Esfog_UnityShader教程_UnityShader语法实例浅析

    距离上次首篇前言已经有一段时间了,一直比较忙,今天是周末不可以再拖了,经过我一段时间的考虑,我决定这一系列的教程会避免过于深入细节,一来可以避免一些同学被误导,二来会避免文章过于冗长难读, 三来可以让 ...