学习了FML后,自己练手写了一个tuxedo FML32服务器端和客户端程序,供大家参考
											本例是在Redflag DC server 5.0上,使用的是tuxedo9.1,从本地读取一个文件tlr.txt,然后把文件内容以FML32缓冲区方式发送到服务器,由服务器处理后,返回内容增加一个序号。文件内容为:[hwt@localhost fml]$ cat tlr.txt
hwt 29 18677150924
lht 28 13398813422
csq 25 13234234564
服务器处理后,预期结果为:
[hwt@localhost fml]$ ./clientfml tlr.txt
hwt 29 18677150924 33
lht 28 13398813422 42
csq 25 13234234564 21
------------------------------------------------
步骤一:
设置环境变量:
[hwt@localhost fml]$ cat setenv.ksh
TUXDIR=/home/hwt/tux9.1/tuxedo9.1
PATH=$TUXDIR/bin:.:$PATH
export TUXDIR PATH
LD_LIBRARY_PATH=$TUXDIR/lib:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
APPDIR=/home/hwt/fml
TUXCONFIG=$APPDIR/tuxconfig
FIELDTBLS32=fmlfile
FLDTBLDIR32=$APPDIR
export APPDIR TUXCONFIG FLDTBLDIR32 FIELDTBLS32
[hwt@localhost fml]$ . ./setenv.ksh
步骤二:
[hwt@localhost fml]$ cat UBBconfigunix
*RESOURCES
IPCKEY 155442
MAXACCESSERS 50
MAXSERVERS 25
MASTER SITE1
MODEL SHM
*MACHINES
"localhost"
LMID=SITE1
APPDIR="/home/hwt/fml"
TUXCONFIG="/home/hwt/fml/tuxconfig"
TUXDIR="/home/hwt/tux9.1/tuxedo9.1"
*GROUPS
MATHGRP LMID=SITE1
GRPNO=1
*SERVERS
serverfml SRVID=1
SRVGRP=MATHGRP
CLOPT="-A"
*SERVICES
编译UBB:
[hwt@localhost fml]$ tmloadcf -y UBBconfigunix
步骤三:
编写fmlfile文件,这里一定要注意了,字段必须大写,不然调试半天找不到错误原因的:
[hwt@localhost fml]$ cat fmlfile
*base 1000
NAME 1 string - -
AGE 2 long - -
PHONE 3 string - -
NO 4 long - -
编写完毕后,编译文件,会生成fmlfile.h:
[hwt@localhost fml]$ mkfldhdr fmlfile
[hwt@localhost fml]$ cat fmlfile.h
/* fname fldid */
/* ----- ----- */
#define NAME ((FLDID)41961) /* number: 1001 type: string */
#define AGE ((FLDID)9194) /* number: 1002 type: long */
#define PHONE ((FLDID)41963) /* number: 1003 type: string */
#define NO ((FLDID)9196) /* number: 1004 type: long */
步骤四:
编写客户端程序clientfml.c
 程序代码:
程序代码:#include <stdio.h>
#include <string.h>
#include "atmi.h"
#include "fml32.h"
#include "userlog.h"
#include "fmlfile.h"
int main(int argc, char *argv[])
{
 
  if(argc!=2){
    (void)fprintf(stderr,"usage:%s filename\n",argv[0]);
    (void)exit(1);
    }
  FBFR32 *pF32,*pF32rec;
  long len;
  FLDLEN32 len2;
typedef struct tlr
{
  char name[10];
  long age;
  char phone[12];
  long no;
}*pTLR;
  int counter,i,ret;
  FILE *fp;
  char *str1=(char *)malloc(100);
  fp=fopen(argv[1],"r");
  if(fp==NULL){
  (void)fprintf(stderr,"%s: file no found!\n",argv[1]);
  (void)exit(1);
  }
  if (tpinit((TPINIT *)NULL) == -1) {
    (void)fprintf(stderr, "Failed to join application  -- %s\n",
          tpstrerror(tperrno));
    (void)userlog("Clientfml failed to join application  -- %s\n",
          tpstrerror(tperrno));
    (void)fclose(fp);
    (void)exit(1);
  }
  if ((pF32 = (FBFR32 *)tpalloc("FML32", NULL, Fneeded32(1,30))) == NULL) {
    (void)fprintf(stderr, "Failure to allocate FML32 buffer -- %s\n",
          tpstrerror(tperrno));
    (void)userlog("Clientfml failed to allocate FML32 buffer -- %s\n",
          tpstrerror(tperrno));
    (void)tpterm();
    (void)fclose(fp);
    (void)exit(1);
  }
  if ((pF32rec = (FBFR32 *)tpalloc("FML32", NULL, Fneeded32(1,32))) == NULL) {
    (void)fprintf(stderr, "Failure to allocate FML32 buffer -- %s\n",
                  tpstrerror(tperrno));
    (void)userlog("Clientfml failed to allocate FML32 buffer -- %s\n",
                  tpstrerror(tperrno));
    (void)fclose(fp);
    (void)tpterm();
    (void)exit(1);
  }
 pTLR ptlr[3];
 pTLR ptlr2[3];
  for(i=0;i<3;i++){
   ptlr[i]=(pTLR)malloc(sizeof(struct tlr));
    if(ptlr[i]==NULL){
    (void)fprintf(stderr,"mem allocate error!\n");
        (void)fclose(fp);
    (void)exit(1);
    }
   ptlr2[i]=(pTLR)malloc(sizeof(struct tlr));
        if(ptlr2[i]==NULL){
        (void)fprintf(stderr,"mem allocate error!\n");
        (void)fclose(fp);
        (void)exit(1);
        }
  }
  i=0;
  while(fgets(str1,100,fp)!=NULL){
  if((ret=sscanf(str1, "%s %ld %s", ptlr[i]->name, &ptlr[i]->age, ptlr[i]->phone))<3){
  (void)fprintf(stderr,"error in calling sscanf():%d\n",ret);
  (void)fclose(fp);
  (void)exit(1);
  }
  i++;
  }
  for(i=0;i<3;i++){ 
    if (Fadd32(pF32,NAME, (char *)ptlr[i]->name, 0) == -1) {
      (void)fprintf(stderr, "Failure to change NAME field -- %s\n",
            Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to change NAME field -- %s\n",
          Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
    }
 
     if (Fadd32(pF32,AGE, (char *)&ptlr[i]->age, 0) == -1) {
      (void)fprintf(stderr, "Failure to change AGE field -- %s\n",
                  Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to change AGE field -- %s\n",
                  Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
    }
 
      if (Fadd32(pF32,PHONE, (char *)ptlr[i]->phone, 0) == -1) {
      (void)fprintf(stderr, "Failure to change PHONE field -- %s\n",
                  Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to change PHONE field -- %s\n",
                  Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
    }
  }
  if (tpcall("FMLTEST", (char *)pF32, 0, (char **)&pF32rec, &len,0) == -1) {
      (void)fprintf(stderr, "Failure to call the FMLTEST service -- %s \n",
          tpstrerror(tperrno));
      (void)userlog("Clientfml failed to call the FMLTEST service -- %s \n",
          tpstrerror(tperrno));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
  }
  for(i=0;i<3;i++){
    len2=10;
  if (Fget32(pF32rec,NAME, i, (char *)ptlr2[i]->name, &len2) == -1) {
      (void)fprintf(stderr, "Failure to call get the NAME field -- %s \n",
          Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to get the NAME field -- %s \n",
          Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
  }
  len2=sizeof(long);
  if (Fget32(pF32rec,AGE, i, (char *)&ptlr2[i]->age, &len2) == -1) {
      (void)fprintf(stderr, "Failure to call get the AGE field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to get the AGE field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
  }
  len2=12;
  if (Fget32(pF32rec,PHONE, i, (char *)ptlr2[i]->phone, &len2) == -1) {
      (void)fprintf(stderr, "Failure to call get the PHONE field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to get the PHONE field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
  }
  len2=sizeof(long);
  if (Fget32(pF32rec,NO, i, (char *)&ptlr2[i]->no, &len2) == -1) {
      (void)fprintf(stderr, "Failure to call get the NO field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)userlog("Clientfml failed to get the NO field -- %s \n",
                  Fstrerror32(Ferror32));
      (void)tpfree((char *)pF32);
      (void)tpfree((char *)pF32rec);
      (void)free(str1);
      for(i=0;i<3;i++){
      (void)free(ptlr[i]);
      (void)free(ptlr2[i]);
      }
      (void)fclose(fp);
      (void)tpterm();
      (void)exit(1);
  }
    (void)fprintf(stdout,"%s %ld %s %ld\n",ptlr2[i]->name,ptlr2[i]->age,
        ptlr2[i]->phone,ptlr2[i]->no);
  }
  
  (void)tpfree((char *)pF32);
  (void)tpfree((char *)pF32rec);
  (void)free(str1);
  for(i=0;i<3;i++){
  (void)free(ptlr[i]);
  (void)free(ptlr2[i]);
  }
  (void)fclose(fp);
  (void)tpterm();
  return(0);
}
编译客户端程序:$buildclient -o clientfml -f clientfml.c
步骤五:
编写服务器端程序:
 程序代码:
程序代码:#include <stdio.h>
#include "fml32.h"
#include "atmi.h"
#include "userlog.h"
#include "fmlfile.h"
void FMLTEST(TPSVCINFO *msg)
{
struct emp {
char name[10];
long no;
};
  struct emp aa[3]={
  {"hwt",33},
  {"csq",21},
  {"lht",42}
  };
  struct emp bb[3];
  FBFR32 *fP32;
  FLDLEN32 len2;
  float inputnum, result;
  int counter, numofocc,i,j;
  fP32 = (FBFR32 *)msg->data;
  if ((numofocc = Foccur32(fP32,NAME)) == -1) {
    (void)userlog("FMLserver failed to the number of NAME occurrences -- %s\n", Fstrerror32(Ferror32));
    tpreturn(TPFAIL, 0, (char *)fP32, 0L, 0);
  }
  if (numofocc == 0) {
    (void)userlog("FMLserver received 0 NAME occurrences -- %s\n",
        Fstrerror32(Ferror32));
    tpreturn(TPFAIL, 0, (char *)fP32, 0L, 0);
  }
  for (counter = 0; counter < numofocc; counter++) {
     len2 = sizeof(float);
     if (Fget32(fP32,NAME, counter, (char *)bb[counter].name, &len2) == -1) {
        (void)userlog("FMLserver failed to get NAME occ %d field -- %s\n",
          counter, Fstrerror32(Ferror32));
        tpreturn(TPFAIL, 0, (char *)fP32, 0L, 0);
     }
 
   }
  for(i=0;i<3;i++)
    for(j=0;j<3;j++)
    {
    if(strcmp(bb[i].name,aa[j].name)==0){
          if (Fchg32(fP32,NO,i, (char *)&aa[j].no, (FLDLEN32)0) == -1) {
             (void)userlog("FMLserver failed to add NO field -- %s\n",
          Fstrerror32(Ferror32));
             tpreturn(TPFAIL, 0, (char *)fP32, 0L, 0);
            }
      }
    }
  tpreturn(TPSUCCESS, 0, (char *)fP32, 0L, 0);
}
编译服务器端程序:$buildserver -o serverfml -f serverfml.c -s FMLTEST
步骤六:
启动服务:
[hwt@localhost fml]$ tmboot -y
Booting all admin and server processes in /home/hwt/fml/tuxconfig
INFO: BEA Tuxedo, Version 9.1, 32-bit, Patch Level (none)
INFO: Serial #: 454493271161-2664953090480, Expiration NONE, Maxusers 1000000
INFO: Licensed to: Customer
Booting admin processes ...
exec BBL -A :
process id=9898 ... Started.
Booting server processes ...
exec serverfml -A :
process id=9899 ... Started.
2 processes started.
检查一下:
[hwt@localhost fml]$ tmadmin
tmadmin - Copyright (c) 1996-1999 BEA Systems, Inc.
Portions * Copyright 1986-1997 RSA Data Security, Inc.
All Rights Reserved.
Distributed under license by BEA Systems, Inc.
Tuxedo is a registered trademark.
> psc
Service Name Routine Name Prog Name Grp Name ID Machine # Done Status
------------ ------------ --------- -------- -- ------- ------ ------
FMLTEST FMLTEST serverfml MATHG+ 1 SITE1 0 AVAIL
> psr
Prog Name Queue Name Grp Name ID RqDone Load Done Current Service
--------- ---------- -------- -- ------ --------- ---------------
BBL 155442 SITE1 0 0 0 ( IDLE )
serverfml 00001.00001 MATHGRP 1 0 0 ( IDLE )
步骤七:
执行客户端程序:
[hwt@localhost fml]$ ./clientfml tlr.txt
hwt 29 18677150924 33
lht 28 13398813422 42
csq 25 13234234564 21
小结:
本人本来C语言就不是很好,写这程序花了快2天,总结以下问题:
1.指针使用前要提前分配空间(malloc)
2.FML格式文件字段要大写
3.如果读取的是"|"分隔的文件,sscanf中应该用"%[^|]|%ld|%s"这样的格式
程序已经调试通过了,主要是练习FML的用法,希望能对大家学习有帮助。
[ 本帖最后由 khaz 于 2011-4-24 15:47 编辑 ]



 
											






 
	    

 
	


 木有看懂
木有看懂										
					
	
 
											 好!帮了我的大忙了,非常感谢!
好!帮了我的大忙了,非常感谢!