[转帖]Tuxedo Quick Start 9 TUXEDO的缓冲区_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4174 | 回复: 0   主题: [转帖]Tuxedo Quick Start 9 TUXEDO的缓冲区        下一篇 
鲲鹏展翅
注册用户
等级:少校
经验:1148
发帖:79
精华:9
注册:2012-11-19
状态:离线
发送短消息息给鲲鹏展翅 加好友    发送短消息息给鲲鹏展翅 发消息
发表于: IP:您无权察看 2012-11-23 10:27:00 | [全部帖] [楼主帖] 楼主

tuxedo的客户端与服务端之间的数据传送是通过数据缓冲区来进行的.TUXEDO的数据缓冲区主要包括STRING,CARRAY,VIEW,VIEW32,FML,FML32,从TUXEDO7.1开始,还增加了XML数据缓冲区.另外,TUXEDO还有几种缓冲区是专门针对COBAL的。在TUXEDO中还可以定义自己的缓冲区类型。
在TUXEDO中客户端与服务端之间进行数据交换的缓冲区(如:tpcall()中的输入,输出缓冲区等)都要用TUXEDO自己提供的API进行操作,不能采用C语言的函数如:malloc(),free()等分配,释放这些缓冲区。同时在程序中要自己管理这些缓冲区,象C语言中的缓冲区一样,在用tpalloc() 分配一块缓冲区之后,在不在需要该缓冲区时用tpfree()释放掉。

与缓冲区使用有关的ATMI

char * tpalloc(char *type, char *subtype, long size)


描述:分配缓冲区
参数:type:缓冲区的类型
    subtype:缓冲区的子类型,只有VIEW有子类型,其他的缓冲区该参数要设为NULL
    long:缓冲区的大小
返回值: 成功返回一个指向所分配空间首地址的CHAR *形指针,失败返回NULL。

char * tprealloc(char *ptr, long size)


描述:重新分配缓冲区
参数:ptr:指向原缓冲区首地址的指针
    size:新缓冲区的大小
返回值: 成功返回一个指向新分配空间首地址的CHAR *形指针,失败返回NULL。

void tpfree(char *bufptr)


描述:释放由TPALLOC()或TPREALLOC()分配的缓冲区
参数:bufptr:指向要释放的缓冲区首地址的指针
返回值:无
注意: 用TPALLOC(),TPREALLOC()分配的内存只能有TPFREE()释放掉,不能用FREE()

long tptypes(char *ptr, char *type, char *subtype)


描述:返回有ptr所指向的缓冲区的类型及子类型
参数: ptr:指向要进行类型识别的缓冲区首地址的指针
type:类型名
subtype:子类型名(只对VIEW类型有效)
返回值:0成功,-1失败, 错误号保存在全局变量tperrno中。

下面我们对常用的数据缓冲区分别进行介绍

STRING:


类似于C中的CHAR *,是以\0接尾的字符串,如果两台机器之间的编码不一样(如一台为ASCII, 另一台为EBCDIC),TUXEDO 将自动进行编码/解码工作。 STRING一般用于在客户端与SERVER端之间传送文本数据。

CARRAY:


是不以\0接尾的字符串,长度要由用户指定。如果两台机器之间的编码不一样,也不进行编码/解码工作。注意在TPCALL,TPACALL,TPRETURN等ATMI中使用CARRY类型的缓冲区时,一定要指定长度,否则会出错。CARRY一般用于传送二进制数据。如在客户端与SERVER端之间传送一个二进制的文件,就要采用CARRAY类型的缓冲区。

VIEW(VIEW32)缓冲区

类似于C中的结构体,不同的是该结构的成员的数据类型可以为short, char, long, float, double,STRING ,CARRAY。 要在一个文件中定义该VIEW(VIEW32)的结构,然后才能使用。VIEW有子类型,子类型为该VIEW(VIEW32)的名字,在调用TPALLOC()分VIEW(VIEW32)缓冲区时要指定该子类型。
VIEW32与VIEW类似,但它采用32位长度的数表示结构体中字段的ID等,VIEW采用16位表示,所以VIEW32可表示更多的字段。
VIEW(VIEW32)缓冲区还可以转化为FML(FML32)缓冲区。

VIEW的使用过程:
1.        定义一个VIEW(VIEW32)的描述文件*.v,如下所示:定义一个名为aud的VIEW

VIEW aud
$ /* View structure for audit information */
# type  cname    fbname        count  flag   size    null
long    b_id     BRANCH_ID     1     -      -    0
float   balance   BALANCE      2      -     -    0.0
string  ermsg    STATLIN       3      -     80   ""
END


说明: 定义一个VIEW(VIEW32)类似于定义一张表,各个字段的含义如下:
type:  该字段的数据类型, 可以为short, char, long, float, double,STRING ,CARRAY.
Cname: 该字段的名字
Fbname: VIEW(VIEW32)可以转化为FML(FML32),  该字段指定如果该VIEW(VIEW32)可以转化
为FML(FML32)时,相应字段的名字。
Count: 该字段的位置值
Flag:  设置该字段的一些标志,主要与转化为FML(FML32)有关
Size:  该字段的长度,只对STRING,CARRY有用
Null: 如果该字段为空(没有被赋值时)时的默认值。如果没有指定,那么数字型的为0,字符型的为"\0",CARRY型的为””。

$:     注释,并且出现在生成的*.h文件中
#:     注释,不出现在生成的*.h文件中
“-”: 表示该属性采用默认值.

2.        用VIEWC(VIEWC32        )进行编译,生成对应的*.h文件和*.VV文件:viewc –n aud
3.        定义环境变量VIEWDIR(VIWEDIR32),VIEWFILES(VIEWFILES32)
VIEWDIR(VIEWDIR32): VIEW(VIEW32)的定义文件所在的路径
VIEWFILES(VIEWFILES32): VIEW(VIEW32)的定义文件名,如果有多个用,隔开
4.        在使用到该VIEW(VIEW32)的程序中用#include包含生成的*.h文件.
5.在程序中可以象使用C语言的结构体一样使用该VIEW(VIEW32)

VIEW(VIEW32)的使用例子:
在客户端通过一个VIEW缓冲区把数据传送到服务器端,在服务器端把收到的数据打印出来。
1.定义VIEW的定义文件aud.v

VIEW aud
$ /* View structure for audit information */
# type  cname    fbname        count  flag   size    null
long    b_id     BRANCH_ID     1     -      -    0
float   balance   BALANCE      2      -     -    0.0
string  ermsg    STATLIN       3      -     80   ""


2.用viewc -n aud.v 进行编译,生成对应的aud.h文件和aud.VV文件.
aud.h文件的内容如下, aud.VV为二进制的文件

 struct aud {
      /* View structure for audit information */
      long b_id;
      float balance;
      char ermsg[80];
};


3. 定义环境变量VIEWDIR,VIEWFILES

set VIEWFILES=aud.VV
set VIEWDIR=%APPDIR%


4.        客户端的程序client.c:

#include <stdio.h>
#include "atmi.h"
#include "aud.h"
#include "fml.h"
main(int argc, char **argv)
{
      struct aud *audv;
      FBFR *rcvbuf;
      long rcvlen;
      char * str_buf = "";
      int ret;
      if (tpinit((TPINIT *) NULL) == -1)
      {
            printf("Tpinit failure: %s\n",tpstrerror(tperrno));
            exit(1);
      }
      if ((audv = (struct aud *)tpalloc("VIEW", "aud", sizeof(struct aud))) ==(struct aud *)NULL)
      {
            printf("tpalloc(VIEW) failure: %s\n",tpstrerror(tperrno));
            exit(1);
      }
      rcvbuf = tpalloc("STRING", NULL, 1000);
      audv->balance = 110.0;
      strcpy(audv->ermsg,"this is a view test");
      /* Request the service TOUPPER, waiting for a reply */
      if(tpcall("VIEWDEMO", (char *)audv, sizeof(struct aud), (char **)&audv,&rcvlen, (long)0)==-1)
      {
            printf("tpcall(TOUPPER) failure:%s\n",tpstrerror(tperrno));
            tpfree(audv);
            tpfree(rcvbuf);
            tpterm();
            exit(1);
      }
      tpfree(audv);
      tpfree(rcvbuf);
      tpterm();
}


服务端的程序server.c如下:

include <stdio.h>
#include <atmi.h>
#include <userlog.h>
#include "aud.h"
TOUPPER(TPSVCINFO *rqst)
{
      struct aud *audv;
      audv = (struct aud *)rqst->data;
      userlog("balance=%f\n",audv->balance);
      userlog("ermsg=%s\n",audv->ermsg);
      tpreturn(TPSUCCESS, 0, NULL, 0, 0);
}




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论