서버 프로그램

본 장에서는 서버 프로그램의 흐름과 특징, 구성에 대해서 설명한다.

1. 프로그램 특징 및 구성

서버 프로그램은 사용자의 요청을 받아서 처리하고 그 응답을 클라이언트에게 반환하는 프로그램이다.

Tmax 서버 프로그램은 다음과 같은 특징을 갖는다.

  • 개발자는 서비스 루틴만을 개발하면 되기 때문에 개발이 용이하고 기간을 단축한다.

  • 서버는 하나 이상의 서비스로 이루어지고 서버 자신이 클라이언트가 되어 다른 서버에 서비스를 요청할 수 있다. 클라이언트의 정보와 결과를 모두 보내어 클라이언트의 관리를 넘길 수도 있다.

  • Tmax 함수가 통신 및 데이터 변환을 제공하므로 개발자는 UNIX 내부 시스템과 프로토콜을 생성하지 않아도 되고 네트워크 프로그래밍에 대한 이해 없이도 프로그램 개발이 가능하다.

  • XA 모드의 경우 데이터베이스 연결과 해제가 Tmax가 관리하는 루틴에서 관리되기 때문에 개발자는 데이터베이스 연결과 관리에 대해 신경쓰지 않아도 된다.

Tmax 응용 서버 프로그램은 Tmax에서 제공하는 main()과 개발자가 작성한 업무처리 서비스 루틴으로 구성된다. 서버 프로그램은 응용 클라이언트 프로그램처럼 Tmax 함수를 이용하여 작성된다. 이 함수들은 라이브러리(libsvr.a, libsvr.so)로 제공되며 응용 서버 프로그램과 같이 컴파일된다. 서버 프로그램은 Tmax가 지원하는 프로세스 유형에 따라서 구성과 개발 방법이 다르다.

다음은 Tmax에서 지원하는 서버 프로세스 유형이다.

figure process type
Tmax 서버 프로세스 유형
  • TCS(Tmax Control Server)

    클라이언트 요청에 따라 프로세스를 처리한다.

  • UCS(User Control Server)

    TCS가 수동적인 방법인 반면, UCS는 능동적인 프로세스 처리 방법으로 클라이언트의 요청 없이 클라이언트에게 지속적으로 데이터를 보낸다.

    • RDP(Realtime Data Processor)

      특정한 용도를 위해 UCS 타입의 프로세스를 개량한 방법이다.

1.1. TCS

TCS 서버 프로그램은 다음과 같은 구성된다.

  • 서버 프로그램

    개발자가 작성한 서비스 루틴이다. 클라이언트의 요청을 처리한다. SQL 문을 사용하였다면 해당 데이터베이스 벤더가 제공하는 툴을 사용하여 프리 컴파일을 완료해야 한다.

  • Tmax 서버 라이브러리(libsvr.a / libsvr.so)

    Tmax에서 제공하는 서버 라이브러리로 서버 main()과 tpsvrinit(), tpsvrdone() 그리고 각종 Tmax 함수들이 있다.

  • 서비스 테이블

    서비스 테이블은 서버마다 제공되는 서비스명들이 나열되어 있는 파일로서 Tmax 환경 파일을 참조하여 생성한다. 서비스 테이블은 서비스를 수행할 때 실제적으로 서버 내에서 해당 서비스 루틴의 위치를 찾기 위해 사용되며 시스템 관리자가 제공한다.

    서비스 테이블을 작성하는 방법은 다음과 같다.

    1. 이진화된 Tmax 환경 파일(예: tmconfig)을 참조하여 gst(generate service table) 명령어를 사용한다.

      gst [-f binary configuration file]

      gst를 수행하면 Tmax 디렉터리 하위의 svct 디렉터리에 Tmax 환경 파일의 SERVER 절에 등록된 서버별로 "서버명_ svctab.c"라는 서비스 테이블이 생성된다. 이는 SERVICE 절을 참조하여 서버별로 제공하는 서비스들이 등록되어 있다.

    2. 이진화된 Tmax 환경 파일(tmconfig)은 시스템 관리자가 작성한 시스템 전체 구성에 대한 텍스트 파일(sample.m)을 cfl 명령어로 컴파일한 후 생성된다.

      $cfl [-i Tmax 환경 파일]

      cfl 및 서비스 테이블에 대한 자세한 내용은 Tmax Administration Guide를 참고한다.

  • 구조체 바이너리 테이블(SDLFILE)

    구조체형 버퍼(STRUCT, X_C_TYPE, X_COMMON)를 사용했다면 이를 정의하는 <xxxx.s> 형식의 구조체 파일이 필요하다. 구조체 파일은 표준 통신 타입(구조체 파일명_sdl.c)과 구조체 헤더 파일(구조체 파일명_sdl.h)이 있다.

    구조체 파일은 sdlc –c 명령어를 이용하여 컴파일하며 그 결과 구조체의 멤버들을 표준 통신형으로 변환하는 데 필요한 바이너리 테이블 파일이 생성된다. 이는 서버 프로그램을 실행할 때에 구조체형의 데이터를 표준 통신형으로 변환/역변환하는 데 사용된다.

  • 필드 버퍼 바이너리 테이블(FDLFILE)

    필드 버퍼를 사용했다면 <xxxx.f> 형식으로 정의된 필드 버퍼 파일이 필요하다.

    필드 버퍼 파일은 fdlc 명령어를 이용하여 컴파일하며 그 결과 필드키와 데이터를 대응시켜주는 바이너리 테이블 파일과 필드키와 필드키명을 대응시켜주는 헤더 파일(xxxx_fdl.h)이 생성된다. 기존의 구조체 파일과는 달리 사용자가 원하는 필드의 값만을 조작하고 전달할 수 있으므로 다양한 타입의 데이터를 사용하는 경우 자원의 낭비를 줄일 수 있다. 하지만 데이터 값과 필드키 값을 같이 관리하므로 많은 필드를 사용하지 않는다면 역효과가 발생할 수도 있다.

  • 구조체-표준 버퍼 변환/역변환 프로그램

    서버 프로그램 내에서 구조체 버퍼를 사용하기 위해서는 sdlc 명령어로 생성된 구조체-표준 버퍼 변환/역변환 프로그램(xxxx_sdl.c, xxxx_sdl.h)을 컴파일하여 같이 링크해야 한다. 구조체를 사용하지 않을 경우에는 TMAXDIR/lib/sdl.o를 링크하도록 한다.

1.2. UCS

UCS 서버 프로그램은 Tmax에서 관리하는 main() 루틴과 서비스 루틴, usermain() 루틴으로 구성된다.

  • main() 루틴

    데이터베이스 연결 및 해제, 명령어 라인 옵션 처리 등의 역할을 한다.

  • 서비스 루틴

    실제로 클라이언트의 요청을 받아 업무를 처리한다.

    다음은 서비스 루틴을 선언하는 방법이다.

    <서비스명>(TPSVCINFO *msg)
    항목 설명

    <서비스명>

    NULL 종료 문자를 포함하여 63자 이내이며 언더스코어(_)로 시작되는 이름은 Tmax에서 내부적으로 사용하므로 사용하지 않도록 한다.

    msg

    서비스 루틴은 TPSVCINFO 구조체를 파라미터로 받아 해당 작업을 수행해야 한다.

  • usermain() 루틴

    usermain() 루틴은 서비스 요청이나 제어 메시지와 같은 특별한 메시지가 없는 동안에 독자적인 작업을 수행한다. 일정 시점에 스케줄링 API를 통하여 TMM, CLH로부터의 제어 명령이나 서비스 수행 명령을 처리한다. usermain()이 종료될 경우 해당 서버 프로세스 역시 종료되므로 일반적으로 무한 루프(Loop) 형식으로 작성된다. 클라이언트의 서비스 요청이나 TMM, CLH 제어 메시지를 처리하기 위해 이 무한 루프 안에는 반드시 하나 이상의 스케줄링 API가 사용되어야 한다.

    usermain()은 명령어 라인 파라미터를 받을 수 있으며 이 값은 Tmax 시스템 환경 파일의 SERVER 절의 CLOPT 항목에 설정된 값으로 tpsvrinit()에 전달되는 값과 동일하다. usermain()이 종료되면 main() 루틴은 tpsvrdone() 루틴을 수행하고 같이 종료된다.

    int usermain(int argc, char *argv[])
    {
           .....
           while(1) {
                 ......
                 tpschedule(-1);
                 .....
           }
           return 0;
    }

    UCS 방식 서버 프로그램의 경우 서비스 루틴은 존재하지 않아도 무관하며 이 경우 서버 프로세스는 데몬 프로세스와 비슷한 성격을 갖게 된다.

    다음은 TOUPPER의 서비스 루틴을 선언하는 예제이다.

    TOUPPER(TPSVCINFO *msg)
    {
        .....
    }

SERVER 절에 대한 자세한 내용은 Tmax Administration Guide를 참고한다.

2. 개발 환경 및 툴

Tmax 응용 서버 프로그램의 OS 환경은 하드웨어와는 무관한 모든 UNIX 기종을 지원하고 UNIX 표준 편집기인 vi로 개발이 가능하다.

3. 프로그램 흐름

Tmax 서버 프로그램의 흐름은 TCS 방식과 UCS 방식에 따라 다르게 진행된다. 일반적인 서버 프로그램인 TCS 방식의 경우 서비스 루틴 안에서 모든 처리가 일어나지만 UCS 방식 서버 프로그램의 경우는 서비스 루틴과 usermain()을 적절히 사용하여 기존에는 구현하기 힘들었던 다양한 방식의 서비스를 제공할 수 있다. 서버 프로그램은 크게 Tmax에서 제공하는 main() 루틴과 개발자가 개발하는 서비스 루틴으로 나눌 수 있다.

figure 1 2
서버 프로그램 흐름
  • main() 루틴

    main() 루틴은 명령어 라인에 입력된 파라미터 처리, 연결된 데이터베이스 연결 및 해제 역할, 서비스 루틴에서 사용할 버퍼를 할당한다. 그리고 클라이언트 요청을 처리하는 서비스 루틴을 호출하는 역할을 한다.

  • 서비스 루틴

    서비스 루틴은 클라이언트의 요청을 처리한다. 클라이언트의 요청은 먼저 main()에서 서비스 요청과 관련된 정보를 가지고 있는 TPSVCINFO 구조체로부터 받는다. 클라이언트가 요구한 버퍼의 내용은 TPSVCINFO→DATA에 있다. 서비스 루틴에서는 TPSVCINFO→DATA에서 데이터를 받아서 요청 기능을 처리한 후 결과를 클라이언트에게 전달하거나, 또 다른 처리를 위하여 다른 서버에 서비스 처리를 요구한다.

    서비스 루틴에서 사용하는 함수에 대한 자세한 사항은 Tmax Reference Guide 또는 Tmax Programming Guide(UCS)를 참고한다.

3.1. TCS

TCS 프로세스는 보통의 3-Tier 개념을 가진 서버 프로세스이다. Tmax 시스템은 요청한 결과를 수신하고 그것을 클라이언트에게 반환하는 적절한 프로세스에 클라이언트의 요청을 스케줄한다. Tmax는 TCS 방식의 서비스 프로그램을 위한 main() 함수를 제공하기 때문에 개발자는 서비스 루틴만을 개발한다. TCS 방식 프로그램은 지정된 서비스명을 함수로 하여 개발한다.

TCS 방식의 main() 루틴과 서비스 루틴은 다음과 같다.

figure 1 3
TCS 방식 서버 프로그램 흐름
  • main() 루틴

    Tmax에서 관리하는 main() 루틴에서는 명령어 라인에 입력된 인수 처리, 필요할 경우 데이터베이스와의 연결과 해제 작업이 이루어지며 서비스 루틴에서 사용하는 TPSVCINFO 구조체 버퍼를 할당하고 관리한다. TMM, CLH로부터 전해지는 메시지를 기다리며 서비스 요청이 오면 데이터를 받아 서비스 루틴을 호출하여 실제 서비스가 이루어지도록 한다.

  • 서비스 루틴

    서비스 루틴은 클라이언트의 요청을 처리한다. main()에서는 클라이언트로부터 받은 서비스 요청을 여러 가지 정보와 함께 TPSVCINFO 구조체에 넣어 서비스 루틴에 전달하며 서비스 루틴은 서비스 수행의 결과를 클라이언트에게 전달한다.

다음은 TCS 방식 프로그램의 예제이다.

SDLTOUPPER(TPSVCINFO *msg)
{
        ...
        struct  kstrdata *stdata;
        stdata = (struct kstrdata *)msg->data;
        ...
        for (i = 0; i < stdata->len; i++)
            stdata->sdata[i] = toupper(stdata->sdata[i]);
        ...
        tpreturn(TPSUCCESS,0,(char *)stdata, sizeof(struct kstrdata), TPNOFLAGS);
}

3.2. UCS

전형적인 TCS 방식 프로세스는 단지 클라이언트에서 요구한 일을 처리하는 수동적인 타입이지만, UCS는 클라이언트의 요청 없이도 연결하여 서비스를 제공한다. UCS는 서비스를 신속하게 제공할 수 있고 TCS 방식을 지원하여 더 많은 기능들을 제공할 수 있다. UCS 방식 프로그램은 usermain()과 서비스 루틴을 구성하고 있다.

UCS 방식의 main() 루틴과 서비스 루틴은 다음과 같다.

figure 1 4
UCS 방식 서버 프로그램 흐름
  • main() 루틴

    UCS 방식 main() 루틴은 TCS 방식과 유사하며 추가적으로 usermain() 루틴을 갖고 있다.

  • 서비스 루틴

    서비스 루틴은 TCS와 동일하고 UCS 방식 프로세스는 UCS 라이브러리(libsvrucs.a, 멀티 스레드를 사용할 경우 libsvrucsmt.a)와 링크되어 있어야 한다.

  • usermain() 루틴

    UCS 방식의 usermain() 루틴은 다른 명령이 없는 동안 독자적으로 반복적인 작업을 수행하며 스케줄링 API를 사용하여 CLH나 TMM으로부터 오는 명령들을 처리해준다. UCS 방식 프로세스가 tmdown 명령어를 사용하여 정상적으로 종료되기 위해서는 루프되는 동안 tpschedule()을 사용해야 한다.

    다음은 usermain() 함수의 예제이다.

    ...
    int usermain(int argc, char *argv[])
    {
            ...
            while (1) /* 무한 루프 */
            {
                clid = tpgetclid();
                ret = tpsendtocli(clid, sndbuf, slen, TPNOFLAGS);
                if (ret < 0)
                {
                    error processing routine
                }
                ...
                tpschedule(10); /* UCS 프로세스는 while loop에 이 함수를 추가해야 한다.*/
                /* 만약 tmdown을 호출하면 이벤트를 여기로 보낸다. */
                ...
            } /* end of while */
    }
    • 기본적으로 usermain()은 루프되고 있는 작업을 처리한다. usermain()은 특정 클라이언트에게 데이터를 보내기 위해 tpsendtocli()를 사용하고 TCS 방식 서비스를 처리하기 위해 tpschedule()을 사용한다.

    • tpschedule()은 UCS 방식 서버 프로세스에서만이 사용되는 함수이다.

      타임아웃 파라미터를 가진 함수는 타임아웃(초)만큼 데이터를 기다리다 데이터가 도착하면 즉시 반환하고 그 시간 안에 도착하지 않으면 타임아웃 적용을 받는다. (단위 : 초)

      파라미터가 '–1’로 설정된 경우에는 반환된 데이터가 있는지 여부에 대해 체크하고, 만약 데이터를 받지 않았다면 다음 단계로 반환한다. 파라미터가 '0’으로 설정된 경우에는 클라이언트의 요청을 받을 때까지 기다린다.

      tpschedule() 함수는 데이터가 도착했을 때 해당되는 서비스가 자동적으로 수행되고 난 후에 반환된다. 그러므로 데이터가 도착한 후에 사용자가 임의로 서비스를 수행하지 말아야 한다. 서비스는 무조건 시스템에 의해서 수행되므로 UCS 방식의 서비스 프로그램이라도 이점을 주의한다.

    • usermain()에서 비동기 통신(tpacall)으로 서비스를 호출할 경우 그에 대한 응답은 tpregcb() 함수로 받아야 한다.

다음은 UCS 방식 프로세스를 사용하기 위한 Tmax 환경 파일의 예제이다.

*DOMAIN
res1        SHMKEY = 66999, MAXUSER = 256

*NODE
tmax       TMAXDIR = "/user/tmax",
           APPDIR  = "/user/tmax/appbin",
           PATHDIR = "/user/tmax/path",
           TLOGDIR = "/user/tmax/log/tlog",
           ULOGDIR = "/user/tmax/log/ulog",
           SLOGDIR = "/user/tmax/log/slog"

*SVRGROUP
svg1        NODENAME = tmax

*SERVER
svr1         SVGNAME = svg1

#UCS 방식 프로세스는 SVRTYPE = UCS라는 항목을 추가해야 한다.
ucssvr1      SVGNAME = svg1, SVRTYPE = UCS
ucssvr2      SVGNAME = svg1, SVRTYPE = UCS
ucssvr3      SVGNAME = svg1, SVRTYPE = UCS

*SERVICE
TOUPPER      SVRNAME = svr1
TOLOWER      SVRNAME = svr1
DUMY1        SVRNAME = ucssvr1
DUMY2        SVRNAME = ucssvr2

다음은 UCS 방식 프로그램의 예제이다.

#include    <stdio.h>
#include    <usrinc/atmi.h>
#include    <usrinc/ucs.h>

DUMY1(TPSVCINFO *msg)
{
        printf("svc start!");
        tpreturn(TPSUCCESS, 0, (char *)msg->data, 0, TPNOFLAGS);
}

int usermain(int argc, char *argv[])
{
        ...
        while (1) {
            jobs = tpschedule(-1);
            cnt++;
            ...
            ret = tpcall("TOUPPER", sbuf, 0, &rbuf, &rlen, TPNOFLAGS);
            if (ret < 0) {
                error processing routine
            }
        }
}

RDP

RDP는 지속적으로 변하는 데이터를 클라이언트에게 효율적이고 빠르게 전달하기 위해 UCS 방식의 프로세스를 커널 수준에서 개량한 서버 프로세스이다. 소량의 데이터를 다수의 클라이언트에게 자주 보낼 필요가 있을 때(초당 10회 이상) 프로세스 점유율이나 처리 속도의 측면에서 월등한 성능을 보인다. 한 노드에는 하나의 RDP 방식 서버만을 사용할 수 있다. RDP는 형식상 UCS와 동일하며 환경 파일의 설정과 컴파일할 때 라이브러리만 다르다.

다음은 RDP 방식 프로세스를 사용하기 위한 Tmax 환경 파일에 대한 예제이다.

*DOMAIN
tmax1   SHMKEY = 7090, MINCLH = 2, MAXCLH = 2

*NODE
tmax1   TMAXDIR = "/home/navis/tmax",
        APPDIR = "/home/navis/tmax/appbin",
        PATHDIR = "/home/navis/tmax/path",
        TLOGDIR = "/home/navis/tmax/log/tlog",
        ULOGDIR = "/home/navis/tmax/log/ulog",
        SLOGDIR = "/home/navis/tmax/log/slog",
        REALSVR = "real",rscpc = 2

RDP에 대한 자세한 설명은 Tmax Administration Guide 또는 Tmax Programming Guide(UCS)를 참고한다.

4. 프로그램 컴파일

개발자가 서버 프로그램의 작성을 완료하면 컴파일하여 실행 파일을 생성한다. 서버 프로그램을 컴파일하기 위해서는 개발자가 작성한 서버 프로그램, Tmax 서버 라이브러리, 서비스 테이블이 필요하다. 구조체 버퍼를 사용한 경우는 구조체-표준 버퍼 변환/역변환 프로그램과 구조체 바이너리 테이블이 있어야 하고 필드 버퍼를 사용했다면 필드 버퍼 헤더 파일과 필드 버퍼 바이너리 테이블이 있어야 한다. 서버 프로그램 컴파일 방법은 TCS 방식과 UCS 방식으로 나누어 설명한다.

4.1. TCS

일반적인 C 컴파일러를 이용한 컴파일 방법으로 Tmax를 설치하면 생성되는 셸 프로그램을 사용하거나 mksvr 유틸리티를 사용하여 간단하게 컴파일할 수 있다.

다음은 구조체 버퍼와 필드 버퍼를 사용하는 서버 프로그램의 작성 순서를 나타낸 그림이다.

figure 6 2
서버 프로그램 컴파일 - 구조체 버퍼
figure 6 3
서버 프로그램 컴파일 - 필드 버퍼

다음 예제는 Linux에서의 실행 예제이며 개발 환경(32/64Bit)과 플랫폼에 따라 사용되는 flags 및 라이브러리가 조금씩 다르다.

  1. 서버 프로그램을 컴파일하여 오브젝트 파일을 생성한다.

    서버 프로그램은 Tmax에서 제공하는 헤더 파일들을 참조해야 하며 필요에 따라 구조체 파일이나 필드 버퍼 헤더 파일도 참조되어야 한다. SQL 문을 사용했다면 먼저 해당 데이터베이스 벤더가 제공하는 툴로 프리 컴파일을 완료해야 한다.

    $cc -c -I/home/tmax/usrinc app.c        → app.o
  2. 구조체 통신인 경우 구조체 파일을 컴파일한다.

    이 단계는 sdlc을 이용하여 구조체-표준 버퍼 변환/역변환 프로그램을 생성하는 단계와 생성한 프로그램을 다시 오브젝트 파일로 컴파일하는 2단계로 이루어진다. 구조체 파일을 사용하지 않는다면 TMAXDIR/lib/sdl.o를 사용한다.

    $sdlc -i demo.s -> demo_sdl.c
    $cc -c -I/home/tmax/usrinc demo_sdl.c → demo_sdl.o
  3. 시스템 관리자가 제공한 서비스 테이블을 컴파일하여 오브젝트 파일을 생성한다.

    $cc -c app_svctab.c → app_svctab.o
  4. 1, 2, 3 과정에서 생성된 오브젝트 파일들과 Tmax 시스템에서 제공하는 서버 라이브러리를 함께 링크하여 서버 실행 프로그램을 생성한다.

    $cc -o app app.o demo_sdl.o app_svctab.o libsvr.a libnodb.a → aptest

셸 프로그램을 사용한 컴파일

Tmax를 설치하면 예제 서버 프로그램 디렉터리에는 기본적으로 예제 프로그램 외에 4개의 Makefile과 이를 이용하는 셸 프로그램이 설치된다(Makefile.c, Makfile.sdl, Makfile.pc, Makefile.psdl, compile).

다음은 구조체 버퍼를 사용하고 데이터베이스를 사용하지 않는 Tmax 서버 프로그램 Makefile(Makefile.sdl)의 예이다. $COMP_TARGET에는 개발한 프로그램명이 들어가며 셸 프로그램 컴파일을 사용하여 전달한다.

# Server makefile

TARGET = $(COMP_TARGET)
APOBJS = $(TARGET).o
SDLFILE = demo.s

#Not use Db
LIBS    = -lsvr -lnodb
#Solaris의 경우 –lsocket –lnsl 이 추가된다.
#Oracle의 경우 –lnodb 대신 -loras, Informix 의 경우 –linfs
#Db2의 경우 –ldb2, Sybase 의 경우 –lsybs 가 들어간다.

OBJS    = $(APOBJS) $(SDLOBJ) $(SVCTOBJ)

SDLOBJ  = ${SDLFILE:.s=_sdl.o}
SDLC    = ${SDLFILE:.s=_sdl.c}
SVCTOBJ = $(TARGET)_svctab.o

CFLAGS  = -O -I$(TMAXDIR)
#CFLAG 는 사용 환경(32/64비트)과 플랫폼에 따라 다르다.
#Solaris 32bit, Compaq, Linux: CFLAGS = -O –I$(TMAXDIR)
#Solaris 64bit: CFLAGS = -xarch=v9 -O –I$(TMAXDIR)
#HP 32bit: CFLAGS = -Ae -O –I$(TMAXDIR)
#HP 64bit: CFLAGS = -Ae +DA2.0W +DD64 +DS2.0 -O –I$(TMAXDIR)
#IBM 32bit: CFLAGS = -q32 –brtl -O –I$(TMAXDIR
#IBM 64bit: CFLAGS = -q64 –brtl -O –I$(TMAXDIR

APPDIR  = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svct
LIBDIR  = $(TMAXDIR)/lib
#64비트 환경을 사용하는 경우 $(TMADIR)/lib64 가 된다.

#
.SUFFIXES : .c

.c.o:
        $(CC) $(CFLAGS) -c $<

#
# server compile
#

$(TARGET): $(OBJS)
        $(CC) $(CFLAGS) -L$(LIBDIR) -o $(TARGET) $(OBJS) $(LIBS)
        mv $(TARGET) $(APPDIR)/.
        rm -f $(OBJS)

$(APOBJS): $(TARGET).c
        $(CC) $(CFLAGS) -c $(TARGET).c

$(SVCTOBJ):
        touch $(SVCTDIR)/$(TARGET)_svctab.c
        $(CC) $(CFLAGS) -c $(SVCTDIR)/$(TARGET)_svctab.c

$(SDLOBJ):
$(TMAXDIR)/bin/sdlc -i ../sdl/$(SDLFILE)
        $(CC) $(CFLAGS) -c ../sdl/$(SDLC)

#
clean:
        -rm -f *.o core $(TARGET)

각 Makefile의 사용법은 다음과 같다. svr1, svr2, svr3, fdltest, sdltest는 모두 Tmax 설치할 때 제공되는 샘플 프로그램이다. 자세한 내용은 해당 Makefile을 참고한다.

$./compile sdl svr1
$./compile c svr2
$./compile c svr3
$./compile pc fdltest
$./compile psdl sdltest

mksvr 유틸리티를 사용한 컴파일

mksvr 유틸리티를 사용하는 경우 Tmax 시스템 환경 파일을 작성할 때 미리 서비스명을 설정할 필요가 없으며 gst를 이용한 서비스 테이블 생성 과정도 필요로 하지 않는다. 그러나 구조체를 사용하는 경우 구조체-표준 버퍼 변환/역변환 프로그램은 미리 생성되어 있어야 하며 데이터베이스를 사용할 경우 미리 프리 컴파일 과정이 끝난 파일을 사용하거나 RM 파일을 지정해야 한다.

$cfl –i sample.m

$sdlc –i demo.s
$sdlc –c –i demo.s –o tmax.sdl
$mksvr –s SDLTOUPPER,SDLTOLOWER –o svr1 –f svr1.c –S ../sdl/demo_sdl.c

$mksvr –s TOUPPER,TOLOWER –o svr2 –f svr2.c

$fdlc –c –i demo.s –o tmax.fdl
$mksvr –s FDLTOPPER, FDLTOLOWER –o svr3 –f svr3.c

$proc iname=fdltest include $TMAXDIR
$mksvr –s FDLINS,FDLSEL,FDLDEL,FDLUPT –o fdltest –f fdltest.c

$mksvr –s SDLINS,SDLSEL,SDLDEL,SDLUPT –o sdltest –f sdltest.c
–S ../sdl/demo_sdl.c –r ORACLE

mksvr에 대한 자세한 내용은 Tmax Reference Guide를 참고한다.

4.2. UCS

UCS 서버 프로그램의 컴파일은 TCS 서버 프로그램과 크게 다르지 않다. 준비 사항과 컴파일 순서는 동일하고 서버 라이브러리를 libsvr.a(혹은 libsvr.so)가 아닌 libsvrucs.a (혹은 libsvrucs.so)를 사용한다. 멀티 스레드 UCS 서버를 사용해야 하면 libsvrucs.a(혹은 libsrucs.so)가 아닌 libsvrucsmt.a(혹은 libsvrucs.so)를 사용해야 한다. 일반적인 C 컴파일러를 이용한 컴파일 방법으로 셸 프로그램을 사용하거나 mksvr 유틸리티를 이용하면 간단하게 컴파일할 수 있다.

다음 예제는 Linux에서의 실행 예제이며 개발 환경(32/64Bit)과 플랫폼에 따라 사용되는 flags 및 라이브러리가 조금씩 다르다. 사용 라이브러리를 제외하고는 TCS 방식과 완전히 동일하므로 자세한 내용은 TCS를 참고한다.

  1. 서버 프로그램을 컴파일하여 오브젝트 파일을 생성한다.

    서버 프로그램은 Tmax에서 제공하는 헤더 파일들을 참조해야 하며 필요에 따라 구조체 파일이나 필드 버퍼 헤더 파일도 참조되어야 한다. SQL 문을 사용했다면 먼저 해당 데이터베이스 벤더가 제공하는 툴로 프리 컴파일을 완료해야 한다.

    $cc -c -I/home/tmax/usrinc app.c        → app.o
  2. 구조체 통신인 경우 구조체 파일을 컴파일한다.

    이 단계는 sdlc을 이용하여 구조체-표준 버퍼 변환/역변환 프로그램을 생성하는 단계와 생성한 프로그램을 다시 오브젝트 파일로 컴파일하는 2단계로 이루어진다. 구조체 파일을 사용하지 않는다면 이 과정을 수행할 필요없이 TMAXDIR/lib 디렉터리 내의 <sdl.o>를 사용하여 같이 컴파일한다.

    $sdlc -i demo.s -> demo_sdl.c
    $cc -c -I/home/tmax/usrinc demo_sdl.c → demo_sdl.o
  3. 시스템 관리자가 제공해준 서비스 테이블을 컴파일하여 오브젝트 파일 형태를 생성한다.

    다음은 데이터베이스를 사용하지 않는 경우의 예제로 데이터베이스를 사용하는 경우 데이터베이스에 따라 liboras.so(a), libinfs.so(a), libdb2.so(a), libsybs.so(a)를 사용한다. 셸 프로그램을 사용하는 경우 해당 makefile의 –lsvr을 –lsvrucs로 바꾼다. 사용법은 동일하다.

    $cc -c app_svctab.c → app_svctab.o

mksvr 유틸리티를 사용한 컴파일

mksvr 유틸리티를 사용하는 경우 Tmax 시스템 환경 파일을 작성할 때 미리 서비스명을 써 줄 필요가 없으며 서비스 테이블 생성(gst) 과정도 필요로 하지 않는다. 그러나 구조체를 사용하는 경우 구조체-표준 버퍼 변환/역변환 프로그램은 미리 생성되어 있어야 하며 데이터베이스를 사용할 경우 미리 프리 컴파일 과정이 끝난 파일을 사용하거나 RM 파일을 지정해야 한다.

$cfl –i sample.m
$sdlc –i demo.s
$sdlc –c –i demo.s –o tmax.sdl
$mksvr –s UCSSAMPLE –o ucs_svr –f ucs_svr.c –S ../sdl/demo_sdl.c –t UCS

mksvr에 대한 자세한 내용은 Tmax Reference Guide를 참고한다.

5. 프로세스 생성 및 종료

서버 프로세스 생성은 시스템 관리자가 해야할 역할이다. 서버 프로세스가 생성되면서 Tmax 관련 환경을 참조하기 때문에 Tmax 애플리케이션 서버는 단독으로 UNIX 실행 파일처럼 실행되지 않는다. 따라서 tmboot 명령어로 서버 프로세스를 생성하고, tmdown 명령어로 종료시킨다.

Tmax 애플리케이션 서버 프로세스를 생성시키기 전에 시스템 관리자가 작성한 Tmax 환경 파일(예: sample.m)이 컴파일(cfl 명령어 이용)되어 있어야 한다. 컴파일된 이진 환경 파일(예: tmconfig)을 참조하여 서버 프로세스를 생성하게 된다.

다음은 프로세스 생성 및 종료를 위해 사용하는 명령어이다.

  • 프로세스 생성

    • Tmax 시스템 프로세스와 이진화된 Tmax 구성 파일에 등록된 모든 서버 프로세스를 생성한다.

      $tmboot [-f 이진화된 구성 파일]
    • 특정 서버 프로세스만을 생성시킨다.

      $tmboot [-s 서버 프로그램명]
  • 프로세스 종료

    • Tmax 시스템 프로세스와 이진화된 Tmax 구성 파일에 등록된 모든 서버 프로세스를 종료시킨다.

      $tmdown [-f 이진화된 구성 파일]
    • 특정 서버 프로세스만을 종료시킨다.

      $tmdown [-s 서버 프로그램명]

명령어에 대한 자세한 내용은 Tmax Reference Guide를 참고한다.