1. 程式人生 > >用Delphi Client和TUXEDO進行檔案傳送

用Delphi Client和TUXEDO進行檔案傳送

在實際的應用中,我們可能需要在客戶端和TUXEDO伺服器之間進行檔案傳輸.在這裡,以Delphi為例介紹了簡要的檔案傳送的方法,算是一個Demo,為大家實現檔案的傳輸做一個參考.在這之前之前,認為你已經實現了Delphi的FML客戶端,能夠通過FML和服務交換資料.
  在檔案傳輸的時候,我們採用的是TUXEDO的CARRAY型別,CARRAY是平臺獨立的,非常適合異構系統之間的資料傳輸,特別是圖片,聲音等非文字檔案.下面的例子中我們將一個JPG的圖片檔案從Windows傳到UNIX.

這裡用到的幾個FML欄位的Delphi宣告如下:
FILEDATA = FLDID32(201327137); // number: 545 type: carray
//這個用來放檔案的資料
RESULT = FLDID32(167772661); // number: 501 type: string
REASON = FLDID32(167772662); // number: 502 type: string
//以上兩個用來返回傳送的結果和失敗時的原因.

先來看看客戶端的程式[主要部分].
implementation
const DataLen = 256;

procedure TForm1.Button1Click(Sender: TObject);
var
PicData, SendBuf: Pointer;
SvcName: array[0..14] of Char;
ret: Integer;
rlen: LongInt;
ms: TMemoryStream;
fsize: Int64;
TempInt: LongInt;
TempPChar: array[0..255] of Char;
TempStr: String;
ldlen: FLDLEN32;
TempBuf: array[0..255] of Char;
pBuf: PChar;

begin

StrPCopy(TempBuf, 'WSNADDR=//ip:port');
//這裡的ip和port根據實際情況指定.
tuxputenv(@TempBuf);

ret := tpinit(0);
if ret = -1 then
begin
showmessage('tpinit failed!');
Exit;
end;

//開闢檔案的記憶體空間 和 SendBuf
PicData := tpalloc('CARRAY', nil, 1024*1024);
SendBuf := tpalloc('FML32', nil, 2048*1024);

//讀取資料檔案到PicData指定的記憶體,fsize為檔案長度
ms := TMemoryStream.Create();
ms.LoadFromFile('pic.jpg');
fsize := ms.Size;
showmessage('fsize: ' + inttostr(fsize));

TempInt := ms.Read(PicData^, LongInt(fsize));
Memo1.SetTextBuf(PicData);
showmessage('read to buffer: ' + IntToStr(TempInt));
ms.Free;

//將檔案資料放入FML SendBuf
ret := Fchg32(SendBuf, FILEDATA, 0, PicData,FLDLEN32(TempInt));

{call service}
TempStr := 'TESTFILE';
strpCopy(SvcName, TempStr);
ret := tpcall(SvcName, SendBuf, 0, @SendBuf, @rlen, 0);
if ret = -1 then
begin
showmessage('tpcall failed!');
tpfree(sendbuf);
tpterm();
Exit;
end;

{get return data}
pBuf := @TempBuf;
Fillchar(TempBuf, DataLen, 0);

{get RESULT & REASON}
ldlen := DataLen;
Fget32(SendBuf, RESULT, 0, pBuf, @ldlen);
showmessage('RESULT: ' + StrPas(pBuf));
ldlen := DataLen;
Fget32(SendBuf, REASON, 0, pBuf, @ldlen);
showmessage('REASON: ' + StrPas(pBuf));

{free buffer and leave the application}
tpfree(sendbuf);
tpterm();

end;

注:關於用到的DLL中TUXEDO函式的Delphi宣告已經在其它unit中做了,是同名的,這裡直接使用了.這裡還有一個地方需要注意的是使用CARRAY型別的欄位時,在Fadd32或者Fchg32放入buffer是,最後一個引數是檔案的大小.這個引數只有在CARRAY型別的時候才要,其它型別置0就可以.

接下來我們看一下server端的程式碼,和client一樣,這裡列出主要的程式碼:
unsigned long len;
long i;
int ret;
char* sbuf;
FBFR32 *iFML;
FILE * fp;

//獲得資料的指標
iFML = (FBFR32 *)rqst->data;
//開buffer用於存放檔案
sbuf = tpalloc((char *)"CARRAY", NULL, 1024*1024);
len = 1024*1024;
//從FML中讀出檔案的資料到buffer
ret = Fget32(iFML, FILEDATA, 0, sbuf, &len);

//寫入磁碟檔案
fp = fopen("pic.jpg","wb");
for (i = 0; i < len; i++)
fputc(sbuf[i], fp);
fclose(fp);

//然後返回處理結果

完成以上的過程,我們就可以自己試驗了,檔案傳到UNIX後,我用FTP工具取下來,圖片的資訊仍完好.
以上程式碼的環境是:
Client: Win 2000 + TUXEDO 8.1 + Delphi 7
Server: HP-UX 11 + TUXEDO 8.0