第八章TUXEDO的通讯方式.docx
- 文档编号:11108548
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:54
- 大小:102.55KB
第八章TUXEDO的通讯方式.docx
《第八章TUXEDO的通讯方式.docx》由会员分享,可在线阅读,更多相关《第八章TUXEDO的通讯方式.docx(54页珍藏版)》请在冰豆网上搜索。
第八章TUXEDO的通讯方式
第八章:
TUXEDO的通讯方式
TUXEDO中的客户端与服务端之间可以采用的通讯方式有:
1.同步调用方式
2.异步调用方式
3.管道方式
4.会话方式
5.消息方式
6.事件发布订阅方式
7./Q方式
注意:
1.服务端的SERVICE之间,可以采用管道方式,客户端与服务端之间不能采用。
2.客户端与服务端之间可以采用消息方式,服务端的SERVICE之间不能采用消息方式。
3.其他通讯方式在服务端的SERVICE之间,及客户端与服务端之间都可以采用。
管道方式(tpforward())在服务端编程中有说明,/Q方式在第十章中在介绍,对这两种方式在本章种不做介绍.
8.1同步调用方式
如下图所示:
在同步请求/回答方式中,客户端使用tpcall()给本地或远程的服务器(由TUXEDO系统根据公告板信息确定)发送服务请求,此时客户将传送请求服务的名字、用于请求服务的输入参数和输出参数,tpcall()发出后,客户的数据被传送至服务器,得到相应的服务处理。
在此方式下,服务器处理请求时,客户端将等待,不继续运行,直到服务器返回相应结果。
调用过程如图:
例子:
客户端通过对一个文件分块,每调用一次TPCALL()发送一块数据,把一个文件从客户端传送到服务端。
客户端与服务端采用FML32缓冲区进行通信。
在异步调用方式和会话方式中也用到该例子。
可以做一个比较。
在该例子中我们把块的大小定义为
1024字节。
采用FML32缓冲区。
FML32定义文件Myfml.h的内容:
*base100
#namenumbertypeflagscomments
FNAME1string--
BNUM3long
BID4long--
FDATA5carray--
BSIZE6long--
服务端程序Call.c的内容:
#include
#include
#include
#include
#include"fml32.h"
#include"myfml.h"
CALL(TPSVCINFO*rqst)
{
FILE*fp;
longi=0;
FBFR32*rcvbuf;
charfname[100]="";
FLDLEN32len=0;
longbid=0;
longbsize=1024;/*传送的块大小为1024字节*/
char*fdata;
rcvbuf=(FBFR32*)rqst->data;
len=sizeof(bid);
if(Fget32(rcvbuf,BID,0,(char*)&bid,&len)==-1)
{
userlog("Fget32(BID)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
len=sizeof(fname);
if(Fget32(rcvbuf,FNAME,0,fname,&len)==-1)
{
userlog("Fget32(FNAME)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
strcat(fname,".s");
if((fp=fopen(fname,"rb"))==NULL)
{
fp=fopen(fname,"wb");
}
elseif(bid==0)
{
fclose(fp);
fp=fopen(fname,"wb");
}
else
{
fclose(fp);
fp=fopen(fname,"r+b");
}
if(fp==NULL)
{
userlog("fopen()%sfailure\n",fname);
tpreturn(TPFAIL,0,0,0,0);
}
fdata=(char*)malloc(bsize+1);
if(fdata==NULL)
{
userlog("malloc(fdata)failure");
tpreturn(TPFAIL,0,0,0,0);
}
len=bsize;
if(Fget32(rcvbuf,FDATA,0,fdata,(FLDLEN32*)&len)==-1)
{
userlog("Fget32(FDATA)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
i=bid*bsize;
if(fseek(fp,i,0)!
=0)
{
userlog("fseek()failure\n");
tpreturn(TPFAIL,0,0,0,0);
}
i=fwrite(fdata,1,len,fp);
if(i!
=len)
{
userlog("fwrite()fail\n");
tpreturn(TPFAIL,0,0,0,0);
}
fclose(fp);
tpreturn(TPSUCCESS,0,NULL,0L,0);
}
客户端程序callcli.c的内容:
#include
#include
#include"atmi.h"
#include"fml32.h"
#include"myfml.h"
FBFR32*sendbuf=NULL;
char*filebuf;
FILE*fp;
log(constchar*fmt,...)
{
va_listap;
va_start(ap,fmt);
vfprintf(stdout,fmt,ap);
fflush(stdout);
va_end(ap);
fclose(fp);
tpfree((char*)sendbuf);
free(filebuf);
tpterm();
exit
(1);
}
main(intargc,char*argv[])
{
longrcvlen=0;
longfilelen=0;
longi=0;
intret=0;
longreallen=0;
longbnum=0;
longbsize=1024;/*传送的块大小为1024字节*/
FLDLEN32len=0;
if(argc!
=2)
{
(void)fprintf(stderr,"Usage:
%sfilename\n",argv[0]);
exit
(1);
}
fp=fopen(argv[1],"rb");
if(fp==NULL)
{
printf("openfile:
%sfailure\n",argv[1]);
exit
(1);
}
if(fseek(fp,0,SEEK_END)!
=0)
{
perror("fseek()failure:
");
exit
(1);
}
filelen=ftell(fp);
if(filelen==-1)
{
perror("ftell()failure:
");
exit
(1);
}
rewind(fp);
if((sendbuf=(FBFR32*)tpalloc("FML32",NULL,bsize+1024))==(FBFR32*)NULL)
{
printf("Errorallocatingsendbuffer\n");
exit
(1);
}
len=Fsizeof32(sendbuf);
if(Finit32(sendbuf,(FLDLEN32)len)==-1)
{
printf("finit32()failure\n");
exit
(1);
}
if(tpinit(NULL)==-1)
{
printf("tpinit()failure");
exit
(1);
}
filebuf=(char*)malloc(bsize);
if(filebuf==NULL)
{
printf("malloc(filebuf)failure");
exit
(1);
}
bnum=(filelen-1)/bsize+1;
if(Fchg32(sendbuf,FNAME,0,argv[1],(FLDLEN32)len)<0)
{
log("Fchg32(FNAME)failure\n",Fstrerror32(Ferror32));
}
printf("filelen=%ld,blocknum=%ld\n",filelen,bnum);
for(i=0;i { if(fseek(fp,i*bsize,0)! =0) { log("fseekfailure\n"); } reallen=fread(filebuf,1,bsize,fp); if(reallen! =bsize&&feof(fp)==0) { log("fread()failure\n"); } if(Fchg32(sendbuf,BID,0,(char*)&i,0)<0) { log("Fchg32(BID)failure: %s\n",Fstrerror32(Ferror32)); } printf("bid=%ld\n",i); if(Fchg32(sendbuf,FDATA,0,filebuf,(FLDLEN32)reallen)<0) { log("Fchg32(FDATA)failure: %s\n",Fstrerror32(Ferror32)); } ret=tpcall("CALL",(char*)sendbuf,0,(char**)&sendbuf,&rcvlen,(long)0); if(ret==-1) { log("tpcall()failure: tperrno=%ld,errstr=%s\n",tperrno,tpstrerror(tperrno)); } } log("finished\n"); } 8.2异步调用方式 如图所示: 在异步请求/回答方式中,客户端使用tpacall()给本地或远程的服务器(由TUXEDO系统根据公告板信息确定)发送服务请求,与同步方式不同的是: 在此方式下,服务器处理请求时,客户端继续运行。 当客户端想得到请求的处理结果时,用tpgetrply()将结果取回。 调用过程如图: 例子: 该例子实现与同步调用方式一样的功能.但在该例子中采用异步通讯方式. 服务端的程序与同步调用方式中的一样,客户端的程序Acallcli.c的内容如下: 注意: 每调用TPACALL()50次之后,就要调用tpgetrply()把服务端返回的结果取出, 否则,返回缓冲区会满,会出如下错误: atpcall()failure: tperrno=5,errstr=TPELIMIT-asystemlimithasbeenreached Acallcli.c的内容: #include #include #include"atmi.h" #include"fml32.h" #include"myfml.h" FBFR32*sendbuf=NULL; char*filebuf; FILE*fp; log(constchar*fmt,...) { va_listap; va_start(ap,fmt); vfprintf(stdout,fmt,ap); fflush(stdout); va_end(ap); fclose(fp); tpfree((char*)sendbuf); free(filebuf); tpterm(); exit (1); } main(intargc,char*argv[]) { longrcvlen=0; longfilelen=0; longi=0; intret=0; longreallen=0; longbnum=0; longbsize=1024;/*传送的块大小为1024字节*/ FLDLEN32len=0; longj=0; intcd[50]; if(argc! =2) { (void)fprintf(stderr,"Usage: %sfilename\n",argv[0]); exit (1); } fp=fopen(argv[1],"rb"); if(fp==NULL) { printf("openfile: %sfailure\n",argv[1]); exit (1); } if(fseek(fp,0,SEEK_END)! =0) { perror("fseek()failure: "); exit (1); } filelen=ftell(fp); rewind(fp); if((sendbuf=(FBFR32*)tpalloc("FML32",NULL,bsize+1024))==(FBFR32*)NULL) { printf("Errorallocatingsendbuffer\n"); exit (1); } len=Fsizeof32(sendbuf); if(Finit32(sendbuf,(FLDLEN32)len)==-1) { printf("finit32()failure\n"); exit (1); } if(tpinit(NULL)==-1) { printf("tpinit()failure"); exit (1); } filebuf=(char*)malloc(bsize); if(filebuf==NULL) { printf("malloc(filebuf)failure"); exit (1); } bnum=(filelen-1)/bsize+1; if(Fchg32(sendbuf,FNAME,0,argv[1],(FLDLEN32)len)<0) { log("Fchg32(FNAME)failure\n",Fstrerror32(Ferror32)); } printf("filelen=%ld,blocknum=%ld\n",filelen,bnum); j=0; for(i=0;i { if(fseek(fp,i*bsize,0)! =0) { log("fseekfailure\n"); } reallen=fread(filebuf,1,bsize,fp); if(reallen! =bsize&&feof(fp)==0) { log("fread()failure\n"); } if(Fchg32(sendbuf,BID,0,(char*)&i,0)<0) { log("Fchg32(BID)failure: %s\n",Fstrerror32(Ferror32)); } printf("bid=%ld\n",i); if(Fchg32(sendbuf,FDATA,0,filebuf,(FLDLEN32)reallen)<0) { log("Fchg32(FDATA)failure: %s\n",Fstrerror32(Ferror32)); } ret=tpacall("CALL",(char*)sendbuf,0,0); if(ret==-1) { log("atpcall()failure: tperrno=%ld,errstr=%s\n",tperrno,tpstrerror(tperrno)); } cd[j]=ret; j++; if(j%50==0) { for(j=0;j<50;j++) { if(tpgetrply(&cd[j],(char**)&sendbuf,&rcvlen,(long)0)==-1) { log("tpgetrply()failure: cd=%ld,errstr=%s\n",cd,tpstrerror(tperrno)); } } j=0; } } log("finished\n"); } 8.3会话方式 采用会话通讯方式,通讯双方在建立连接之后,可以多次发送或接收数据,TUXEDO中采用的是半双工的通讯方式,这种方式特别适用于大批量的数据传输。 名称解释: 发起者(originator,initiator): 发起该会话的进程,它调用tpconnect()与服务端的一个SERVICE建立连接 从属者(subordinate): tpconnect()中指定的SERVICE 发送者(sender): 当前拥有发送权的进程,它只能发送数据 接收者(receiver): 当前拥有发送权的进程,它只能接收数据 函数说明: inttpconnect(char*name,char*data,longlength,longflags) 描述: 与名为name的SERVICE建立连接 参数: name: SERVICE的名字 *data: 要发送的数据 length: 数据的长度 flags: 可以为TPNOTRAN,TPNOTIME,TPNOBLOCK,TPSIGRSTRT TPSENDONLY: 发送者只能发送数据,被调用的SERVICE只能接收数据 TPRECVONLY: 发送者只能接收数据,被调用的SERVICE只能发送数据 返回值: 成功返回一个标识该连接的标识符,失败为-1 inttpsend(intcd,char*data,longlength,longflags,long*revent) 描述: 用于发送数据 参数: cd: tpconnect()的返回值,用于标识该连接 data: 要发送的数据 length: 要发送的数据的长度 flags: (TPNOBLOCK,TPNOTIME,TPSIGRSTRT TPRECVONLY: 把发送权交给接受者,在接受者那里会产生事件TPEV_SENDONLY。 revent: 当返回值为-1时,如果tperrno=TPEEVENT,那么表明有事件发生。 可能的事件有: TPEV_DISCONIMM: 当会话的发起者调用tpdiscon(),tpreturn(),tpcommit()时,会话的 从属者会收到该事件。 如果有网络故障等,那么会话的发起者也会收到该 事件。 TPEV_SVCFAIL: 会话的发起者会收到该事件,表明会话的从属者调用tpreturn(TPFAIL) 或tpreturn(TPEXIT),并且该会话的从属者不在拥有该控制权 TPEV_SVCERR: 会话的发起者会收到该事件,表明会话的从属者调用 tpreturn(TPSUCCESS,..)返回,并且该会话的从属者不在拥有该控制权. 返回值: 失败为-1,如果tperrno=TPEEVENT,那么导致该调用失败的事件保存在revent中 inttprecv(intcd,char**data,long*length,longflags,long*revent) 描述: 用于接收数据 data: 接收的数据放到该缓冲区中 length: 接收大的数据的长度 flags: (TPNOCHANGE,TPNOBLOCK,TPNOTIME,TPSIGRSTRT) revent: 当返回值为-1时,如果tperrno=TPEEVENT,那么表明有事件发生。 可能的事件有: TPEV_DISCONIMM: 与tpsend()中的含义一样. TPRECVONLY: 该会话的发送者把发送权交给接受者,在接受者这里会产生事TPEV_SENDONLY。 TPEV_SVCFAIL: 与tpsend()中的含义一样. TPEV_SVCERR: 与tpsend()中的含义一样. TPEV_SVCSUCC: 该会话的从属者已成功完成并关闭该会话,那么会话的发起者会收到该事件.表明该会话已成功结束. 返回值: 失败为-1,如果tperrno=TPEEVENT,那么导致该调用失败的事件保存在revent中 inttpdiscon(intcd) 描述: 关闭标识符为cd的会话 参数: tpconnect()的返回值,用于标识该连接 返回值: 失败为-1 会话通讯方式的整个过程如图所示: 例子: 该例子实现与同步通讯的例子一样的功能,但采用的是会话通讯方式. 服务端程序的内容: #include #include #include #include"fml32.h" #include"myfml.h" longbsize=1024;/*传送的块大小为1024字节*/ FBFR32*rcvbuf; charfname[256]=""; char*fdata; tpsvrinit(intargc,char**argv) { if((rcvbuf=(FBFR32*)tpalloc("FML32",NULL,(bsize+1024)))==NULL) { userlog("tpallocfai
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第八 TUXEDO 通讯 方式