Chinaunix首页 | 论坛 | 博客
  • 博客访问: 662849
  • 博文数量: 77
  • 博客积分: 6055
  • 博客等级: 准将
  • 技术积分: 617
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 02:15
个人简介

一句话太少

文章分类

全部博文(77)

文章存档

2018年(1)

2015年(1)

2014年(1)

2013年(6)

2011年(1)

2010年(1)

2009年(4)

2008年(2)

2007年(21)

2006年(39)

我的朋友

分类:

2006-06-07 23:19:05

 一:概述:
在BEA TUXEDO中,有七种通信方式,而最为常用的就是同步和会话了,尤其在大批量传输数据的时,会话就显得更尤为重要了,但是会话在BEA TUXEDO的示例中没有象同步那样,给出一个SIMPAPP的例子,来给学习者一个很快认识同步通信的方式,不过,在BANKAPP中有关于会话示例,是作为整个BANKAPP的里的一部分出现的。在这个会话中加入了身份校验,和比较复杂的业务逻辑,这样也就增加了学习的难度,但是我们仍然可以只抽取自己需要的,实现一个简单的会话,来学习BEA TUXEDO的会话的通信方式。这也就是怎么样来化繁为简来学习编写会话程序。

二:会话简介:
会话是一个半双工的通信模式,下面的图给出了会话通信的简单模型:


图1:此图来自BEA TUXEDO 官方文档

现在对上图中的函数和标识符作以简单的说明:
Tpconnect函数:通过服务名(name)和service建立连接。
Tpsend函数:把数据通过此函数发送到数据的接收方。
Tprecv函数:把发送来的数据进行接收。
(注:关于函数具体参数的描述读者可以详见TUXEDO文档。)
TPSENDONLY:此标识符表明发送者只能发送数据,而被调用的服务(service)只能接收数据。发送者最初有连接(connect)的控制权。
TPRECVONLY:此标识符表明接收者在接收数据的同时,也接收了对连接(connect)的控制权。
简单的说,我们的会话就是在上面的函数和标识符的配合下,进行着发起方和接受方之间的数据传输工作。

三:简化BANKAPP的会话程序。
我们可以根据BANKAP应用中提供的会话程序部分来做一个单独的会话的示例,这样就可以把作成的示例做为一个模板,作为今后不同业务逻辑下的会话程序开发的基本框架结构。因此解决重复劳动,并且可以快速,正确的达到目的。
BANKAPP中的会话程序中有比较复杂的业务逻辑,还有身份校验的程序,我们把这些程序代码从程序中去掉,对程序作简单更改,达到程序可以正常的运行的目的。
我们对程序做这样的更改:客户端执行循环向服务端传送1到9这9个数字,然后在让服务端把这9个数字加上服务端的信息(也就是在服务端加入了"SERVER"这个字符串)返回,这就是我们在程序中加入的内容。
在BEA TUXEDO 的示例中和会话有关的程序文件是:auditcon.c和AUDITC.c,其中:auditcon.c是客户端程序,AUDITC.c是服务端程序。
下面我们来做这个改写的工作:
客户端程序:auditcon.c修改后如下:
#include /* UNIX */
#include /* UNIX */
#include /* TUXEDO */
#include /* TUXEDO */
#include /* TUXEDO */
#define LINE 80 /* size of reply line */

#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif

{
int i; /*add variable在程序中加入的变量此程序中仅加入了这一个变量*/
int cd; /* conversation descriptor */
char *line; /* tux buffer holding reply */
long len; /* length of recv'd line */
long revent; /* events for send/recv */

TPINIT *tpinitbuf ; /* for client identification */

/*
* Alloc a TPINIT buffer for identification purposes
* This is not mandatory if no authentication is configured
*/

tpinitbuf = (TPINIT *) tpalloc("TPINIT", NULL, TPINITNEED(16)) ;

if (tpinitbuf == (TPINIT *) NULL) {
(void)fprintf(stderr, "Failed for TPINIT buffer, %s\n",
tpstrerror(tperrno));
(void)userlog("Failed for TPINIT buffer, %s",
tpstrerror(tperrno));
exit(1);
}

/* Join application */

if (tpinit(tpinitbuf) == -1) {
(void)fprintf(stderr, "Failed to join application, %s\n",
tpstrerror(tperrno));
(void)userlog("Failed to join application, %s",
tpstrerror(tperrno));
exit(1);
}

/*
* string buffer will be used to convey balance request and return
* results from conversational service.
*/

if ((line = tpalloc("STRING","",LINE+1)) == (char *)NULL) {
(void)fprintf(stderr,"tpalloc failed tperrno %d\n", tperrno);
(void)userlog("tpalloc failed tperrno %d", tperrno);
exit(1);
}

/* open connection to audit conversational service. */

if ((cd = tpconnect("AUDITC",NULL,0,TPSENDONLY)) == -1) {
(void)fprintf(stderr,"tpconnect failed tperrno %d\n", tperrno);
(void)userlog("tpconnect failed tperrno %d", tperrno);
(void)tpterm();
exit(1);
}
/*下面这段程序中是循环向服务端发送0-9这9个数字的程序*/
for (i=0;i<10;i++) {
(void)sprintf(line,"%d",i);
/* send balance request and relinquish line control. */
if (tpsend(cd,line,0,TPRECVONLY,&revent) == -1) {
(void)fprintf(stderr,"tpsend failed tperrno %d\n", tperrno);
(void)userlog("tpsend failed tperrno %d", tperrno);
(void)tpterm();
exit(1);
}
/* wait for service to return balance request results. */
if (tprecv(cd,&line,&len,TPNOCHANGE,&revent) != -1) {
(void)fprintf(stderr,"tprecv failed tperrno %d revent %ld\n",
tperrno,revent);
(void)userlog("tprecv failed tperrno %d revent %ld",
tperrno,revent);
(void)tpterm();
exit(1);
}

/* anything other than a send or disconnect event is an error.*/

if ((tperrno != TPEEVENT) || ((revent != TPEV_SENDONLY) &&
(revent != TPEV_SVCSUCC))) {
(void)fprintf(stderr,"tprecv failed tperrno %d revent %ld\n",
tperrno,revent);
(void)userlog("tprecv failed tperrno %d revent %ld",
tperrno,revent);
(void)tpterm();
exit(1);
}
printf("return result line =%s\n", line);
}
/*结束添加*/

/* Leave application */

if (tpterm() == -1) {
(void)fprintf(stderr,"failed to leave application\n\n");
(void)userlog("failed to leave application\n");
exit(1);
}
return(0);
}
服务端程序:AUDITC.c修改后如下:
#include /* UNIX */
#include /* UNIX */
#include /* TUXEDO */
#include /* TUXEDO */
#include /* TUXEDO */

#define LINE 80 /* size of balance request line */

static char pgmname[80]; /* program name = argv[0] */
/*
* AUDITC is a conversational server containing a service of the same
* name that finds the total balance of all accounts/tellers at a
* branch or the total for the entire bank
*/

void
#if defined(__STDC__) || defined(__cplusplus)
AUDITC(TPSVCINFO *svcinfo)
#else
AUDITC(svcinfo)
TPSVCINFO *svcinfo;
#endif
{

char c; /* Option character */
char *line; /* tux buffer holding request */
long len; /* length of recv'd line */
long revent; /* events for send/recv */
char tmpStr[100];

/* allocate buffer to receive balance request. */

if ((line = tpalloc("STRING","",LINE+1)) == (char *)NULL) {
(void)userlog("%s: string tpalloc failed tperrno %d",
pgmname,tperrno);
(void)tpreturn(TPFAIL,0,NULL,0,0);
}
/*下面程序中把客户端发送来的数据,加入服务端的信息的代码*/
for (;;) {

/* receive balance request */

if (tprecv(svcinfo->cd,&line,&len,TPNOCHANGE,&revent) != -1) {
(void)userlog("%s: recv'd message without event",pgmname);
(void)sprintf(line,"%s: audit request failed (see ulog)\n",
pgmname);
(void)tpreturn(TPFAIL,0,line,strlen(line),0);
}

/* if anything other than an event is received, its an error. */

switch (tperrno) {
case TPEEVENT:
switch ((int)revent) {
case TPEV_SENDONLY:
break;
case TPEV_DISCONIMM: /* disorderly disconnect */
(void)tpreturn(TPSUCCESS,0,NULL,0,0);
}
break;
default:
(void)userlog("%s: tprecv failed tperrno %d revent %ld", pgmname,tperrno,revent);
(void)sprintf(line,"%s: audit request failed (see ulog)\n",
pgmname);
(void)tpreturn(TPFAIL,0,line,strlen(line),0);
}

strcpy(tmpStr,line);
strcat(tmpStr," server");
strcpy(line,tmpStr);
/* return balance query results */

if (tpsend(svcinfo->cd,line,0,TPRECVONLY,&revent) == -1) {
switch (tperrno) {
case TPEEVENT:
switch ((int)revent) {
case TPEV_DISCONIMM:
(void)tpreturn(TPSUCCESS,0,NULL,0,0);
}
default:
(void)userlog("%s: tpsend failed tperrno %d revent %ld",
pgmname,tperrno,revent);
(void)sprintf(line,
"%s: tpsend failed (see ulog)\n",
pgmname);
(void)tpreturn(TPFAIL,0,line,strlen(line),0);
}
}
}
}

更改BANKAPP中的配置文件UBBSHM,先将UBBSHM文件中的注释的语句全部都删除。利于观看有用的配置信息,然后根据需要,将UBBSHM文件改写成如下形式:

UBBSHM文件如下:

图2:UBBSHM
编译程序:
BUILDCLIENT -o auditcon -f auditcon.c
BUILDSERVER -o AUDITC -f AUDITC.c -s AUDITC
编译UBBSHM文件:C:\TUXEDO\apps\backcon>tmloadcf -y ubbshe
启动服务:C:\TUXEDO\apps\backcon>tmboot -y
执行程序,程序正确执行后,将在屏幕显示的结果如下:

图3:程序执行结果
以上就是通过化繁为简的方法来完成了一个会话的建立,并且可以根据不同需要改写代码来实现不同的功能。由此可以看出程序是一个由简驭繁,由繁化简的过程。

四:总结
通过程序告诉大家一个学习的方法,首先要坚持信心寻求突破方式。其次,就是要把复杂的程序简单化,来学习程序,而不至于让复杂的程序使我们望而却步。

五:参考
1. BEA官方网站文档:《BEA TUXEDO Programmer's Guide》
2. BEA TUXEDO安装目录下的TUXEDO程序示例:BANKAPP
3. 经乾:《BEA TUXEDO的七种通信方式(1)》
六:程序文件:
本文中的程序文件供大家下载,仅作为大家的参考之用。本程序在WINDOWS 2000 SERVER、TUXEDO6.5(TUXEDO8.1)上通过。


阅读(2131) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~