其实很多客户都在用Tuxedo来进行文件传输,实现的方式大同小异,以下内容比较老了,权当参考。
摘 要: 本文以应用TUXEDO中间件同步调用tpcall和采用FML编程方式为例,介绍了Windows客户端(调用VC++制作的动态链接库)与Unix 服务器之间如何完成文件传输的方法。
关键词: tuxedo tpcall FML动态链接库 UNIX 代写毕业论文
1 引言
近几年来,以交易中间件为框架基础的三层客户机/服务器模式已被广泛证实为建立开放式关键业务应用系统的最佳环境。
TUXEDO 是美国BEA公司的一种交易中间件产品,它在银行、电信、邮政、金融证券等大规模关键事务处理领域中有着广泛的应用。它能够在C/S环境下整合各种异构平台,通过联机事务处理机制,保证交易的完整性和数据的一致性。BEA TUXEDO是在企业、Internet 这样的分布式运算环境中开发和管理三层结构的客户/服务器型关键任务应用系统的强有力工具。
BEA TUXEDO 采用三层结构的客户机/服务器模式组件软件模型,该结构利用交易中间件将应用的业务逻辑、表示逻辑和数据分为三个不同的处理层:客户为第一表示逻辑层,实现用户交互和数据表示,第二层的逻辑业务层为应用的主体,负责业务的逻辑处理,第三层数据层负责对数据库的检索、读取和更新等操作。交易中间件作为构造三层结构应用系统的基础平台,提供了两个主要功能:负责客户机和服务器间的联接和通讯;提供一个三层结构应用开发和运行的平台。由此可见,交易中间件提供了一个基础的框架去帮助你建立、运行和管理一个三层客户机/服务器模式的应用,使你不需要从零做起,大大缩短了应用开发的时间,提高了应用开发的成功率。
本文以应用TUXEDO的同步调用tpcall方式和FML编程方式为例,介绍了在Windows客户端和Unix服务器之间完成文件传输的方法。客户端调用VC++制作的传输文件的tuxedo动态链接库,实现Windows客户端与Unix服务器端传输文件(包括上传和下载文件两种方式)的实现方法。
2 客户端应用TUXEDO实现文件传输方法
在客户端,首先设置客户端与服务器端在文件传输中文件块的大小、文件的块标识等基本信息,将字节数比较大的文件分为很多小块,利用TUXEDO的同步调用 tpcall方式循环调用后台的文件处理服务,将字节数较大的文件按着块的大小分多次传输到UNIX后台。下面以下载文件为例讲解使用tuxedo同步调用tpcall方式完成文件传输的例子。
首先利用TUXEDO的tpalloc申请需要使用的发送和接收缓存,使用Fchg32函数在缓存中放入服务器端需要的域值:文件块的大小、文件的标识等基本信息。
SndBuf = (FBFR32 *)tpalloc("FML32", NULL, 1024); /* 申请发送的缓存 */
iRet = Fchg32(SndBuf,BLOCKSIZE,0,(char *)&lBlockSize,0); /* 设置文件块的大小 */
设置完毕后,开始使用同步tpcall调用UNIX后台文件处理FTPSVR服务。
/* 客户端同步调用UNIX平台文件处理服务*/
iRet = tpcall("FTPSVR",(char *)SndBuf,0L,(char **)&RcvBuf,(long *)&len,0L);
iRet = Fget32(RcvBuf, FILELEN, 0, (char *)&lFileLen, 0);/* 接收文件长度*/
接收文件并将第一块数据写入文件
iRet = Fget32(RcvBuf, FILEDATA, 0, pszFileBuf, (FLDLEN32 *)&lFileDataLen);
fp = fopen(pszCltFileName, "wb+"); /* 创建文件*/
lBlkLen = fwrite(pszFileBuf,1,lFileDataLen,fp); /* 将接收第一块数据写入文件*/
同时计算需要调用下载文件服务的次数,多次调用文件服务,将后续文件下载到客户端。
lBlkNum = (lFileLen -1)/lBlockSize +1 ;
for(i=2; i<lBlkNum+1;i++){
……
iRet = tpcall("FTPSVR",(char *)SndBuf,0L,(char **)&RcvBuf,(long *)&len,0L);
Fget32(RcvBuf, FILEDATA, 0, pszFileBuf, (FLDLEN32 *)&lBlockSize);
lBlkLen = fwrite(pszFileBuf, 1, lBlockSize, fp);
……
}
以下内容需要回复才能看到
3 UNIX服务器端实现方法
在 Unix服务器端,接收客户端发送过来的缓存内容,如:文件块的大小、文件块内容、文件块标识等。根据文件块的标识移动文件指针来写文件,每次文件指针移动的大小由文件块的大小决定,并将读取的文件块的内容放入输出缓存中,并返回给客户端。Unix服务器端程序例子说明如下:
FTPSVR(TPSVCINFO *rqst)
{
…………
RcvBuf = (FBFR32 *)rqst->data; /*指向接收客户端的缓存*/
iRet = Fget32(RcvBuf, BLOCKID, 0, (char *)&lBlockID, 0); /* 接收client发送的块标识*/
fp = fopen(pszSvrFileName, "rb"); /* 打开文件,准备读取*/
(fseek(fp, (lBlockID-1)*lBlockSize, 0)!=0) /* 根据块标识移动文件指针*/
lReadLen=fread(pszFileBuf, 1, lBlockSize, fp); /* 读取文件块*/
Fchg32(SndBuf, FILEDATA, 0, pszFileBuf, (FLDLEN32 )lReadLen); /* 将文件块的内容方式放入tuxedo申请的缓存中*/
tpreturn(TPSUCCESS, 0, (char *)SndBuf, 0L, 0); /* 将输出缓存返回给客户端*/
}
4 WINDOWS平台文件传输的设计
4.1 WINDOWS客户端动态链接库的实现
使用PowerBuilder、Delphi、VB等软件不能直接调用 C语言源代码,它们只能调用动态链接库文件。下面我们讲述如何使用VC++6.0将Windows客户端的文件传输的C、TUXEDO代码制作成动态链接库供Power Builder、Delphi、VB等程序调用。
使用VC++可以制作三种DLL,分别是
(1)Non-MFC Dlls
(2).Regular Dlls
(3)Extension Dlls
Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。因为我们不使用MFC类库,所以采用Non-MFC Dlls。
每一个DLL必须有一个入口点,就象用C编写的应用程序,必须有一个main函数一样. DllMain就是一个缺省的函数入口。
创建一个动态链接库,选择File->New菜单,弹出New对话框。在Projects标签页下,选择“Win32 Dynamic-Link Library”。Visual C++就会创建动态链接库所需的工程文件。
创建ftpfile.def文件,这个文件记录了可被外部应用程序使用的DLL库函数名字。这些名字信息和对应的函数位置的信息将被编译进动态链接库文件中,然后应用程序根据函数名字和函数位置对照表来找到对应的函数。ftpfile.def内容如下:
LIBRARY "ftpfile"
EXPORTS
ftpfile; /*与C代码中的函数名称相同*/
将 ftpfile.def、源程序ftpfile.cpp、头文件public.h和ftpfld.h、tuxedo库文件wtuxws32.lib和 libwsc.lib加入到工程中。选择Project->add to project->files.然后开始编译动态链接库生成ftpfile.dll。
代码样例如下:
BOOL WINAPI DllMain( HMODULE hModule, DWORD dwReason, LPVOID lpvReserved )
/* 动态链接库函数入口*/
{
return TRUE;
}
LRESULT WINAPI ftpfile(char* CltFileName,char* SvrFileName,long lBlockSize,long lOptFlag) /* 动态链接库函数主体*/
{
FBFR32 *RcvBuf,*SndBuf; /*变量声明*/
int iRet;
long i,lBlkLen,len,lFileLen,lBlkNum;
…………
/* 动态链接库程序主体*/
SndBuf = (FBFR32 *)tpalloc("FML32", NULL, MAXBUFLEN); /*申请发送缓存*/
if (SndBuf == NULL)
{
userlog("tpalloc sndbuf error errno=[%d] err=[%s]",tpstrerror(tperrno));
tpterm();
return TPALLOCERR;
}
RcvBuf = (FBFR32 *)tpalloc("FML32", NULL, MAXBUFLEN);/*申请接收缓存*/
iRet = Fchg32(SndBuf,BLOCKSIZE,0,(char *)&lBlockSize,0); /*把块大小放入发送缓存*/
if (iRet <0){ /*错误处理*/
tpfree((char *)SndBuf);
tpfree((char *)RcvBuf);
tpterm();
return FCHGERR;
}
iRet = Fchg32(SndBuf,OPTFLAG,0,(char *)&lOptFlag,0);
……………………………
}/* 程序主体结束*/
4.2 WINDOWS客户端动态链接库的调用
以Power Builder7.0为例,讲述如何在Power Builder中调用文件传输的客户端动态链接库。
首先,在Power Builder声明该函数,声明如下:
Function Integer ftpfile(string CltFileName,string SvrFileName,long lBlockSize,long lOptFlag) LIBRARY "ftpfile.dll"
然后,在程序中就可以应用了。示例如下:
string CltFileName
string SvrFileName
long lBlockSize
long lOptFlag /*设置文件上传或下载标志*/
integer iRet
CltFileName=“..\data\report.txt”
SvrFileName=“../up/form.txt”
LBlockSize=1024
LOptFlag=1
IRet = ftpfile(CltFileName,SvrFileName,lBlockSize,lOptFlag)
If (iret< 0){
messagebox('系统提示',’调用ftpfile函数错误’)
return
}