클라이언트 프로그램

본 장에서는 클라이언트 프로그램의 흐름과 개발 환경, 특징 및 구성에 대해서 설명한다.

1. 프로그램 특징 및 구성

Tmax는 통신 네트워크, 버퍼 관리를 위한 함수를 제공하여 애플리케이션 개발을 용이하게 한다. Tmax에서 제공하는 함수는 라이브러리 형태로 제공되고 애플리케이션과 같이 컴파일된다. 개발자는 어느 머신의 어느 서버에서 무슨 서비스를 제공하는지 관여하지 않아도 프로그램을 개발할 수 있다.

클라이언트 프로그램의 코딩이 완료되면 컴파일하여 실행 파일을 생성한다. 클라이언트 프로그램을 컴파일하기 위해서는 개발자가 작성한 클라이언트 프로그램, Tmax 클라이언트 라이브러리, 구조체 버퍼를 사용하는 경우 구조체 파일, 그리고 필드키 버퍼는 필드 테이블이 정의된 파일이 준비되어야 한다.

다음은 클라이언트 프로그램의 구성에 대한 설명이다.

  • 클라이언트 프로그램

    개발자가 작성한 클라이언트 프로그램이다.

  • 클라이언트 라이브러리

    Tmax가 제공하는 라이브러리(libcli.a / libcli.so)로 클라이언트 프로그램을 개발할 때 사용하는 함수들의 오브젝트 코드이다.

  • 구조체 파일(.s)

    클라이언트 프로그램에서 구조체(STRUCT, X_C_TYPE, X_COMMON)를 사용했다면 <파일명 .s>의 구조체 파일이 필요하다. 구조체 파일을 sdlc 명령어를 사용하여 미리 컴파일한다. 컴파일하면 구조체의 각 데이터가 표준 통신형으로 변환되는 데 필요한 정보를 담은 이진(binary) 형태의 파일이 생성된다. 이는 클라이언트 프로그램 실행할 때에 표준 통신형으로 데이터가 송/수신되는 데 사용한다.

  • 필드키 파일(.f)

    필드키 구조를 사용하였다면 <파일명.f>의 필드 정의 파일이 필요하다. 파일을 fdlc 명령어를 이용하여 컴파일하면 필드키 버퍼 파일은 키 매핑(Key Mapping)을 이용하여 <필드키버퍼명_fdl.h>를 생성하여 프로그램을 사용하게 된다. 기존의 구조체 파일과는 달리 사용자가 원하는 필드의 값만을 조작하고 전달할 수 있어 자원의 낭비를 줄일 수 있다. 하지만 키 매핑 과정에서의 오버헤드도 발생할 수 있으므로 주의한다.

2. 개발 환경 및 툴

Tmax 클라이언트 프로그램의 개발 환경 및 지원하는 개발 툴은 다음과 같다.

  • 개발 환경

    UNIX, WindowNT, Windows95/98/2000, Windows 3.1, MS-DOS 등의 운영체제

  • 개발 툴

    ANSI C, VC++, BC++, VB, VB .Net, C#, Delphi, PowerBuilder, Embedded VC 등

개발 툴을 사용한 프로그램의 자세한 내용은 Tmax Programming Guide (4GL)를 참고한다.

3. 프로그램 흐름

클라이언트 프로그램은 사용자의 요구를 받아서 서버에 전달하고, 서버에서 처리된 결과를 받아서 사용자에게 보여주는 역할을 하는 프로그램이다.

다음은 클라이언트 프로그램을 작성하는 순서이다.

main()
{
        tpstart 버퍼 할당
        tpstart 버퍼 초기화

        Tmax에 접속
        송신/수신 메시지 버퍼 할당
        while {
            송신 메시지 버퍼에 사용자의 요구 입력
            송신 메시지 버퍼를 서버에 보냄(서비스 요청)
            서버로부터 응답을 송신 메시지 버퍼로 받음
            송신 메시지 버퍼의 내용을 사용자에게 보여줌
        }
        송신/수신 메시지 버퍼 제거

        Tmax 연결해제
}

다음은 클라이언트 프로그램 흐름을 나타낸 그림이다.

figure client prog process
클라이언트 프로그램 흐름

다음은 클라이언트 프로그램의 각 함수의 프로세스에 대한 그림이다.

figure client prog process1
클라이언트 프로그램 함수 프로세스

Tmax에서 애플리케이션 개발을 위해서 제공하는 통신 네트워크, 버퍼 관리를 위한 함수에 대한 자세한 사항은 클라이언트 API를 참고하거나 Tmax Reference Guide를 참고한다.

클라이언트 프로그램에서 사용되는 주요 함수에 대한 설명은 다음과 같다.

  • Tmax 통신 환경 함수

    함수 설명

    tmaxreadenv

    Tmax 클라이언트 프로그램을 실행할 때 기본적으로 참조하게 되는 일련의 Tmax 환경변수들을 특정 파일에 기술할 수 있다.

    API를 호출하는 프로그램을 작성할 때 특정 파일의 경로명 및 파일명을 설정하면 해당 클라이언트 프로그램을 실행할 때 설정된 파일의 파일 포인터를 받은 후 내용을 파싱(parsing)한다. 파싱한 내용 중 TMAX_HOST_ADDR, TMAX_HOST_PORT 등의 Tmax 환경변수는 클라이언트 프로그램 실행할 때 확보된 메모리 공간 내에 적재한 후 관련 API 함수를 호출할 경우에 이용한다.

  • 클라이언트와 서버 연결 및 종료 함수

    함수 설명

    tpstart

    CLL 프로세스로 소켓 연결을 요청하고 Accept된 연결을 CLH 측으로 전달한다. tpstart()를 호출할 때 TMAX_HOST_ADDR, TMAX_HOST_PORT에 설정된 값을 사용한다.

    tpend

    CLL 프로세스로 소켓 연결을 종료한다.

  • 통신 버퍼와 해제 함수

    함수 설명

    tpalloc

    Tmax를 통해 클라이언트와 서버 사이의 데이터 송수신을 할 경우 사용하는 메모리를 동적으로 할당한다. 데이터를 송수신할 때 필요한 길이 정보를 예측하여 그 크기만큼 미리 할당해야 한다. 동적 할당된 메모리는 반드시 명시적으로 해제해야 한다.

    tpfree

    tpalloc()을 통해 할당된 동적 할당 메모리를 명시적으로 해제(반환)한다. 할당된 메모리 버퍼는 반환해야 한다. 메모리를 반환하지 않으면 gabage(memory leakage)가 발생하게 된다.

  • 클라이언트 동기 통신 함수

    함수 설명

    tpcall

    CLH 측으로 서비스 요청 및 송신 데이터를 전달하고 클라이언트의 요청 서비스를 확인한 후 서버 애플리케이션 프로세스로 넘겨준다. 클라이언트는 서비스 요청에 대한 응답이 도착할 때까지 대기한다.

  • 클라이언트 비동기 통신 함수

    함수 설명

    tpacall

    CLH 측으로 서비스 요청 및 송신 데이터를 전달하고 클라이언트의 요청 서비스를 확인한 후 서버 애플리케이션 프로세스로 서비스를 전달한다.

    클라이언트는 서비스 요청에 대한 응답 여부와는 관계없이 tpacall() 이후 로직을 수행한다.

    tpgetrply

    tpacall()의 파라미터(cd) 값을 통해서 CLH 측으로 응답 데이터를 요청하고 이미 해당 클라이언트로 보낼 응답 데이터가 있으면 이를 클라이언트로 즉시 전달한다.

    파라미터 중 flags 설정값에 따라 응답 데이터가 올 때까지 기다리거나 혹은 기다리지 않고 즉시 응답 수신 에러를 클라이언트에 알려준다.

4. 프로그램 컴파일

클라이언트 프로그램을 컴파일하여 오브젝트 파일을 생성한다.

다음 그림은 구조체 버퍼와 필드 버퍼를 사용하여 클라이언트 프로그램을 컴파일하는 과정이다.

figure 5 3
클라이언트 프로그램 컴파일 과정 - 구조체 버퍼 사용
figure 5 4
클라이언트 프로그램 컴파일 과정 - 필드 버퍼 사용

다음은 클라이언트 프로그램의 컴파일 순서이다.

  1. UNIX 환경 파일을 생성한다.

    Tmax 접속에 필요한 환경변수를 설정한다(.profile, .login, .cshrc).

    TMAX_HOST_ADDR = Tmax 주소 (=IP Address)
    TMAX_HOST_PORT = 포트 번호 (default : 8888)
  2. 클라이언트 프로그램을 작성한다(client.c).

    서버에 서비스 요청을 하고 서버로 응답을 하는 프로그램을 개발한다.

  3. 개발된 클라이언트 프로그램을 컴파일해서 라이브러리를 생성한다(libcli.a / libcli.so).

  4. 구조체 버퍼를 사용하는 경우 구조체 헤더 파일을 컴파일한다. STRUCT, X_C_TYPE, X_COMMON 버퍼 사용하는 경우 dummy 구조체를 생성해야 한다. 통신할 때 표준 통신형으로 바꾸기 위해 sdlc를 사용해 컴파일한다. 생성된 sdl 파일은 클라이언트 프로그램을 실행할 때 필요하다.

    필드 버퍼를 사용하는 경우에는 fdlc를 사용해서 필드키 파일을 컴파일한다.

다음은 Tmax 클라이언트 프로그램을 위한 Makefile의 예제이다.

TARGET = <clientname>
APOBJS = $(TARGET).o

TMAXLIBD = $(TMAXDIR)/lib

#TMAXLIBS는 OS별로 다르다.
#Solaris : TMAXLIBS = -lsocket -lnsl –lcli
#Compac, HP, IBM, Linux : TMAXLIBS= -lcli

TMAXLIBS = -lcli

#CFLAGS는 OS별로 다르다.
#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

CFLAGS = -O –I$(TMAXDIR)

#
.SUFFIXES : .c

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

#
# client compile
#

$(TARGET): $(APOBJS)
         $(CC) $(CFLAGS) -L$(TMAXLIBD) -o $(TARGET) $(APOBJS) $(TMAXLIBS)

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

Tmax에서 제공되는 예제 프로그램에는 compile이라는 셸 스크립트를 사용하여 make를 실행하고 있다. compile이라는 셸 스크립트를 사용하기 위해서는 command에 아래와 같이 입력한다. compile에서 Makefile의 EXE에 확장자를 뺀 클라이언트 프로그램명을 넣는다.

compile c cli (=>확장자를 뺀 클라이언트 프로그램명)

5. 프로세스 기동 및 종료

Tmax를 기동하기 위해서 환경변수를 설정해야 한다.

클라이언트 프로그램은 Tmax에 연결할 때 환경변수에서 필요한 정보를 얻기 때문에 미리 UNIX 셸 환경 파일(c 셸: .cshrc, korn 셸: .profile, bash 셸: .bash_profile 등)에 TMAX_HOST_ADDR, TMAX_HOST_PORT가 설정되어 있는지 확인한다. 장애에 대비하여 TMAX_BACKUP_ADDR과 TMAX_BACKUP_PORT를 설정할 수 있다. 네트워크 장애에 대비하여 TMAX_CONNECT_TIMEOUT을 지정할 수 있다.

UNIX 환경 파일에 Tmax 환경변수가 설정되어 있으면 클라이언트 프로세스를 생성시키는 데 필요한 준비는 완료된다. 클라이언트 프로세스는 다른 실행 파일과 같은 방법으로 실행하고 종료시키면 된다.

다음은 각 환경변수에 대한 설명이다.

환경변수 설명

TMAX_HOST_ADDR

Tmax 서버의 IP를 설정하는 부분으로 매우 중요한 역할을 한다. 클라이언트가 요청한 서비스가 처음 연결이 설정된 서버에 있지 않다면 내부적으로 다시 연결을 설정하여 서비스를 받게 된다.

클라이언트가 트랜잭션 처리를 요구했다면 처음 연결이 설정된 Tmax가 트랜잭션의 조정자가 되어 2PC를 주관한다. 따라서 가장 많이 사용되는 서비스가 위치한 서버의 주소를 설정하여 네트워크 부하 경감은 물론 응답시간의 단축도 기대할 수 있다.

TMAX_HOST_PORT

Tmax 서버의 포트를 설정하는 부분으로 Tmax 환경 파일에 TPORTNO가 설정되어 있지 않으면 기본값인 8888이 사용된다.

TMAX_BACKUP_ADDR

클라이언트에서 서비스 요청하면 먼저 TMAX_HOST_ADDR가 지정하는 서버로 연결을 시도하고, 그 서버가 장애라면 TMAX_BACKUP_ADDR가 지정하는 서버로 다시 연결을 시도한다.

TMAX_BACKUP_ADDR이 지정되어 있지 않다면 클라이언트의 요청은 재접속 시도 없이 바로 실패로 끝난다.

TMAX_BACKUP_PORT

TMAX_BACKUP_ADDR가 지정하는 Tmax 서버의 포트 번호이다.

TMAX_CONNECT_TIMEOUT

네트워크 장애에 대비하여 TMAX_CONNECT_TIMEOUT을 지정한다. 클라이언트는 환경변수에 설정한 시간 동안 대기한다.

TMAX_CONNECT_TIMEOUT에 지정된 시간 내에 설정되지 않으면 tpstart()는 실패로 끝난다. 네트워크 장애의 경우 tperrono를 TPETIME으로 설정한다.

TMAX_BACKUP_ADDR / TMAX_BACKUP_PORT가 설정되면 tpstart()는 백업 호스트를 하기 위해 다른 TMAX_CONNECT_TIMEOUT을 시도한다.

SDLFILE

구조체 통신을 하는 클라이언트 프로그램인 경우 반드시 설정한다.

FDLFILE

필드 버퍼 통신을 하는 클라이언트 프로그램인 경우 반드시 설정한다.

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

5.1. sdlc

구조체 통신을 하는 클라이언트 프로그램인 경우 환경변수 중 SDLFILE이 반드시 설정되어야 한다. 클라이언트 프로그램에서 사용하는 구조체 파일을 sdlc로 컴파일한 SDL 파일이 SDLFILE 변수에 정의되어야 한다. 구조체 통신을 실행할 때 구조체 정보가 SDLFILE에 있으면 Tmax 서버와 통신할 수 있다.

구조체 파일은 다음과 같은 형식으로 컴파일한다.

$ sdlc -c -i 구조체 파일명 [-o sdl 파일명] [-h 헤더 파일명]
옵션 설명

-i 구조체 파일명

컴파일할 대상인 구조체 파일의 이름을 지정한다. 파일은 하나 또는 여러 개가 정의될 수 있으며, 확장자는 상관없다. 애스터리스크(*)가 모든 파일에 대응하는 와일드 카드로 사용될 수 있다.

구조체 파일에는 "struct명 { . . . };" 형식으로 구조체가 하나 이상 정의되어야 한다.

[-o sdl 파일명]

생성될 SDL 파일명을 지정하는 변수로 SDLFILE 변수에 정의되는 이름이다.

[-h 헤더 파일명]

구조체 정보를 단순히 헤더 파일 형식으로 생성한다. [-h] 옵션이 생략될 경우 <이름_sdl.h>가 생성된다.

[-o] 옵션이 생략될 경우 기본값으로 생성되는 SDL 파일은 다음과 같다.

  • 구조체 파일이 하나인 경우 생성되는 파일명은 <확장자를 제외한 구조체 파일명.sdl>이 된다.

    다음의 경우 생성되는 파일명은 <demo.sdl>이 된다.

    sdlc -c -i demo.s
  • 구조체 파일이 여러 개 나열된 경우 생성되는 파일명은 <맨 앞의 구조체 파일명.sdl>이 된다.

    다음의 경우 생성되는 파일명은 <stra.sdl>이 된다.

    sdlc -c -i stra.s bana.s orage.s

    다음은 현재 디렉터리에 존재하는 .s 파일이 a.s, b.s, c.s일 때 파일을 생성하는 예로 생성되는 파일명은 <a.sdl>이 된다.

    sdlc -c -i *.s

5.2. fdlc

필드 버퍼 통신을 하는 클라이언트 프로그램인 경우 환경변수 중 FDLFILE이 반드시 설정되어야 한다. 클라이언트 프로그램에서 사용하는 필드 버퍼 파일을 fdlc로 컴파일한 FDL 파일이 FDLFILE 변수에 정의되어야 한다. 필드 버퍼의 통신을 실행할 때 필드 정보가 FDLFILE에 있으면 Tmax 서버와 통신할 수 있다.

필드 버퍼 파일은 다음과 같은 형식으로 컴파일한다.

$ fdlc -c -i 필드 버퍼 파일명 [-o fdl 파일명] [-h 헤더 파일명]
항목 설명

-i 필드 버퍼 파일명

컴파일할 대상인 필드 버퍼 파일의 이름을 지정한다.

[-o fdl 파일명]

생성될 FDL 파일명을 지정하는 변수로 FDLFILE 변수에 정의되는 이름이다. [-o] 옵션이 생략될 경우 기본값으로 생성되는 FDL 파일은 <tmax.fdl>이 된다.

[-h 헤더 파일명]

구조체 정보를 단순히 헤더 파일 형식으로 생성한다. [-h] 옵션이 생략될 경우 <이름_fdl.h>가 생성된다.