Tmax Application Development Guide Copyright 2000 TmaxSoft Co., Ltd. All Rights Reserved
Copyright Notice Copyright 2000 TmaxSoft Co., Ltd. All Rights Reserved. TmaxSoft Co., Ltd. 대한민국서울시강남구대치동 946-1 글라스타워 18 층우 )135-708 Restricted Rights Legend This software and documents are made available only under the terms of the TmaxSoft License Agreement and may be used or copied only in accordance with the terms of this agreement. No part of this document may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, or optical, without the prior written permission of TmaxSoft Co., Ltd. 소프트웨어및문서는오직 TmaxSoft Co., Ltd. 와의사용권계약하에서만이용이가능하며, 사용권계약에따라서사용하거나복사할수있습니다. 또한이매뉴얼에서언급하지않은정보에대해서는보증및책임을지지않습니다. 이매뉴얼에대한권리는저작권에보호되므로발행자의허가없이전체또는일부를어떤형식이나, 사진녹화, 기록, 정보저장및검색시스템과같은그래픽이나전자적, 기계적수단으로복제하거나사용할수없습니다. Trademarks Tmax, WebtoB, WebT, and JEUS are registered trademarks of TmaxSoft Co., Ltd. All other product names may be trademarks of the respective companies with which they are associated. Tmax, WebtoB, WebT, JEUS 는 TmaxSoft Co., Ltd. 의등록상표입니다. 기타모든제품들과회사이름은각각해당소유주의상표로서참조용으로만사용됩니다. Document Edition Date Version TMAG-0107-04-400 Jan 1, 2006 Tmax 4.0 Tmax 제품은아래표와같습니다. 본서는 Tmax Standard 와옵션중에굵게기울임꼴로인쇄되어있는내용을포함하고있습니다. Tmax Standard Tmax Options TP Function + 2 Phase Commit Web Admin Console, X.25 Gateway, TCP/IP Gateway, Host- Link, Power Builder Interface Module, SERIAL Gateway, 1
TCP/IP Service Gateway 2
이책에관하여... 는 Tmax Application 을쉽게개발하기위하여 Tmax 의기본적인함수를설명하고그에따른예제프로그램을포함한다. 이책의독자는 Application 프로그램을개발하기위해 Tmax, Unix C Programming 에대한기본적인지식과 text editor(vi 등 ) 를사용할수있는능력이있어야한다. 누구를위한책인가? 이책은 Tmax Application 프로그램을개발하기전에개발자들에게일반적인정보를주기위한것이다. 이는 Tmax 로개발을함에있어모든상황에대한고려사항을자세히다루고있지는않다. 또한이책은각프로젝트의특징들을담고있으므로 Tmax Soft Software Engineer 들에게추천된다. 어떻게사용하는가? 이책은 Tmax 를사용하는개발자들을위해기본적인 Tmax 개발방법을예제로서설명한다. 그리고 Tmax 의가장기본적인프로그래밍을서술하며보다상세한프로그래밍을위해다른책들을참조할것을권장한다. FIELD buffer, Tmax 환경설정과다른 Tmax 와관련한주제들은 Tmax Soft 에서제공하는다른메뉴얼들을참조하기바란다. 1. 소개 Tmax 프로그램들과 API 들그리고 Buffer 타입들에대한간략한설명을기술한다. 2. Tmax Application Programs 분산된클라이언트와서버프로그래밍시의 Tmax 에의해지원되는기능들에대한예제들을기술한다. 3. 부록 - Tmax 환경파일을설명한다. 더자세한설명을원한다면 Tmax Administration Guide 를참조하도록한다. 기본적인 Tmax 프로그램의예제프로그램을포함한다. 관련서 Tmax Getting Started Guide Tmax Reference Manual Tmax FDL Reference Manual Tmax Administration Guide 3
Tmax Installation Guide 규약 규 약 설 명 { [ ] ( ) Numeric String Literal 필수항목옵션항목지정된여러개의값중배타적인선택구분자디폴트값숫자 abc 형태의문자열 abc 형태의문자열 4
차례 1 Tmax 응용프로그램소개... 9 1.1 Tmax 응용프로그램이란... 9 1.1.1 Tmax 응용프로그램구성... 10 1.1.2 Tmax 응용프로그램특징... 11 1.1.3 Tmax 응용프로그램장점... 12 1.2 Tmax 응용프로그램흐름... 13 1.2.1 Tmax 응용클라이언트프로그램이란무엇인가?... 13 1.2.2 Tmax 응용서버프로그램이란?... 14 2 Tmax API 함수... 17 2.1 TX 함수... 17 2.2 비표준 API 함수... 19 2.3 XATMI (X/Open Application - Transaction Monitor Interface) API 함수... 22 2.4 필드키 Buffer 관련함수... 24 3 Tmax Buffer 유형... 30 4 Tmax 통신유형... 34 4.1 동기형통신... 36 4.2 비동기형통신... 37 4.3 대화형통신... 38 5 Tmax 클라이언트프로그램... 39 5.1 Tmax 클라이언트함수개요... 39 5.2 Tmax 클라이언트함수... 40 5.2.1 Tmax 연결및해제... 40 5.2.2 Buffer 관리... 44 5
5.2.3 동기통신... 50 5.2.4 비동기통신... 55 5.2.5 비요청메시지처리... 59 5.2.6 타임아웃변경... 61 5.3 Tmax 클라이언트프로그램컴파일... 62 5.3.1 클라이언트프로그램구성... 63 5.3.2 클라이언트프로그램컴파일... 63 5.3.3 클라이언트프로세스기동및종료... 67 6 Tmax 서버프로그램작성... 70 6.1 Tmax 서버함수개요... 70 6.2 Tmax 서버함수... 71 6.2.1 서비스루틴인자... 71 6.2.2 서비스완료... 73 6.2.3 서버초기화와종료루틴... 76 6.2.4 XA 모드와 NonXA 모드... 79 6.2.5 비요청메시지관련인터페이스... 80 6.3 서버프로그램... 84 6.3.1 서버프로그램구성... 84 6.3.2 서버프로그램컴파일... 85 6.3.3 서버프로세스생성및종료... 90 7 대화형통신... 91 7.1 대화형통신함수개요... 91 7.2 대화형통신함수... 92 7.2.1 int tpconnect(char *svc, char *sbuf, long slen, long flags)... 92 7.2.2 int tpsend(int cd, char *sbuf, long slen, long flags, long *revent)... 94 7.2.3 int tprecv(int cd, char **rbuf, long *rlen, long flags, long *revent)... 96 7.3 대화형모드의연결끊기... 98 7.3.1 int tpdiscon(int cd)... 98 7.4 대화형통신과관계있는이벤트... 100 8 트랜잭션관리... 101 8.1 전역트랜잭션처리 (Global Transaction Processing)... 102 8.2 트랜잭션흐름... 103 6
8.3 트랜잭션관련함수... 103 8.3.1 int tx_begin()... 103 8.3.2 int tx_commit()... 105 8.3.3 int tx_rollback()... 106 8.3.4 int tx_set_transaction_timeout(transaction_timeout timeout)... 108 8.3.5 int tx_set_transaction_control( TRANSACTION_CONTROL control)... 108 8.3.6 int tx_set_commit_return(commit_return when_return)... 109 8.3.7 int tx_info(txinfo *info)... 110 8.4 트랜잭션관련에러... 111 8.4.1 트랜잭션에러...111 8.4.2 XA 에러... 112 9 RQ... 114 9.1 int tpenq(char *qname, char *svc, char *data, long len, long flags);... 114 9.2 int tpdeq(char *qname, char *svc, char **data, long *len, long flags);... 115 9.3 int tpqstat(char *qname, long flags);... 116 9.4 int tpextsvcname(char *data, char *svc);... 117 10 프로세스처리... 118 10.1 TCS(Tmax Control Server)... 118 10.2 UCS(User Control Server)... 119 10.3 RDP(Realtime Data Processor)... 123 11 Tmax 보안... 125 11.1 1단계보안 : 시스템접속제어... 125 11.2 2단계보안 : 사용자인증... 127 11.3 3단계보안 : 서비스접근제어... 129 12 Tmax 함수에러메시지... 132 12.1 tperrno : Tmax 에러상황이발생할경우에설정이되는전역변수 ( 이때 ATMI 호출은 1을반환한다.)... 132 12.1.1 char *tpstrerror(int errno); 에러메시지를반환함... 136 7
13 부록... 138 13.1 Tmax 환경파일... 138 13.1.1 DOMAIN 절... 139 13.1.2 *NODE 절... 139 13.1.3 *SVRGROUP 절... 140 13.2 Tmax 응용프로그래밍... 144 13.2.1 기초프로그램... 144 13.2.2 실전프로그램... 162 13.2.3 고급프로그램... 203 8
1 Tmax 응용프로그램소개 1.1 Tmax 응용프로그램이란 Tmax 응용프로그램이란개방형환경에서 Tmax( 티맥스 ) 를미들웨어로하여개발한클라이언트 / 서버프로그램을말한다. 고성능 PC 의등장과프로그램기법의발달은호스트중심의중앙처리방식에서클라이언트와서버가작업처리를분담하는형태, 즉클라이언트 / 서버환경으로의변화를가져왔다. 이와같은클라이언트 / 서버컴퓨팅은작업을분담함으로써고성능 PC 의활용과서버의소형화, 각종하드웨어선택폭의확대등과같이자원의효율적활용을가능하게하였다. 하지만클라이언트 / 서버환경은아래와같은문제점도가지고있다. 개발자가각하드웨어, 운영체제, 네트웍프로토콜에대한깊은이해가있어야만프로그램이가능하다. 사용자수와데이터양의증가에따라처리속도가현저하게저하된다. 과다한네트웍트래픽발생으로속도가저하된다. 분산환경에따른관리 ( 프로세스관리, 통신, 보안, 장애대책등 ) 가어렵다. Tmax 응용프로그램은클라이언트 / 서버프로그램의장점을유지하면서, 위와같은단점을획기적으로보완한다. 9
그림 1-1. Tmax application program Tmax 를미들웨어로하여응용프로그래밍을작성한다는의미는 Tmax 에서제공하는함수들을이용하여프로그램을작성하여, 통신프로그램및프로세스관리, 트랜잭션관리등관리상의어려운부분을 Tmax 가해결하는것이다. Tmax 에서제공하는함수는 Buffer 및통신, 기록트랜잭션관련함수들이며, 서버라이브러리 (libsvr.a) 와클라이언트라이브러리 (libcli.a) 로나누어제공된다. 이함수들은분산처리국제표준 X/Open DPT 모델을준수한다. 1.1.1 Tmax 응용프로그램구성 Tmax 응용프로그램은크게 Tmax 클라이언트프로그램과 Tmax 서버프로그램으로나누어진다. 그리고여기에 Tmax 를사용하기위한환경설정작업이추가된다. 1.1.1.1 클라이언트프로그램 클라이언트프로그램은사용자의요청에따라서비스를요청하고, 그요청에대한응답을서버에서받아사용자가원하는형식으로결과를전달하는역할을하는프로그램이다. Tmax 응용클라이언트프로그램과 UNIX 환경파일 (ex:.profile) 이필요하다. Unix 환경파일 (ex:.profile) 에는클라이언트가 Tmax 에연결할때필요한사전정보 (Tmax 어드레스, 포트번호등 ) 를설정한다. 10
1.1.1.2 서버프로그램 서버프로그램은시스템자원에대한접근관리와클라이언트의요청을받아서처리하고응답을클라이언트에게전달하는역할을하는프로그램이다. 서버프로그램은 Tmax 에서제공하는 main() 과개발자가개발한서비스루틴으로구성되어있다. Tmax 응용서버에서반드시필요한파일들은 Tmax 환경파일과서버프로그램이다. Tmax 환경파일은 Tmax 가사용하는자원들에대한전체시스템구성을설정하는파일이며, Tmax 관리자가작성한다. 이파일은 Tmax 시스템과서버프로그램기동시참조되며, 서비스테이블작성시도참조된다. 자세한내용은서버프로그램컴파일페이지와 Tmax Reference Guide 를참조하기바란다. 1.1.2 Tmax 응용프로그램특징 Tmax 응용프로그램은다른 UNIX 프로그램과비교하여다음과같은특징을갖는다 : 프로그램작성시 Tmax 함수들을이용하며이함수들은분산처리국제표준 (X/Open DTP model) 을준수한다. 응용서버프로그램을만들때서비스루틴만개발한다. 클라이언트는기본적인 C 언어형식에맞게프로그램 ( 내부에 main() 을포함 ) 을개발해야하며, 서버프로그램은클라이언트의서비스요청을처리하는순수한업무서비스루틴 ( 내부에 main() 이없는 ) 만을개발한다. 서비스요청에는 3 가지통신유형이제공된다 : 동기통신, 비동기통신, 그리고대화형통신이있다. 동기통신은서비스요청 (tpcall) 후응답이올때까지기다린다. 비동기통신은서비스를요청 (tpacall) 하고응답을받고자 (tpgetrply) 할때까지다른일을할수있다. 대화형통신은초기연결설정 (tpconnect) 후메시지송신 (tpsend) 과수신 (tprecv) 을반복적으로수행할수있다. 이와같은유형의통신을제공함으로써개발자는통신네트워크에대한깊은이해없이도쉽게프로그램이가능하게된다. 11
서비스요청시 7 가지 Buffer 를사용할수있다. 보통개발자는타기종간데이터통신을할때데이터무결성을보장하는데어려움을겪는다. 각머신, 각운영체제, 그리고네트워크프로토콜에대한깊은이해가있어야만개발이가능하다. 하지만 Tmax 에서는 7 가지유형의 Buffer 를지원함으로써개발자에게선택의폭을넓혔을뿐아니라, 머신, 운영체제, 네트워크에대한깊은이해가없이도개발이가능하다. 1.1.3 Tmax 응용프로그램장점 Tmax 를이용한프로그래밍은아래와같은장점이있다 : 하드웨어, 통신네트워크에대한깊은이해가없어도쉽게프로그래밍을가능하게한다. 클라이언트는위치를알지못해도, 이름만으로서비스를요청할수있다. 통신에서사용하는 Buffer 의유형이다양하다. 이기종하드웨어, 이기종운영체제에따라데이터를메모리에할당하는방식과데이터타입별로정의된길이가서로다를수있다. 따라서특정데이터값을송신했을때수신측에서는다른값으로인식될수있으므로일반적으로모든하드웨어나운영체제에서동일하게인식될수있는문자형으로변환하여데이터를송 / 수신한다. 하지만 Tmax 통신에서는문자형이외에구조체유형등의 Buffer 를제공함으로써시스템성능향상은물론네트웍부하를감소시킨다. 다양한통신유형을제공한다. 동기 (tpcall()), 비동기 (tpacall()), 대화형통신 (tpconnect()), 자발적인통신 (tpbroadcast()) 등을제공하여다양한환경에맞는통신을지원한다. 트랜잭션처리의무결성을제공한다. 프로그램에서는트랜잭션의범위만을설정하면 Tmax 는 2PC (two-phase commit) 방식으로데이터의무결성을제공한다. 12
1.2 Tmax 응용프로그램흐름 1.2.1 Tmax 응용클라이언트프로그램이란무엇인가? 1.2.1.1 클라이언트프로그램 사용자의요구를받아서서버에전달하고, 서버에서처리된결과를받아서사용자에게보여주는역할을하는프로그램이다. 1.2.1.2 Tmax 응용클라이언트개발환경 Tmax 클라이언트의개발환경은 Unix, WindowNT, Windows95/98/2000, Windows 3.1, MS-DOS 등이가능하다. 개발 Tool 로써 Unix 의 C, Visual C++, Boland C++, Visual Basic, 델파이, 파워빌더등이지원가능하다. 1.2.1.3 Tmax 응용클라이언트흐름 main() { tpstart Buffer 할당. tpstart Buffer 초기화. Tmax 에접속. 송신 / 수신메시지 Buffer 할당. while{ 송신메시지 Buffer 에유저의요구입력. 송신메시지 Buffer 를서버에보냄 ( 서비스요청 ). 서버로부터응답을송신메시지 Buffer 로받음. 송신메시지 Buffer 의내용을사용자에게보여줌. 송신 / 수신메시지 Buffer 제거 Tmax 연결해제 클라이언트는제일먼저 Tmax 에연결한다. tpstart() 는환경변수 (Tmax 연결서버주소와포트번호 ) 를읽어서연결을 13
설정하며, 연결시클라이언트의연결정보를서버에게주고싶다면 TPSTART_T Buffer 를미리할당하여사용한다. Tmax 는다양한통신 Buffer 유형을지원한다. 통신에서사용할 Buffer 를할당하고, 사용자의요구를 Buffer 에입력한다. 통신 Buffer 는반드시 Tmax 제공함수 (tpalloc()) 로생성되어야한다. 서비스를요청하고응답을받는다. 서비스요청과응답은동기, 비동기, 대화형통신이제공된다. 서버로부터받은응답내용을사용자에게전달한다. Tmax 와의연결을해제한다. 1.2.1.4 Tmax 응용클라이언트특징 Tmax 응용프로그램은 2-Tier 클라이언트 / 서버프로그램과비교하여몇가지다른점을가진다. Tmax 에서는통신네트워크, Buffer 관리를위한함수들을제공하여응용프로그램개발을용이하게한다. 이함수들은라이브러리형태로제공되고응용프로그램과같이컴파일된다. 개발자는어느머신의어느서버에서무슨서비스를제공하는지관여하지않아도프로그램을개발할수있다. 1.2.2 Tmax 응용서버프로그램이란? 1.2.2.1 Tmax 응용서버프로그램 사용자의요청을받아서처리하고그응답을클라이언트에게반환한다. 1.2.2.2 Tmax 응용서버프로그램개발환경 Tmax 응용서버프로그램의 O/S 환경은하드웨어와는무관한모든 UNIX 기종을지원한다. 유닉스표준편집기 vi 로개발이가능하다. 14
1.2.2.3 Tmax 응용서버흐름 서버프로그램은 Tmax 에서제공하는 main() 과개발자가개발하는서비스루틴으로크게나누어볼수있다. main() 은명령어라인에입력된인수처리, 연결된데이터베이스연결및해제역할과, 서비스루틴에서사용할 Buffer 를할당한다. 그리고클라이언트요청을처리하는서비스루틴을효출하는역할을한다. 서비스루틴은클라이언트의요청을처리한다. 클라이언트의요청은먼저 main() 에서서비스요청과관련된정보를가지고 15
있는 TPSVCINFO 구조체로부터받는다. 클라이언트가요구한 Buffer 의내용은 TPSVCINFO->DATA 에있다. 서비스루틴에서는 TPSVCINFO->DATA 에서데이터를받아서요청기능을처리한후, 결과를클라이언트에게전달하거나, 또다른처리를위하여다른서버에서비스처리를요구한다. 1.2.2.4 Tmax 응용서버프로그램특징 Tmax 응용서버프로그램은 Tmax 에서제공하는 main() 과개발자가작성한업무처리서비스루틴으로구성된다. 서버프로그램은응용클라이언트프로그램처럼 Tmax 함수를이용하여작성된다. 이함수들은라이브러리 (libsvr.a) 로제공되며응용서버프로그램과같이컴파일된다. 프로그래머는서비스루틴만을개발하면된다. 이것은개발을용이하게하며개발기간을단축시켜준다. 서버는하나이상의서비스로이루어진다. 게다가서버자신이클라이언트가되어다른서버에서비스를요청할수있다. Tmax 함수가통신및데이터변환을제공하므로, 개발자는유닉스내부시스템에대한깊은이해없이 Tmax 함수만으로프로그래밍을할수있다. XA 모드의경우데이터베이스연결과해제가 Tmax 서브루틴에서제공되므로, 개발자는 DB open 과 close 에신경쓰지않아도된다. 참고 : 여기서서비스는 tpcall 등의함수에첫번쨰인자로쓰이며클라이언트의요청사항을처리하는최소단위이다. 이런서비스는하나의서비스에서클라이언트의요청을모두처리할수도있고다른서비스를다시호출할수도 (tpcall, tpacall, etc) 있으며다른서비스에게서비스처리를전달 (tpforward) 할수도있다. (C 에서프로그램내의함수와유사함.) 서버는이런서비스를하나이상 (UCS 의경우하나도안가지고있을수도있다 ) 가지고있다. (C 에서하나의프로그램과유사함.) 16
2 Tmax API 함수 Tmax API 는응용프로그래밍을위하여 Tmax 에서제공한다. Tmax API 는 X/Open 의 XATMI 와 TX 표준을따르는함수로이루어져있다. 이함수들은데이터베이스관리, Buffer 관리, 트랜스잭션범위설정, 클라이언트와서버간의통신등을제공한다. 이들함수는이기종간통신과데이터변환, 그리고분산트랜스잭션처리를가능하게한다. Tmax API 함수들은서버라이브러리와클라이언트라이브러리로구성된 Tmax 라이브러리로제공된다. UNIX 환경에서는서버쪽은 libsvr.a, 클라이언트쪽은 libcli.a 로제공되며, 응용프로그램과같이컴파일하여야한다. Tmax API 는 atmi.h, tmaxapi.h, 그리고 tx.h 를헤더파일로사용한다. atmi.h 는 Buffer 관리및통신과관련된 API 들이정의되어있고, tx.h 는트랜잭션과데이터베이스와관련된 API 들이정의되어있으며, tmaxapi.h 는비표준 API 의프로토타입이정의되어있다. 서버프로그램작성시필요한함수들, 즉 XATMI 와 TX 표준함수들을개략적으로소개하겠다. 2.1 TX 함수 TX 는응용프로그램과 Tmax 간의인터페이스로서트랜잭션범위를설정하고트랜잭션을수행한다. 이것은 X/Open DTP 표준을준수한다. 함수함수이름기능 17
tx_begin() 트랜잭션을시작한다. tx_commit() 트랜잭션을저장한다. tx_rollback() 트랜잭션을원상태로회복시킨다. tx_open() resource manager 를연다. ( 내부적으로작동됨 ) 트랜잭션 관리함수 tx_close() tx_set_transaction_t imeout() resource manager 를닫는다. ( 내부적으로작동됨 ). 트랜잭션 처리시 사용될 시간을 설정한다. tx_info() 전역 (global) 트랜잭션에대한정보를리턴한다. tx_set_commit_retu rn() 전역 (global) 트랜잭션의 승인시점을 지정한다. tx_set_transaction_ control() 한트랜잭션완료시자동으로새로운트랜잭션을시작한다. 표 1-1. TX Functions 18
2.2 비표준 API 함수 함수 함수이름기능 tpbroadcast () tpsendtocli() 서버나클라이언트에서시스템에기록된다수의클라이언트혹은특정클라이언트에게일방적으로비요청데이터를송신한다. 서버가현재연결된특정클라이언트에게일방적으로비요청데이터를송신한다. 비요청 데이터 tpnotify() 서버가클라이언트각자에게일방적으로비요청데이터를송신한다. tpsetunsol() 비요청데이터를처리하는함수를지정한다. tpgetunsol() 비요청데이터를수신한다. tpsetunsol_fl ag() 알림메시지를수락하는플래그를설정한다. tpchkunsol() 비요청메시지의도착을확인한다. 에러관련함수 tpstrerror() userlog() 에러번호에대한스트링메시지를확인한다. 지정된메시지를 ulog 파일에기록한다. ulog 파일은 Tmax 시스템환경파일에지정된 ULOGDIR 에생성된다. 19
함수 함수이름기능 ulogsync() UserLog() gettperrno() 메모리 Buffer 에있는 ulog 내용을디스크에저장한다. userlog() + ulogsync() Tmax 시스템호출에서발생한에러넘버 (errno) 를반환한다. gettpurcode() 개발자가설정한 urcode 를반환한다. tperrordetail( ) 시스템호출에서발생한에러에관한세부적인정보를얻는다. 소켓정보관련함수 tpgetpeer_ip addr() tpgetpeerna me() tpgetsockna me() 클라이언트의 IP 주소를제공한다. 클라이언트의 name 을확인한다. 클라이언트의소켓이름제공한다. 블록타임아웃설정함수 tpset_timeou t() 블록타임아웃을설정한다. 장애대책함수 tptobackup() 백업머신으로연결을맺는다. 20
함수 함수이름기능 연결함수 tpstart() Tmax 시스템과의연결시작한다. tpend() Tmax 시스템과의연결종료한다. tpenq() RQ 에데이터를저장한다. tpdeq() RQ 로부터데이터를추출한다. RQ tpqstat() RQ 에저장된데이터통계정보를획득한다. tpextsvcnam e() RQ 에저장된데이터의서비스이름을얻는다. Set Get and Environm ent tmaxreadenv () 환경변수를파일로부터읽는다. tpputenv() 환경변수값을설정한다. tpgetenv() 환경변수에대한설정값을반환한다. 기 타 tpscmt() 트랜잭션 commit 모드를변경및설정한다. tpgetlev() 트랜잭션모드여부를확인한다. tpchkauth() 인증에대한설정여부를확인한다. tpgprio() 설정된우선순위를확인한다. tpsprio() 우선순위를설정한다. 21
함수 함수이름기능 tpsleep() 지정된시간안에메시지가도착할때까지기다린다. tp_sleep() 데이터의도착을초단위로기다린다. tp_usleep() 데이터의도착을백만분의 1 기다린다. 초단위로 tpschedule() tpuschedule( ) UCS 유형의프로세스에서 TCS 채널을검사한다. UCS 유형의프로세스에서 TCS 채널을검사한다. 표 1-2. Non-Standard API Functions 2.3 XATMI (X/Open Application - Transaction Monitor Interface) API 함수 XATMI 는응용프로그램과 Tmax 간의인터페이스로서 Buffer 의할당및해제, 서버와클라이언트사이의통신등을제공한다. 이것은 X/Open DTP 의표준을준수한다. 함수함수이름기능 Buffer 관리 tpalloc() 데이터를송수신할 Buffer 를할당한다. 22
함수 tprealloc() Buffer 의크기를변경한다. tpfree() 할당된 Buffer 를해제시킨다. tptypes() Buffer 의유형및크기에대한정보를제공한다. 서비스요구 및 tpcall() tpacall() 서비스를 요청하고 응답이 올 때까지 기다린다. 서비스를요청한후다른일을처리한다. tpgetrply() 호출로처리결과를수신한다. 응답관련함수 tpcancel() 어떤서비스요청에대한응답을취소한다. tpgetrply() tpacall() 의호출에대한응답을받는다. tpconnect() 대화형모드로서비스와연결을설정한다. 대화형함수 tpdiscon() 대화형모드서비스와연결을비정상적으로종료한다. tprecv() 대화형모드에서메시지를수신한다. tpsend() 대화형모드에서메시지를송신한다. 서비스 종료관련함수 tpreturn() 서비스요청에대한응답을클라이언트에게보내고서비스루틴을종료한다. 표 1-3. XATMI API Functions 23
2.4 필드키 Buffer 관련함수 함 수 함수이름 기 능 fbget_fldk ey() 필드이름에대한필드키 (fieldkey) 값을반환한다. 필드키 사상함수 fbget_fldn ame() fbget_fldn o() fbget_fldt ype() 필드키에대한이름을반환한다. 필드키로부터해당필드키번호를가져온다. 필드키로부터 필드형 (type) 을 가져온다.( 정수값 리턴 ) fbget_strfl dtype() 필드키로부터 형 (type) 에 대한 포인트 값을 가져온다. Buffer fbisfbuf() 할당된 Buffer 가필드 Buffer 인지확인한다. 할당함수 fbinit() fbcalcsize( ) 필드 Buffer 로할당된메모리공간을초기화시킨다. 필드 Buffer 의크기를계산한다. fballoc() 필드 Buffer 를동적으로할당한다. fbfree() 필드 Buffer 를해제한다. 24
함 수 함수이름 기 능 fbget_fbsi ze() 바이트단위로필드 Buffer 크기를반환한다. fbget_unu sed() 사용되지않는필드 Buffer 공간을체크한다. fbget_used () 사용중인필드 Buffer 공간을바이트 (byte) 수단위로반환한다. fbrealloc() Buffer 의크기를다시줄이거나늘릴때사용한다. 필드접근및수정함수 fbput() fbinsert() 필드 Buffer 에필드키값을추가하거나덧붙일때사용된다. 필드 Buffer 에있는필드키의필드값을지정된필드키와포지션에저장한다. fbchg_tu() 내용을전송하기전에지정된필드 Buffer 내용을이동한다. 에 fbdelete() Buffer 의필드내용을삭제한다. fbdelall() 필드에들어있는모든값들을지운다. fbdelall_tu () 필드키어레이 (fieldkey[]) 에기재되어있는필드의모든내용을지운다. fbget() Buffer 에들어있는필드내용을얻는다. fbgetf() 필드 Buffer 에있는지정된필드키의필드값을얻는다. 25
함 수 함수이름 기 능 fbget_tu() fbnext_tu( ) 지정된 필드키의 값을 지정된 필드 순번에서 얻는다. 필드 Buffer 에서지정된필드키의필드값을연속적으로얻는다. fbgetalloc _tu() 리턴된데이터를저장하기위해다른 Buffer 내부적으로할당하고 Buffer 에게단지포인터만반환한다. 를 fbgetval_l ast_tu() fbgetlast_t u() 필드 Buffer 에서지정한필드키에있는필드데이터중마지막데이터값을얻는다. 필드 Buffer 에서지정한필드키의마지막순번의데이터를리턴한다. fbgetnth() 지정된필드값을찾는다. fbfldcount () 지정된 Buffer 안에포함된필드개수를반환한다. fbkeyoccu r() 필드키로지정된필드의개수를반환한다. fbispres() fbgetval() FBUF 의지정된필드안에요청된내용이있는지검사한다. 요청된내용의크기를반환하고, 위치는포인터로리턴한다. 26
함 수 함수이름 기 능 fbgetvall_t u() 필드의실값을 long 값으로반환한다. fbupdate() 필드 Buffer 에있는필드키의필드값을지정된순번에갱신한다. fbgetlen() 필드 Buffer 의선택된필드키에맞는필드데이타의첫번째어커런스의길이를반환해준다. 변환함수 fbtypecvt( ) 데이터형을변환시켜준다. fbputt() 새로운데이터값을데이터형과같이필드 Buffer 에덧붙여준다. fbget_tut() 필드데이터를지정한필드순번에넣는다. 그리고필드키의타입을지정한다. fbgetalloc _tut() 리턴된데이터를정의된데이터타입으로변환하여저장하기위해다른 Buffer 를내부적으로할당한다. fbgetvalt() 변환된값에포인터를리턴한다. fbgetvali() 어느필드데이터이든지정수형으로리턴한다. fbgetvals() 어느필드데이터이든지문자형으로리턴한다. fbgetvals_ tu() 지정한필드키의필드순번에해당하는필드데이터를문자형으로리턴한다. 27
함 수 함수이름 기 능 fbgetntht() 변형된값을리턴한다. fbchg_tut( ) 필드키의값을필드 Buffer 에있는다른정의된시작순번에있는것과바꾼다. Buffer 조작함수 fbbufop() fbbufop_p roj() 두필드 Buffer 의내용을비교, 복사, 이동, 변경한다. 필드키에해당되는 Buffer 를변경한다. fbread() 파일로부터필드 Buffer 를읽는다. 이함수는표준 I/O 라이브러리에사용된다. I / O fbwrite() 파일에적는다. 이함수는표준 I/O 라이브러리에사용된다. fbprint() 표준 I/O 에 Buffer 내용을출력한다. fbfprint() 필드 Buffer 에있는활용가능한데이터를파일스트림에출력 에 러 fbstrerror( ) getfberrn o() 필드 Buffer 조작시에러내용을문자열로얻는다. 에러가나타나면에러넘버로리턴한다. 기 타 fbmake_fl dkey() 새로운필드키를동적으로생성하지만 FDLFILE 에는써넣지않는다. 28
함 수 함수이름 기 능 fbftos() fbstof() fbsnull() fbstelinit() fbstinit() 필드 Buffer 에저장된데이터를 C 구조체 (stname) 에전송한다. C 구조체에저장된데이터를구조체파일로쌓여져있는필드 Buffer 로전송한다. 필드 Buffer 에위치한 C 구조체의선택된필드키의구조체의멤버변수가 NULL 인지확인 필드 Buffer 에위치한 C 구조체의각각의멤버변수를 NULL 로초기화 필드 Buffer 에위치한 C 구조체를 NULL 로 초기화한다. 표 1-4. FIELD Buffer Functions 29
3 Tmax Buffer 유형 서로다른하드웨어, 서로다른운영체제간의통신은데이터값이변할수있다. 이것은하드웨어, 운영체제마다데이터유형의길이 ( 바이트수 ) 가다르고, 메모리할당방식이다르기때문이다. 이와같이통신상의문제점을해결하기위해서, 대부분이기종간통신에서는데이터를문자형으로바꾼다. 문자형으로변환하면네트웍부하가증가되고많은시간이소요된다. 예를들어 100,000 이라는 int 형의데이터를전송할때 32 비트운영체제에서 4 바이트이지만, 문자형으로변환하면 6 바이트가필요하기때문이다. 하지만 Tmax 에서는네트웍부하의감소와개발자에게개발의용이성을위하여다양한형태의 Buffer 를지원한다 : STRING; CARRAY; X_OCTET; STRUCT; X_COMMON; X_C_TYPE; FIELD. STRING Buffer 는널값으로끝나는문자형의데이터통신시사용된다. CARRAY 와 X_OCTET Buffer 는길이가지정된문자형일때사용한다. 데이터를보낼때에는반드시길이를명시해주어야한다. STRUCT 와 X_C_TYPE Buffer 타입은 C 언어의구조체타입의데이터통신에사용한다. Buffer 를할당할때반드시하위유형, 즉구조체이름을제시하여야한다. X_COMMON Buffer 는멤버타입이 char, int, long 으로한정된 C 구조체이다. FIELD 버퍼는필드키와데이터의구조로구성되어있다. Buffer 데이터를전송할때쓰인다. 는 Tmax 는 Buffer 의무결성을보장하기위해표준통신형을사용한다. 통신시표준통신형은데이터타입과메모리할당방식에기준을정하는것이다. 송신하기전에 Buffer 의데이터를표준통신형으로변환하고수신하기전에역변환한다. 데이터의변환 / 역변환을통해, Tmax 는이기종간통신시문자형뿐만아니라구조체형의 Buffer 도사용 30
가능하게된다. 표준통신형으로의변환을위해 Tmax 에서는 sdlc 프로그램이사용된다. sdlc 프로그램을이용하면클라이언트쪽에는표준통신형데이터로의변환을위한정보테이블이, 서버쪽에서는표준통신형으로의변환 / 역변환프로그램이생성된다. 서버쪽의변환 / 역변환프로그램은응용서버프로그램과함께컴파일되어야한다. 클라이언트쪽의정보테이블은사용된하드웨어와운영시스템을적응시키기기위해데이터를변환한다. 결론적으로구조체 Buffer 를사용할때반드시반드시 sdlc 명령을통하여클라이언트에는데이터정보테이블을, 서버에는변환 / 역변환프로그램을생성하여야한다. STRING, CARRAY, X_OCTET 버퍼는이기종간에도 string 형통신이가능하므로표준버퍼형으로의변환이필요없다.. STRUCT, X_C_TYPE, X_COMMON 는구조체 Buffer 이므로표준통신형으로변환되어야하고컴파일시추가되어야한다. 아래는구조체 Buffer(STRUCT, X_C_TYPE, X_COMMON) 를사용하는응용프로그램에서컴파일흐름이다. 여기서구조체 buffer 의이름은 demo.s 이다. 31
그림 1-2. 구조체 buffer 를이용한 Application 프로그램의컴파일 FIELD Buffer 는자주사용하는버퍼형태로 Macro 를사용하여조작하므로배우는데나사용하는데있어구조체보다쉽다. 아래는 FIELD Buffer(FIELD) 를사용하는응용프로그램에서컴파일흐름이다. 여기서 FIELD buffer 의이름은 demo.f 이다. 32
그림 1-3. FIELD buffer 를이용한 Application 프로그램의컴파일 자세한사항은 Tmax FDL Reference Manual 을참조하도록한다. 따라서 Tmax 응용프로그램개발자는 Tmax 에서제공하는다양한 Buffer 를사용함으로써아래와같은효과를얻을수있다 : 응용프로그램은다양한 Buffer 로업무프로그램을보다유연하게개발할수있도록한다. 데이터변환에필요한프로그램을필요로하지않는다. 네트워크부하를감소시킨다. 초기에설정한데이터유형을송신 / 수신할수있게함으로써문자형데이터로변환하는데따르는네트워크부하를감소시킨다. 33
4 Tmax 통신유형 Tmax 시스템에서응용서버와클라이언트사이의통신은동기통신, 비동기통신, 대화형통신의 3 가지유형이있다. 동기통신은클라이언트가 tpcall() 을호출하여서버에요청을보내고서버에서응답이올때까지블럭킹되어기다린다. 비동기통신은클라이언트가 tpacall() 을호출하여서버에요청을보낸후서버에서응답이올때까지기다리지않고, 다른일을처리할수있다. 응답을받고자할경우 tpgetrply() 를호출하여서버로부터응답을받는다. 대화형통신은 tpconnect() 서비스를연결하고 tpsend() 로메시지를보낸다. 그리고메시지를받을때는 tprecv() 로받는다. 동기 / 비동기통신은아래와같은특징을가진다 : 보통의경우동기형통신을가장많이사용한다. tpcall() and tpacall() 로서비스요청을한다. 데이터를보내기전에반드시 tpalloc() 으로송 / 수신 Buffer 할당해야한다 를 클라이언트는한번에하나의요청을보내고응답을받는다. 서버는요청을처리할때한건씩처리종료후다른요청을받는다. 서버의업무처리서비스루틴은 tpreturn() or tpforward() 에의해서끝난다. 대화형통신은아래와같은특징을가진다 : tpconnect() 로서비스요청을초기화한다. 34
데이터를보내기전에반드시 tpalloc() 으로송 / 수신 Buffer 할당해야한다. 를 서버는동기 / 비동기통신과는달리반드시대화형서비스함수만을사용하여프로그램을개발해야한다. 데이터를주고받기위해 tpsend() 와 tprecv() 를이용한다. 대화형통신에서 tpforward() 를사용할수없다. 대화형모드에서보통연결유지시간이길어잘사용하지않는다. 35
4.1 동기형통신 동기형통신은클라이언트가서비스를요청하고, 그응답이오거나 Timeout 이될때까지기다린다. 서비스를요청한후. 클라이언트는블록킹상태로응답을기다린다. 아래의그림은동기형통신을사용하는 Client/ Server 프로그램의동작원리를보여주고있다 : 그림 1-4. 동기형통신모델 36
4.2 비동기형통신 비동기형통신은클라이언트가서비스를요청하고응답을기다리지않고다른일을계속할수있다. 응답을받고자할때해당요청에대한응답을받는다. 서비스를요청하는 tpacall() 은호출시즉시반환되어다른서비스요청을처리할수있다. 하지만응답을받기위해호출하는 tpgetrply() 는응답이도착하거나타임아웃될때까지블럭킹되어기다린다. 아래의그림은비동기형통신을사용하는 Client/Server 프로그램의동작원리를보여주고있다 : 그림 1-5. 비동기형통신모델 37
4.3 대화형통신 tpconnect() 로연결을한후, tpsend() 와 tprecv() 를호출하여데이터를주고받는다. 데이터를보내려면 tpconnect() 와 tpsend() 에서플래그값의설정으로만움직이는연결컨트롤을가져야만가능하다. 아래는 client/server 프로그램중대화형통신모드의동작원리를보여주고있다 : 그림 1-6. 대화형통신모델 38
5 Tmax 클라이언트프로그램 5.1 Tmax 클라이언트함수개요 아래는 Tmax 함수중클라이언트프로그램작성시사용할수있는함수들이다 : 함수이름기능 연결함수 tpstart() tpend() 클라이언트 어플리케이션과 Tmax 를 연결한다. Tmax 와연결된클라이언트어플리케이션을해제한다. tpalloc() 데이터를송수신할 Buffer 를할당한다. Buffer 관리함수 tprealloc () Buffer 의크기를변경한다. tpfree() 할당된 Buffer 를해제시킨다. tptypes() Buffer 에있는정보를반환한다. 서비스요구 및 응답관련 tpcall() tpacall() 서비스를 요청하고 응답이 올 때까지 기다린다. 서비스를요청한후다른일을처리할수있으며 tpgetrply() 호출로요청결과를수신한다. 39
함수 tpcancel( ) 어떤서비스요청에대한응답을취소한다. tpgetrply () tpacall() 의호출에대한응답을받는다. tpconnec t() 대화형모드로서비스와연결을설정한다. 대화형함수 tpdiscon( ) 대화형모드서비스와연결을비정상적으로종료한다. tprecv() 대화형모드에서메시지를수신한다. tpsend() 대화형모드에서메시지를송신한다. 표 2-1. 클라이언트함수 5.2 Tmax 클라이언트함수 5.2.1 Tmax 연결및해제 5.2.1.1 int tpstart(tpstart_t *tpinfo) Tmax 시스템에접속하다. - TPSTART_T 구조체의항목 char cltname[maxtident + 2]; /* MAXTIDENT = 16 */ => 비요청메시지수신시사용되는사용자구별이름 char dompwd[max_passwd_length+2]; /* MAX_PASSWD_LENGTH = 16 */ => 시스템접속제어보안을위한암호 40
5.2.1.2 int tpend() char usrname[maxtident + 2]; => 사용자인증보안을위한사용자계정 char usrpwd[max_passwd_length + 2]; => usrname 에해당하는암호 int flags; => 비요청메시지유형과시스템접근방법결정 Tmax 시스템과의연결을끊음. 클라이언트프로그램에서가장먼저할일은 Tmax 시스템에연결하는것이다. 즉클라이언트는어떤서비스를요청하기전에먼저 Tmax 시스템에연결되어야만한다. 만약 tpstart() 가호출되기전에서비스를요청하였다면, 내부에서자동적으로 tpstart() 를 NULL 인자로부른다. tpstart() 는 Tmax 응용프로그램과연결할때 TPSTART_T Buffer 를가지고 Tmax 시스템에연결할수있다. 이것은클라이언트정보, 비요청메시지처리여부, 그리고보안관련정보를담고있다. 보안은시스템접속보안과사용자인증보안관련정보가포함된다. cltname 은최대길이 18 자이며, NULL 로끝나는문자열이다. cltname 은응용프로그램에서정의한이름이고, tpbroadcast() 에서일방적인데이터를보낼클라이언트를지정하기위해사용된다. dompwd 는시스템접속보안에대한 Tmax 시스템의단일암호이다. 만약시스템접속제어보안이설정된다면, 이항목에 Tmax 환경파일중 *DOMAIN 절의 OWNER 항목에지정된계정에해당하는암호를등록하면된다. 암호를옳게등록하여야만시스템접속에성공한다. 특별히등록하지않으면 NULL 로전달된다. usrname, usrpwd 는사용자인증보안을위해사용되는항목이다. 만약사용자인증보안이설정된다면, Tmax 시스템에인증가능한계정과그에해당하는암호를각각등록하면된다. 이를등록하지않거나인증된사용자가아니면 Tmax 시스템접속에실패한다. 특별히등록하지않으면, NULL 로전달된다. flags 는자발적인메시지처리와시스템접근방법을결정하기위해사용한다. 41
TPUNSOL_HND : 비요청메시지를받지만클라이언트가그것을받아들일지를결정할수있다. TPUNSOL_IGN : 비요청메시지무시 TPUNSOL_POLL: 비요청메시지허락 위와같이 TPSTART_T Buffer 를사용하겠다면 tpstart() 를호출하게전에 tpalloc() 으로 Buffer 를할당해야한다. Buffer 타입은 tpstart() 만을위한 TPSTART 로지정하여야한다. TPSTART_T Buffer 구조체는 atmi.h 헤더파일에선언되어있다. 에러가나타날때 tpstart() 와 tpend() 는 1 값을리턴하고, 외부전역변수인 tperrno 에에러번호가설정된다. 에러의각사항은 Tmax Error Message Reference 를참조하기바란다. <Ex 1> # include <usrinc/atmi.h> # include <usrinc/tmaxapi.h> main ( ) { if (tpstart((tpstart_t*) NULL ) == -1 ) { error processing routine buffer 할당. 사용자입력을받아서비스함수를호출서버로부터응답을받음... buffer 해제. if (tpend() == -1 ) { error processing routine <Ex 2> 42
# include <usrinc/atmi.h> # include <usrinc/tmaxapi.h> main() { TPSTART_T *tpinfo; /* TPSTART Buffer 할당 */ if((tpinfo = (TPSTART_T *)tpalloc( TPSTART, NULL, sizeof(tpstart_t)))== NULL){ error processing routine /* TPSTART_T 구조체항목 */ strcpy(tpinfo->dompwd, tmax1234 ); strcpy(tpinfo->usrname, tmax ); strcpy(tpinfo->usrpwd, tmax1234 ); /* Tmax 시스템에접속 */ if(tpstart(tpinfo) == -1){ error processing routine..... tpend( ) ; 43
5.2.2 Buffer 관리 서로다른하드웨어나운영체계에있어서메모리할당방식과데이터유형의크기차이로송신한데이터와다른데이터값을가질수있다. 따라서일반적인클라이언트 / 서버환경에서이기종간의통신은주로문자형으로변환하여통신하게된다. 이것은네트웍부하를증가시키는원인이되기도한다. Tmax 에서는통신에서사용할수있는 7 개의 Buffer 를지원한다 :STRING, CARRAY, X_OCTET, STRUCT, X_COMMON, X_C_TYPE, FIELD. STRING Buffer 타입은널로끝나는문자열의데이터일때사용된다. CARRAY 와 X_OCTET Buffer 타입은길이가지정된문자형의데이터일때사용된다. Buffer 를할당하거나보낼때반드시길이를명시하여야한다. STRUCT 와 X_C_TYPE Buffer 타입은 C 언어의구조체타입의데이터일때사용한다. Buffer 를할당할때반드시하위유형, 즉구조체이름을지정하여야한다. X_COMMON 은구성요소가 char, int, long 만가능한 C 언어구조체이다. 5.2.2.1 char *tpalloc(char *type, char *subtype, long size) : Buffer 할당 type : Buffer 유형 subtype : Buffer 의하위유형 size : Buffer 크기 tpalloc() 은서비스요청이나응답시필요한 Buffer 사용하는함수이다. 를할당하기위해 type 은앞에서언급한 7가지타입이지원된다. subtype 은 C 언어에서선언된구조체의이름이다. 그리고 Buffer 유형이 X_C_TYPE STRUCT, X_COMMON 일경우에만사용하며, 그외의경우에는 NULL 을갖는다. 44
size 는 CARRAY 와 X_OCTET 에서는반드시지정하여야하며이를제외하고는생략가능하다. 즉 0 으로지정하면각 Buffer 의기본크기가사용된다. STRING, STRUCT, X_C_TYPE, X_COMMON 의기본크기는 1024byte 이다. CARRAY 의기본크기는 0 이지만 Buffer 를할당할때에는반드시 0 보다커야한다. tpalloc() 이성공하면 char 타입의포인터를반환한다. 따라서 STRING 와 CARRAY 가아닌 C 언어구조체인경우에는반드시적합한형변환을하여야한다. tpalloc() 시에러가발생하면 NULL 포인터를반환한다. 에러는지정되지않은 Buffer 타입을사용하거나 STRUCT 타입에서 subtype 을지정하지않는경우에주로발생한다. <Ex 1> struct account *accp;... accp = (struct account *) tpalloc( X_C_TYPE, account, sizeof(struct account)); /* X_C_TYPE 타입은 subtype 을지정하여야함. */ <Ex 2> char *data; long datalen;... datalen = 512; data = tpalloc( CARRAY, NULL, datalen); /* CARRAY 인경우는 datalen 이 0 보다커야함. */ <Ex 3> char *data;... data = tpalloc( STRING, NULL, 0); /* size 가 zero 이면 STRING 타입은디폴트로 1024 byte 가할당됨. */ 45
<Ex 4>... /* C 언어구조체인경우에는반드시적합한형변환. */ if ((strdata = (struct strdata *)tpalloc( STRUCT, strdata, sizeof(struct strdata))) == NULL){ fprintf(stderr, tpalloc failed\n ); exit(0) ; strdata->id = cltid; strdata->passwd = cltpasswd; strcpy(strdata->msg, cltmsg);... <Ex5>... FBUF *sndbuf, *rcvbuf; char sndata[30], rcvdata[30];... if ((sndbuf = (FBUF *)tpalloc("field", NULL, 0)) == NULL) { error processing routine if ((rcvbuf = (FBUF *)tpalloc("field", NULL, 0)) == NULL) { error processing routine... fbput(sndbuf, INPUT, sndata, 0); 서비스호출 fbget(rcvbuf, OUTPUT, rcvdata, 0);... 46
5.2.2.2 char *tprealloc(char *bufptr, long size) Buffer 크기재조정한후새롭게할당된 Buffer 의포인터를반환함. bufptr : 재조정이될 Buffer 에대한포인터 size : 새로운 Buffer 의크기 tprealloc() 은 tpalloc() 으로할당된 Buffer 의크기를조정하고자하는경우에사용한다. 할당되지않은 Buffer 를조정하고자하는경우에는 tperrno 에 TPEINVAL 로설정되고크기조정에실패한다. tprealloc() 으로반환되는포인터는원래 Buffer 와같은형의 Buffer 를가리키지만주소는변경될수있다. 따라서 Buffer 크기를조정하였다면반드시 tprealloc() 에서반환된 Buffer 의포인터를사용하여야한다. tprealloc() 이실패하면 NULL 포인터를반환하고 tperrno 을설정한다. tperrno 의각사항은 Tmax Error Message Reference 를참조하기바란다. <Ex 1> char *data;... data = tpalloc( STRING, NULL, 512);... if ((data = tprealloc(data, 1024)) == NULL){ /* tpalloc() 으로할당된 Buffer 이어야한다. */ error processing routine <Ex 2> char *octet_ptr; char *ptr1, *ptr2;... octet_ptr = tpalloc( X_OCTET, NULL, 25);... if ((octet_ptr = tprealloc(octet_ptr, 40)) == NULL){ error processing routine 47
5.2.2.3 void tpfree(char *bufptr) 할당된 Buffer 를해제시킴 ( 반환값이 void 임을유의 ) bufptr : 해제시킬 Buffer 에대한포인터 tpfree() 은 tpalloc() 이나 tprealloc() 으로할당되었거나재조정된 Buffer 를해제한다. 만일 tpalloc() 이나 tprealloc() 으로할당된 Buffer 가아닌 Buffer 를 tpfree() 로해제하려고하면그 Buffer 는해제되지않으며 error 도반환하지않음에유의한다. < Ex > char *octet_ptr; char *ptr1, *ptr2; octet_ptr= tpalloc( X_OCTET, NULL, 25);... octet_ptr= tprealloc(octet_ptr, 40); tpfree(octet_ptr) ; 5.2.2.4 long tptypes(char *ptr, char *type, char *subtype) 이미할당된 Buffer 의유형과하위타입을알아냄. ptr : 할당된 Buffer 에대한포인터 type : 할당된 Buffer 유형에대한포인터 subtype : 할당된 Buffer 의하위유형에대한포인터 tptypes 는 tpalloc() 이나 tprealloc() 으로할당된 Buffer 의유형을판단한다. 첫번째인자는 Buffer 에대한포인터를가지고나머지두개의인자에는그 Buffer 의유형과하위유형을반환한다. Buffer 의유형을얻는데실패하면 1 을반환하고 tperrno 에에러를설정한다. <Ex > char type[9], subtype[17]; long len; 48
char *octet_ptr... octet_ptr = tpalloc( X_OCTET, NULL, 25);... len = tptypes(octet_ptr, &type, &subtype); 49
5.2.3 동기통신 5.2.3.1 int tpcall(char *svc, char *sbuf, long slen, char **rbuf, long *rlen, long flags) 동기적인송신과수신처리. ( 클라이언트는결과가 RETURN 될때까지대기함.) svc : 호출되는서비스이름 sbuf : 보내는 Buffer 의포인터 slen : 보내는 Buffer 의데이터길이 (CARRAY, X_OCTET, MULTI STRUCT 일때반드시설정 ) rbuf : 응답 Buffer 의포인터주소 rlen : 응답 Buffer 의데이터길이 flags : 호출시사용되는옵션 TPNOTRAN : 트랜잭션모드에서의호출이아님 TPNOCHANGE : 받는버퍼의타입이자동으로변경되지않음 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 TPNOTIME : Blocking time-out 을무시함 TPSIGRSTRT : 시그널캐취를허가함 TPNOFLAGS : 아무옵션도설정하지않음 tpcall( ) 은클라이언트가서비스를요청하고응답이올때까지기다리는동기통신이다. 50
그림 2-1. 동기형통신 tpcall() 은첫번째인자에서지정한 svc 로서비스요청을보낸다. 이서비스는 Tmax 응용서버프로그램에서제공되고있는것이어야한다. sbuf 는요청하는데이터의주소를가리키는포인터로써, tpalloc() 으로생성된것이어야한다. Buffer 타입은응용처리서비스루틴에서의타입과일치시켜야한다. 일치하지않으면시스템은 tperrno 에 TPEITYPE 을설정하고 tpcall() 은실패한다. 보낼데이터가없는경우 sbuf 을 NULL 로설정하면 slen 의값은무시되고, Buffer 를할당할필요도없다. slen 은보낼 Buffer(sbuf) 의크기를가리킨다. STRUCT, X_COMMON, X_C_TYPE, STRING, FIELD 는 tpalloc() 에서할당된크기대로통신에서사용하기때문에 slen 을 0 으로설정할수있다. CARRAY, X_OCTET 또는 MULTI-STRUCT 유형은반드시 slen 길이를지정해야한다. rbuf, rlen 은응답 Buffer 에대한주소와 Buffer 길이이다. 응답 Buffer(rbuf) 도보낼 Buffer 처럼 tpalloc() 으로미리만들어져야한다. 만일 tpcall() 이성공적으로수행되었더라도응답데이터가없다면 *rlen 는 zero 로설정된다. 에러가발생하면 *rbuf 이나 rlen 이 NULL 로설정된다. 보내는 Buffer 와받는 Buffer 를같이사용할수있다. 이때받는 Buffer(rbuf) 는보내는버퍼의주소로설정하여야한다. 즉 (char **)&sbuf 와같이지정해야한다. 만일서버로부터받는데이터가처음할당된 Buffer 크기보다크다면, 받는 Buffer 는자동적으로커지며 Buffer 의주소도달라질수있다. 또한보낼 Buffer 와받을 Buffer 를같이사용할때는주소가동시에달라진다. flags 는어떤방식으로통신할것인지를지정한다. 51
TPNOTRAN tpcall() 이트랜잭션범위 (tx_begin() 부터 tx_commit() 이나 tx_rollback() 사이 ) 에포함되더라도 TPNOTRAN 의 tpcall() 로요청된서비스는트랜잭션의범위에서제외된다 TPNOCHANGE tpcall() 에서받을응답 Buffer 가 tpalloc() 으로할당된타입과다를수있다. flags 을 TPNOCHANG 로설정하면처음할당된 Buffer 와응답 Buffer 의유형이일치되어야만한다 TPNOBLOCK 이플래그는블럭킹상태가존재할때어떤행동을취할지를나타낸다. 통신에서전형적인블럭킹은요청을보내고응답을기다리거나, 또는요청을받는서버큐나보내는내부큐가가득차서큐에쓰기위해기다릴때일어난다. 보통블럭킹이되면환경파일에정의된타임아웃시간만큼기다리게되며, 이시간이지나면 tperrno 에 TPETIME 로설정하고함수는실패된다플래그로 TPNOBLOCK 을설정한다는것은내부큐에대한블록킹상태가되면즉각실패가되고요청데이터를보내지않는다. tpcall() 에서는데이터를보낼때와응답을기다릴때블럭킹이일어날수있다 TPNOBLOCK 은데이터를보내기위해내부큐에 write 할때에만해당된다. 이때내부큐 (CLH 큐 ) 가가득찼으면블로킹되지않고즉시반환된다 TPNOTIME 플래그를 TPNOTIME 으로설정할때시스템은블러킹타임아웃을무시한다. 즉타임아웃시간을무시하고응답이올때까지기다리겠다는것이다. 만약트랜잭션이존재한다면트랜잭션타임아웃시간이적용되고이플래그는무시된다 TPSIGRSTRT 이플래그는시그널인터럽트수용하고자할때사용한다. 내부에서시그널인터럽트가발생하여시스템함수호출이 52
방해될때, 시스템함수호출이재실행된다. 만약이플래그가설정되지않은경우시스템인터럽트가발생하였다면, 그함수는실패되고 tperrno 에 TPGOTSIG 로설정된다 <Ex 1> struct transf *transfp; long nrecv;... if ((transfp = (struct transf *) tpalloc( STRUCT, transf, sizeof(struct transf))) == NULL){ error processing routine transfp->b_id = q_branchid; transfp->balance = 0.0; strcpy(transfp->errmsg, ); if (tpcall(svc_name, (char *)transfp, 0, (char **)&transf, &nrecv, TPNOFLAGS)== -1){ /* 보낼 Buffer 와받을 Buffer 를같이사용 */ error processing routine else printf( Branch %ld balance is %.2f\n, transfp- >b_id,transfp->balance) ; <Ex 2> struct send_dat *strdata; char *data; long len; if ((strdata = (struct send_dat *)tpalloc( STRUCT, send_dat, 0))== NULL){ error processing routine if ((data = tpalloc( STRING, NULL, 512)) == NULL){ 53
error processing routine strdata->id=cltid; strdata->passwd=cltpasswd; strcpy(strdata->msg, cltdata); if (tpcall( sel_ora, (char *)strdata, 0, &data, &len, TPNOTIME) == -1) { error processing routine 54
5.2.4 비동기통신 5.2.4.1 int tpacall(char *svc, char *sbuf, long slen, long flags) Client 에서서비스를호출하고즉시다른일을할수있도록한다. svc : 호출하는서비스의이름 sbuf : 보내질 Buffer slen : 요구된 Buffer 의데이터길이 (CARRAY, X_OCTET, MULTI- STRUCT 인경우유의 ) flags : 호출모드결정. TPNOTRAN : 트랜잭션모드에서의호출이아님 TPNOREPLY : 응답을받지않음 TPBLOCK : 서비스나서버의이상유무응답을받음 TPNOBLOCK: 서비스나서버의실패에대한응답을받지않음 TPNOTIME : Blocking time-out 을무시함 TPSIGRSTRT : 시그널캐취를허가함 TPNOFLAGS : 아무옵션도설정하지않음 tpacall() 은서비스요청을위해 svc 에서지시된서비스루틴으로메시지를보내고제어를즉시반환한다. 그요청에대한응답을받기위해서는 tpgetrply() 를이용한다. sbuf, slen, flags 는 tpcall() 과같은방식으로사용한다. tpacall() 이성공적으로완료되었으면연결을구별할수있는정수 (call descriptor (cd), 이하구별자로명칭 ) 를반환하며, 구별자는 tpgetrply() 에서사용된다. 실패하게되면 -1 을반환한다. tpacall() 에는다음플래그들이있다 : TPNOREPLY 55
이플래그는요청을보내고응답을받지않겠다는것이다. 이플래그가설정되고 tpacall() 이성공적으로완료되었다면구별자로 zero 가반환된다. 이구별자 (cd) 는 tpgetrply() 에서사용할수없다. tpacall() 이트랜잭션상태일때는응답을반드시받아야함으로이 flags 을사용할수없다. 만약사용하려면 flags 를 TPNOTRAN 과함께사용하여트랜잭션참여의일부분에서벗어나야한다. TPBLOCK 이플래그는요청을보내고서비스나서버의이상유무에대한응답을받겠다는것이다. 이플래그가설정되고 tpacall() 이성공적으로완료되었다면 tperrno 는 TP_OK 로설정된다. tpacall() 이실패시 Tmax 에러값이반환된다. 반환된구별자 (cd) 로는요청한데이터를응답받기위한 tpgetrply() 에서사용된다. <Ex 1> if ((cd = tpacall(sname, data, len, TPNOREPLY)) == -1 ) { error processing routine <Ex 2> if ((cd = tpacall(sname, data, len, TPBLOCK)) == -1 ) { error processing routine 5.2.4.2 int tpgetrply(int *cd, char **rbuf, long *rlen, long flags) 응답 Buffer 의데이터를받음. cd : tpacall() 호출에서반환된정수 ( 구별자 ) rbuf : 응답 Buffer 의포인터에대한주소 rlen : 응답 Buffer 의크기에대한포인터 56
flags TPNOTIME : Blocking time-out 을무시함 TPSIGRSTRT : 시그널캐취를허가함 TPNOCHANGE : 받는버퍼의타입이자동으로변경되지않음 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 TPGETANY : 구별자를무시하고가능한모든응답을받아들임 tpgetrply() 는 tpacall() 에의해서보낸요청에대한응답을받는데사용한다. tpgetrply 는기본적으로블럭킹통신이다. 즉일단호출하면응답을받거나블럭킹타임아웃이발생할때까지기다린다. 타임아웃이발생하면호출은실패하고 tperrno 에 TPETIME 이설정된다. cd 는 tpacall() 이반환한구별자로써, 요청된것에대응하는응답을구별할수있도록한다. rbuf 와 rlen 은 tpcall() 인자와사용이동일하다. 물론 rbuf 는 tpalloc() 으로미리할당되어야한다. rlen 이 0이면응답받은 Buffer 에데이터가없는것이다. 함수호출이실패하면 *rbuf 와 rlen 은 NULL 로된다. flags 대부분은 tpcall() 에서설명이되었다. 만약 flags 의값을 tpgetany 로설정하면 cd 는무시되고먼저가능한응답을반환한다. 응답이없으면기본적으로응답이도착할때까지기다린다. 그림 2-2. 비동기형통신 <Ex> 57
... if ((cd1 = tpacall( service1, buf1, 0, TPNOFLAGS)) == -1) error processing routine if ((cd2 = tpacall( service2, buf2, 0, TPNOFLAGS)) == -1)... error processing routine if (tpgetrply(&cd1, &buf1, &buf1len, TPNOFLAGS) == -1) error processing routine if (tpgetrply(&cd2, &buf2, &buf2len, TPNOFLAGS) == -1)... 5.2.4.3 int tpcancel(int cd) error processing routine 미응답된구별자를취소함. cd : tpacall() 호출에서반환된구별자 tpcancel() 은 tpacall() 로반환된구별자를취소한다. 전역트랜잭션에참여중인구별자를취소하려고하면에러가발생한다. 호출이성공하면 cd 는더이상사용할수없다. 실패하면 -1 이반환된다. <Ex 1>... if ((cd = tpacall( service1, buf1, 0, TPNOFLAGS)) == -1) error processing routine... if (tpcancel(cd) == -1) error processing routine... 58
5.2.5 비요청메시지처리 비요청메시지처리함수는메시지를무조건보내거나, 일방적으로보내는메시지를처리하기위한함수이다. 서버에서보내는일방적인메시지 ( tpbroadcast () ) 를언제나, 모든클라이언트가받을수있는것은아니다. 비요청메시지를받기위해서는먼저클라이언트가 Tmax 에접속되어있어야하고, Tmax 접속시비요청메시지를받겠다는정보를주어야한다. tpstart() 시사용하는 TPSTART_T 구조체의 flags 값을 TPUNSOL_POLL 이나 TPUNSOL_HND 로설정해야만서버에서보내는일방적인데이터를 Tmax 가중계하여준다. 5.2.5.1 void *tpsetunsol(void(* disp)(char *data, long len, long flags))() 비요청메시지처리를위한함수를설정함. tpsetunsol() 로전달하는 Buffer 를받아서인자로지정된함수에서처리하도록하기위해사용한다. tpbroadcast() 을이용하여일방적인메시지를받기위해선 tpstart() 인자인 TPSTART_T 의구조체의 flags 을 TPUNSOL_HND 로설정하여야한다. <Ex1> main(int argc, char *argv[]) {... TPSTART_T *tpinfo;... tpinfo = (TPSTART_T *)tpalloc("tpstart", NULL, sizeof(tpstart_t)); if (tpinfo == NULL) { error processing routine... tpsetunsol(get_unsol); 59
... void * get_unsol(char *data, long len, long flag) { printf("unsolicited data = %s\n", data); 5.2.5.2 int tpgetunsol(int type, char **data, long *len, long flags) type : UNSOL_TPPOST, UNSOL_TPBROADCAST, UNSOL_TPSENDTOCLI data : 받을 Buffer len : 받을 Buffer 크기 flags TPBLOCK,TPNOCHANGE,TPBLOCK,TPNOTIME,TPSIGRSTRT tpgetunsol() 는 tpbroadcast() 로전달하려고하는 Buffer 를받고자할때사용한다. tpgetunsol() 를 이용하여 일방적인 메시지를 받기 위해선 Tmax 에 처음으로접속할때, tpstart() 인자인 TPSTART_T 구조체의 flags 값으로는 TPUNSOL_POLL 또는 TPUNSOL_HND 로설정하여야한다. 이 flags 값으로는 TPUNSOL_POLL, TPUNSOL_HND, TPUNSOL_IGN 이사용된다. TPUNSOL_IGN 은서버의일방적인메시지를무시하겠다는뜻이며, TPUNSOL_POLL 과 TPUNSOL_HND 는 서버의 일방적인 메시지를 받겠다는것이다. type 에 UNSOL_TPSENDTOCLI 로지정하면서버에서 tpsendtocli API 로보낸데이터를직접수신할수있다. data 는 tpbroadcast() 에서보내는 Buffer 이다. len 은받을 Buffer 인 data 의크기이다. flags 로는 TPBLOCK 과 TPNOBLOCK 이있다. 기본값은 TPBLOCK 이고, 이것은 tpgetunsol() 를호출하면받는큐룰체크하여서버에서메시지가 60
올때까지블록킹되어기다린다. TPNOBLOCK 는큐를체크하여메시지가없으면즉각반환된다. <Ex>... if ((rc_buf = (char*)tpalloc( STRING, NULL, 512)) == NULL){ exit(0); if ((val = tpgetunsol(unsol_tpsendtocli, rc_buf, &len, TPBLOCK)) < 0){ error processing routine... 5.2.6 타임아웃변경 5.2.6.1 int tpset_timeout(int sec) Client 에서서버쪽에설정된블로킹타임아웃시간을변경하도록한다. sec : 변경할타임아웃시간. ( 초단위 ) 클라이언트는서비스를요청한후그에대한응답을일정한시간동안기다리게된다. 그시간안에응답이도착하면이를정상적으로수신하며, 만약이시간이지날때까지응답이도착하지않으면클라이언트는응답을기다리는일을중단하고에러를리턴한다. 후에응답이도착하면이를무시한다. 이시간이블로킹타임아웃시간이다. 이는 Tmax 환경파일중 *DOMAIN 절의 BLOCKTIME 항목에정의된다 (Tmax Administration Guide 참조 ). 정의된 BLOCKTIME 시간이 Tmax 시스템에접속된모든클라이언트에세적용된다. 이때, 클라이언트에서이시간을변경하고자할경우사용되는함수가바로 tpset_timeout() 이다. 서비스요청전에이 tpset_timeout() 함수를호출하면이후그클라이언트의서비스요청에대하여는 tpset_timeout() 으로변경한시간값이적용된다. 이는다시 tpset_timeout() 을호출하거나클라이언트가종료할때까지유효하다. sec 는초단위이다. <Ex> 61
main(int argc, char *argv[ ]) {.... if(tpstart(null) == -1) { printf( Tpstart failed\n ); exit(1); printf( tpstart-ok \n ); if((sndbuf = (struct kstrdata *) tpalloc( STRUCT, kstrdata, 0))== NULL) { error processing routine /* 10 초로블로킹타임아웃시간을변경 */ tpset_timeout(10); if (tpcall( BLOCK, (char *)sndbuf, 0, (char **)&rcvbuf, &rcvlen, TPNOFLAGS)== -1){ error processing routine sleep(3); /* 30 초로블로킹타임아웃시간을변경 */ tpset_timeout(30); if (tpcall( BLOCK2, (char *)sndbuf, 0, (char **)&rcvbuf, &rcvlen, TPNOFLAGS)== -1){ error processing routine.... tpend(); 5.3 Tmax 클라이언트프로그램컴파일 클라이언트프로그램의코딩이끝났다면이제컴파일하여실행파일을만들차례다. 클라이언트프로그램을컴파일하기위해서는개발자가작성한클라이언트프로그램, Tmax 클라이언트라이브러리, 구조체 62
Buffer 를사용한다면구조체파일이, 그리고필드키 Buffer 는필드테이블이정의된파일이준비되어야한다. 5.3.1 클라이언트프로그램구성 5.3.1.1 클라이언트프로그램 : 개발자가작성한클라이언트프로그램이다. 5.3.1.2 Tmax 클라이언트라이브러리 ( libcli.a / libcli.so) Tmax 가제공하는라이브러리로클라이언트프로그램개발시사용하는함수들의 object 코드이다. 5.3.1.3 구조체파일 (.s) 클라이언트프로그램에서구조체 (STRUCT, X_C_TYPE, X_COMMON) 를사용하였다면 파일명.s 로끝나는구조체파일이필요하다. 이구조체파일을 sdlc 명령어를이용하여미리컴파일한다. 컴파일하면구조체의각데이터가표준통신형으로변환되는데필요한정보를담은이진 (binary) 형태의파일이생성된다. 이는클라이언트프로그램실행시에표준통신형으로데이터가송 / 수신되는데사용한다. 5.3.1.4 필드키파일 (.f) 필드키구조를사용하였다면.f 로끝나는필드정의파일이필요하다. 이파일을 fdlc 명령어를이용하여컴파일하면, 이때필드키 Buffer 파일은 Key Mapping 을이용하여 필드키 Buffer 이름 _fdl.h 을만들어프로그램실행시사용하게된다. 기존의구조체파일과는달리사용자가원하는필드의값만을조작하고전달할수있어자원의낭비를줄일수있다. 하지만 key Mapping 하는과정에서의오버헤드도있다는점을간과해서는안될것이다. 5.3.2 클라이언트프로그램컴파일 클라이언트프로그램을컴파일하여오브젝트파일을생성한다 (ex: aptest.c -> aptest.o). 이때, Tmax 에서제공하는 atmi.h( 또는 tmaxapi.h) 파일이 63
참조되어야하며, 만약구조체통신을한다면관련된구조체파일 (ex: demo.s) 도함께참조되어야한다. 오브젝트형태의클라이언트프로그램과클라이언트프로그램에서사용하는라이브러리, 그리고 Tmax 에서제공하는클라이언트라이브러리 (libcli.a 또는 liblia.so) 를함께링크하여실행파일을생성하도록한다. 그림 2-3. 구조체 buffer 를사용한클라이언트프로그램컴파일 64
그림 2-4. FIELD buffer 를사용한클라이언트프로그램컴파일 다음은 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) 65
#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) $(TMAXLIBS) $(CC) $(CFLAGS) -L$(TMAXLIBD) -o $(TARGET) $(APOBJS) # clean: -rm -f *.o core $(TARGET) Tmax 에서제공되는예제프로그램에는 compile 이라는 shell script 를사용하여 make 를실행하고있다. 이 compile 이라는 shell script 를사용하기위해서는 command 에아래와같이입력을한다. compile c cli (=> 확장자를뺀클라이언트프로그램이름 ) 이렇게하면 compile 에서 make file 의 EXE 에확장자를뺀클라이언트이름을넣게되어동일한동작을하게된다. 66
5.3.3 클라이언트프로세스기동및종료 5.3.3.1 클라이언트를위한 Tmax 환경변수 TMAX_HOST_ADDR 및 TMAX_HOST_PORT 클라이언트프로그램은 Tmax 에연결할때환경변수에서필요한정보를얻기때문에미리 UNIX 쉘환경파일 (c shell:.cshrc, korn shell:.profile, bash shell :.bash_profile, etc.) 에 TMAX_HOST_ADDR, TMAX_HOST_PORT 가설정되어있는지확인한다. TMAX_HOST_ADDR=Tmax system node IP TMAX_HOST_PORT=8888 TMAX_HOST_ADDR 는 Tmax 가있는서버의 IP 를나타낸다. 이설정은매우중요한역할을한다. 클라이언트가요청한서비스가처음연결이설정된서버에있지않다면내부적으로다시연결을설정하여서버스를받게된다. 그리고클라이언트가트랜잭션처리를요구했다면처음연결이설정된 Tmax 가트랜잭션의조정자가되어 2PC(Phase Commit) 를주관하게되기때문이다. 따라서가장많이사용되는서비스가위치한서버의주소를설정함으로써네트워크부하경감은물론응답시간의단축도기대할수있다. Tmax 환경파일에 TPORTNO 가설정되어있지않으면디폴트로 8888 이사용된다. TMAX_BACKUP_ADDR 및 TMAX_BACKUP_PORT 장애에대비하여 TMAX_BACKUP_ADDR 과 TMAX_BACKUP_PORT 를 설정할수있다. 이를설정해놓으면클라이언트에서서비스요청시, 먼저 TMAX_HOST_ADDR 가지정하는서버로연결을시도하고, 만약그 서버가장애라면 TMAX_BACKUP_ADDR 가지정하는서버로다시 연결을시도한다. 이경우 TMAX_BACKUP_ADDR 이지정되어있지 않다면클라이언트의요청은재접속시도없이바로실패로끝난다. TMAX_BACKUP_PORT 는 TMAX_BACKUP_ADDR 가지정하는 Tmax 서버의포트번호이다. TMAX_CONNECT_TIMEOUT 67
네트워크장애에대비하여 TMAX_CONNECT_TIMEOUT 를지정할수있다. 이환경변수는클라이언트가정한시간동안대기한다. 만약 TMAX_CONNECT_TIMEOUT 에지정된시간내에설정되지않으면 tpstart() 는실패로끝난다. 네트워크장애시에는 tperrono 를 TPETIME 로설정한다. 만약 TMAX_BACKUP_ADDR/TMAX_BACKUP_PORT 가설정되면 tpstart() 는다른 TMAX_CONNECT_TIMEOUT 시간을백업호스트를하기위해시도한다. SDLFILE 이는구조체통신을하는클라이언트프로그램인경우, 반드시설정되어야하는환경변수이다. 이변수에는클라이언트프로그램에서사용하는구조체파일이 sdlc 로컴파일된 sdl 파일이정의되어야한다. 구조체파일은다음과같은형식으로컴파일한다 : $ sdlc -c -i 구조체파일이름 [ -o sdl 파일이름 ] [ -h 헤더파일이름 ] 구조체파일이름으로는파일하나또는여러개가정의될수있으며, 확장자에상관없다. * 가모든파일에대응하는와일드카드로사용될수있다. 구조체파일에는 struct 이름 {... ; 형식으로구조체가하나이상정의되어야한다. -o 옵션은생성될 sdl 파일이름을지정하는데사용되며, 이것이바로 SDLFILE 변수에정의되는이름이다. -o 옵션이생략된다면, 디폴트로생성되는 sdl 파일은다음과같다.: 구조체파일이하나인경우 : 확장자를제외한구조체파일이름.sdl Ex ) sdlc -c -i demo.s -> demo.sdl 구조체파일이여러개나열된경우 : 맨앞의구조체파일이름.sdl Ex ) sdlc -c -i stra.s bana.s orage.s -> stra.sdl Ex ) sdlc -c -i *.s -> a.sdl ( 현재디렉토리에존재하는.s 파일이 a.s, b.s, c.s 일때.) 68
-h 옵션은구조체정보를단순히헤더파일형식으로생성한다. -h 옵션이생략되면, 이름 _sdl.h 가생성된다. 이와같이 sdlc 로컴파일된 sdl 파일이 SDLFILE 변수에정의되어야한다. 구조체통신실행시, 구조체정보가 SDLFILE 에있으면 Tmax 서버와의통신을할수있다. FDLFILE 이는 FIELD buffer 통신을하는클라이언트프로그램인경우, 반드시설정되어야하는환경변수이다. 이변수에는클라이언트프로그램에서사용하는 FIELD buffer 파일이 fdlc 로컴파일된 fdl 파일이정의되어야한다. FIELD 파일은다음과같은형식으로컴파일한다 : $ fdlc -c -i FIELD 파일이름 [ -o fdl 파일이름 ] [ -h 헤더파일이름 ] -o 옵션은생성될 fdl 파일이름을지정하는데사용되며, 이것이바로 FDLFILE 변수에정의되는이름이다. -o 옵션이생략된다면, 디폴트로생성되는 fdl 파일은 tmax.fdl 이된다. -h 옵션은구조체정보를단순히헤더파일형식으로생성한다. -h 옵션이생략되면, 이름 _fdl.h 가생성된다. 이와같이 fdlc 로컴파일된 fdl 파일이 FDLFILE 변수에정의되어야한다. FIELD buffer 통신실행시, FIELD 정보가 FDLFILE 에있으면 Tmax 서버와의통신을할수있다. 유닉스환경파일에 Tmax 환경변수가설정되어있다면, 클라이언트프로세스를생성시키는데필요한준비는끝났다. 클라이언트프로세스는다른실행파일과같은방법으로실행하고종료시키면된다. 69
6 Tmax 서버프로그램작성 6.1 Tmax 서버함수개요 여기서는 ATMI 에서서버프로그램작성시필요한함수에대해알아본다. 서버또한클라이언트역할도할수있기때문에클라이언트에서사용하는함수도사용이가능하다. 함수이름기능 서비스요청 관련함수 tpreturn() tpforward() 서비스요청에대한응답을클라이언트에게보내고서비스루틴을종료한다. 또다른서비스를처리하기위해다른서버로서비스를의뢰한다. 비요청관련 함수 tpbroadcast( ) tpsendtocli () 클라이언트의요청이없더라도서버에접속된모든클라이언트에게자동으로메시지를송신한다. 클라이언트의요청이없더라도서버에서클라이언트가사전등록한요구메시지를자동으로송신한다. 서버초기화와종료관련함수 tpsvrinit() 서버를초기화한다. tpsvrdone() 서버의초기화를해제한다. 표 2-2. 서버함수 70
6.2 Tmax 서버함수 6.2.1 서비스루틴인자 서버프로그램은 Tmax 에서제공하는 main() 과서비스루틴으로이루어진다. main() 은데이터베이스연결및해제, 명령어라인옵션처리등의역할을하는루틴으로이루어져있으며, 서비스루틴은실제로클라이언트의요청을받아업무를처리하는루틴으로이루어져있다. 서버 main() 은클라이언트요청을받아서해당서비스루틴을 TPSVCINFO 구조체로호출하여요청을처리하게한다. TPSVCINFO 구조체는서비스를요청한클라이언트에대한정보와처리할데이터정보를가지고있다. TPSVCINFO 구조체는 atmi.h 헤더파일에선언되어있으며, 구성요소는아래와같다.: #define XATMI_SERVICE_NAME_LENGTH 16 struct tpsvcinfo { ; char name[xatmi_service_name_length]; /* 요청된서비스이름 */ char *data; /* 요청데이터 */ long len; /* 요청데이터길이 */ long flags; /* 서비스속성 */ Int cd; /* 연결구별자 */ typedef struct tpsvcinfo TPSVCINFO name 은클라이언트에서요청한서비스루틴의이름이다. data 는클라이언트가요청데이터를받기위해서사용되는 Buffer 로써, 서버 main() 안에서 tpalloc() 으로미리할당되어진다. 71
len 은요청한데이터의길이를나타낸다. flags 는서비스에게트랜잭션상태에있는지, 또는호출자가반드시응답을요구하는지등을알려준다. 예를들어 flags 가 TPTRAN 이라면서비스가트랜잭션모드안에있다는것을, TPNOTRAN 이라면현재의트랜잭션에참여할수있다는것을알게한다. cd 는연결구별자이다. 이것은어떤클라이언트에게응답을보내야할지를알게한다. 서버는클라이언트가요청한서비스를처리하기위해미리 Buffer 를 main() 에서할당하기때문에 tpreturn(), tpforward() 로통신할때 TPSVCINFO 의 data 를쓸것을권장한다. TPSVCINFO 의 data 에대해접근할때, 서버프로그램과클라이언트프로그램의 Buffer 유형이같아야한다. <Ex> 클라이언트부분 ) #include <usrinc/atmi.h>... main() { struct strdata *cltdata; if ((cltdata = (strcut strdata *)tpalloc( STRUCT, strdata, sizeof(struct strdata)) ) == NULL){ error processing routine... if ((tpcall ( SEL_SVC, cltdata, 0, (char **)&cltdata, &len, TPNOFLAGS))== -1){ error processing routine... 72
서버부분 ) 개발자가작성한서비스루틴으로써 main() 은 Tmax 에서제공 #include <usrinc/atmi.h>... SEL_SVC(TPSVCINFO *msg) /* 클라이언트와클라이언트의요청내용이들어있는구조체 */ { struct strdata *svcdata; /* Buffer 유형과일치하도록데이터형을변환 */ svcdata = (struct strdata *)msg->data;... svcdata->ip = sip; strcpy(msg ->data, svcdata); tpreturn(tpsuccess, 0, msg->data, sizeof(struct strdata), TPNOFLAGS); ; 6.2.2 서비스완료 서비스루틴의완료를표시하는함수로 tpreturn() 과 tpforward() 가있다. tpreturn() 은클라이언트에게응답을보내는것이며, tpforward() 는필요에의하여또다른서버로서비스요청을전가하고서비스를끝낸다. 6.2.2.1 void tpreturn(int rval, int rcode, char *data, long len, long flags) 서비스요구에대한응답을클라이언트로보냄. rval : 서비스완료값을반환함 TPSUCESS : 서비스가정상처리됨 TPFAIL : 서비스가비정상처리됨. (tperrno 가설정됨.) TPEXIT: TPFAIL 과같은의미이며, 서버는종료 (exit) 함 rcode : 응용프로그램에서지정한반환값으로설정이됨 73
data : 응답 Buffer 에대한포인터 len : 응답 Buffer 의길이 (CARRAY, X_OCTET 또는 MULTI- STRUCT 인경우 ) flags : TPNOFLAGS tpreturn() 은서비스처리결과를클라이언트에게보내고서비스루틴을마친다. tpreturn() 은서비스루틴을마치면서컨트롤을서버메인으로반환한다. 만일이때서비스루틴에서비동기로다른서버의서비스를요청한것이있다면, 컨트롤이메인으로반환되기전에모두응답을받거나 tpcancel() 로그것들을무효화시켜야한다. 그렇지않으면응답들이왔을때, Tmax 메인에서응답내용을무시하고서비스를요청한곳에에러를반환한다. rval 인자는 TPSUCCESS, TPFAIL, TPEXIT 로설정될수있다. 이값들은서비스가응용레벨 (application level) 에서성공적으로완료되었는지여부를표시한다. TPSUCCESS 은처리가성공적임을표시하며, 응답메시지를요청자에게전달한다. TPFAIL 은처리가실패했음을표시하며, 요청자에세에러가전달된다. rval 를 TPFAIL 로지정하면서비스를요청한쪽의 tpcall() 이나 tpgetrply() 은실패하고 tperrno 에 TPESVCFAIL 이설정된다. TPEXIT 는기능적으론 TPFAIL 이수행되고, 응답이클라이언트에보내진후서버는 exit 한다. 기본값은 TPFAIL 이다. rcode 인자는요청자에게어플리케이션레벨에서정의된반환코드 (application-defined return code) 를알리기위해사용된다. 클라이언트에서는 rcode 로반환된값이전역변수 tpurcode 에설정된다. rcode 는서비스처리가성공하든실패하든보낼수있다. data 는클라이언트로반환될결과데이터에대한포인터이며이메시지 Buffer 는미리 tpalloc() 으로할당되어야한다. 서비스를시작할때 TPSVCINFO 형의 Buffer 는 main() 루틴에서미리할당되므로 tpalloc() 으로할당할필요가없다. main() 루틴에서할당된 Buffer 는서비스루틴에서해제시킬수없고단지 tprealloc() 으로 Buffer 크기만조정할수있다. Tmax 는메인에서할당된 Buffer 가서비스에서크기변화에상관없이동일한 Buffer 로처리한다. 서비스루틴안에서 tpalloc() 으로할당하여사용하는 Buffer 는 tpreturn() 시자동으로해제된다. 만일응답메시지에데이터영역이없다면 data 에 NULL 을설정할수있다. 74
len 은응답 Buffer 의데이터길이이다. data 영역이 NULL 이면 tpreturn() 은 len 인자를무시하고 zero 로설정하여보낸다. tpacall() 에서 TPNOREPLY 로설정될때서버는 tpreturn() 에서 buffer 와길이를무시하고컨트롤을메인으로반환하며서버는다음서비스를처리할수있게된다. flags 인자는아직사용하지않고있다. TPNOFLAGS 로설정하면된다. <Ex 1> /* 클라이언트에게 sdata 의내용을 len 만큼보냄. */ tpreturn(tpsuccess, 0, sdata, len, TPNOFLAGS); <Ex 2> /* 클라이언트에게 TPESVCFAIL 값을보내고내용을보내지않는다. */ tpreturn(tpfail, 0, transb->data, 0, TPNOFLAGS); 6.2.2.2 void tpforward( char *svc, char *data, long len, long flags) 서비스요청을다른서버로보냄. svc : Buffer 를받을서비스이름 data : 보내질 Buffer 에대한포인터 len : 보내질 Buffer 의길이 (CARRAY 등에서사용 ) flags : 현재사용되지않음 tpforward() 는필요에의해다른서비스를요청할때사용한다. 이함수는 tpcall(), tpacall() 등의서비스를요청하는함수와는성격이다르다. tpforward() 를부른서비스측은결과값을받지않으며응답은서비스요청을받은서비스에서클라이언트로직접전달된다. 즉 tpreturn() 했을때응답은 tpforward() 호출한서비스루틴으로보내지지않고, 처음요청을보낸클라이언트에게로바로간다. tpforward() 는 tpreturn() 과거의같다. 호출되었을때메인에컨트롤이반환되고메인은다른일을처리할수있게된다. 주의할점은서버가클라이언트로서동작할때응답을 tpforward() 로요청하는서버에되돌릴수없다. 즉재귀하는요청은제공하지않는다. 75
하지만응답을기대하지않을때, TPNORPLY 로설정한요청은정상처리된다. 그림 2-5. tpforward <Ex> /*DEPOSIT 이라는다른서비스로서비스를요청함 */ tpforward( DEPOSIT, transb->data, 0, 0); 6.2.3 서버초기화와종료루틴 Tmax 에서기본적으로제공되는서브루틴으로 tpsvrint() 와 tpsvrdone() 이있다. 이것들은주로응용프로그램과연결할데이터베이스의 open 과 close 를담당하고, 명령어라인옵션처리등의기능을제공한다. 이서브루틴을개발자가작성하지않으면 Tmax 에서기본적으로제공된다. 6.2.3.1 int tpsvrinit(int argc, char **argv) : 서버의 Start-Up 루틴 tpsvrinit() 는서버를실행할때초기화를위한루틴이며, 만일사용자가작성하지않으면기본으로제공되는초기화루틴이포함된다. 역할은데이터베이스를열고, 명령어라인옵션 (command line option) 을받아서 76
초기화하는작업을한다. 이것은서버프로그램에연결할 NonXA 모드데이터베이스를만들기위해사용한다. <Ex> #include <stdio.h> #include <usrinc/atmi.h> EXEC SQL INCLUDE sqlca.h; tpsvrinit(int argc, char **argv) { EXEC SQL begin declare section; char user_name[30]; char user_passwd[30]; EXEC SQL end declare section; int c; /* 명령어라인옵션을받아서처리한다.*/ while ((c = getopt(argc,argv, "U:P:"))!= EOF) { switch((char)c) { case 'U': strcpy(user_name, optarg); break; case 'P': strcpy(user_passwd, optarg); break; /* 데이터베이스연결 */ EXEC SQL CONNECT :user_name IDENTIFIED BY :user_passwd; if (sqlca.sqlcode!= 0) { error processing routine return(0); 77
6.2.3.2 void tpsvrdone() : 서버종료루틴 서버가메모리에서내려올경우 (tmdown 명령실행시 ) 에수행되는루틴으로만일작성하지않으면 Tmax 에서기본적으로제공되는종료루틴이실행된다. 역할은필요에의해할당된모든자원을닫고반환한다. 주로데이터베이스를닫는루틴으로사용된다. <Ex> void tpsvrdone() { EXEC SQL COMMIT WORK RELEASE; 78
6.2.4 XA 모드와 NonXA 모드 서버프로그램은트랜잭션과데이터베이스연결형을가짐으로써 XA 모드, Non XA 모드로구별된다. Tmax 시스템이기동되어있다면데이터베이스재기동시에도 Tmax 시스템을재기동할필요없이내부적으로재연결이맺어지기때문에서비스가정상적으로이루어진다. XA 모드는분산트랜잭션처리를함에있어 X/Open DTP 모델을표준으로삼는다. 예를들어분산환경하에서트랜잭션을그룹지어다양한서비스들을요청한다. Tmax 에서제공하는 TMS 서버는트랜잭션처리를관리한다. 개발자는트랜잭션범위와제어를설정할수있다.(tx_begin, tx_commit, tx_rollback 등을사용한다.) NonXA 모드는네이티브 SQL 과정확하게 RDBMS 에연결된트랜잭션제어를가진서버프로그램방식이다. NonXA 모드는네이티브 SQL 로 RDBMS 와직접적으로연결하여트랜잭션제어를서버프로그램이가지고있는방식이다. NonXA 모드는 Tmax 에서제공하는트랜잭션을사용할수없다. 또한 local 트랜잭션만이가능하게된다. XA 모드는다중 RDBMS 와함께분산개발환경에서사용한다. 또한항상일관된데이터가있는시스템에사용된다. XA 서비스내에서서버트랜잭션을수행할때, 서버프로세스가비정상종료되는경우에해당트랜잭션은롤백된다. XA 모드서버프로그램은 XA 모드서버그룹에속해있다. Tmax 의 TMS 프로세스는데이터베이스연결과트랜잭션을관리한다. 다음은 Tmax 환경파일에있는 XA 모드서버그룹환경설정의예이다. *SVRGROUP svg1 NODENAME = tmax, DBNAME = ORACLE, OPENINFO = ORACLE_XA+Acc=P/scott/tiger+SesTm=600, TMSNAME = svg1_tms *SERVER svr1 SVGNAME = svg1 79
Non XA 모드서버프로그램은배치타입이나간단한서버프로세스의쿼리에적합하다. Non XA 모드에서도트랜잭션범위와제어를설정할수있다. 하지만 Non XA 모드의유저어플리케이션과 RDBMS (direct connection) 사이에서만가능하다. Tmax 와는전혀관련이없다. Non XA 모드에는 XA 모드와 2 가지다른점이있다. 첫째로유저어플리케이션의 SQL 을사용함으로써 RDMBS 와연결하거나연결을끊는다. 둘째로서버프로그램은트랜잭션을요청할수있지만클라이언트프로그램은할수없다. Non XA 서버프로그램은 DB 와연결하거나해제할때 tpsvrinit() 와 tpsvrdone() 루틴을사용하는것을추천한다. 다음은 Tmax 환경파일의 Non XA 모드서버그룹환경설정예이다. *SVRGROUP svg1 NODENAME = tmax *SERVER svr1 SVGNAME = svg1 서버프로그램의 XA 모드설정여부는어플리케이션디자인단계에서결정되어야한다. 위에서언급한것과같이 XA 모드는분산환경에서하나이상의데이터베이스를처리하는데필요하다. 그러나 Non XA 모드는간단한셀렉트쿼리나수행시간이긴배치서버프로그램을하는데적당하다. 6.2.5 비요청메시지관련인터페이스 Tmax 에서서버는클라이언트가요청하지않은메시지를클라이언트에게일방적으로보낼수있다. 이것은 Tmax 에접속되어있는클라이언트에게알리고싶은메시지를전달하고자할때사용한다. 비요청메시지를받을수있는클라이언트는 Tmax 에접속되어있어야하고, Tmax 접속시비요청메시지를받겠다고플래그값을설정해야한다. 80
6.2.5.1 Int tpbroadcast( char *lmid, char *usrname, char *cltname, char *data, long *len, long flags) 비요청메시지를보냄. lmid : 메시지를받을대상이되는노드이름 usrname : 메시지를받을대상이되는사용자이름 cltname : 메시지를받을클라이언트그룹 data : 메시지 Buffer len : 메시지 Buffer 의길이 flags : 메세지송신시사용되는옵션 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 TPNOTIME : Blocking time-out 을무시함 TPSIGRSTART : 시그널캐취를허가함 이함수는클라이언트와서버가다른클라이언트에게로비요청메시지를보내고자할때사용한다. 이때비요청메시지를받을클라이언트는 Tmax 에접속되어있어야하며, tpstart() 에서비요청메시지를받겠다는플래그로접속되어있어야만한다. 받을대상이되는클라이언트는 cltname 에설정된다. cltname 정보는 tpstart() 호출시 TPSTART_T 구조체의 cltname 에설정된값이다. <Ex>... ret = tpbroadcast(null, "user", cli1, (char *)msg->data, 0, 0); if (ret < 0) { error processing routine... 81
6.2.5.2 int tpsendtocli(int clid, char *data, long len, long flags) clid : Tmax 에서얻은클라이언트의유일한값 data : 보낼 Buffer 에대한크기 len : Buffer 크기 flags : 메세지송신시사용되는옵션 TPFLOWCONTROL : 클라이언트의상태를점검하고다른메시지를요청할수있는지확인함 TPUDP : 호출자가데이터를송신할때, 송신할내부버퍼에전달될메세지가가득차서보내지못할경우데이터를버려도됨. TPUDP TPFLOWCONTROL : TPFLOWCONTROL flag 와비슷하지만이 flag 는큐가가득찼을경우 1 이아닌일반적인결과물을 return 함 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 tpsendtocli() 는단지서버에서만사용할수있고, 클라이언트에서는사용할수없다. tpsendtocli() 은어떤요청에대한응답을전송하는 tpreturn() 과는달리서버가클라이언트에게일방적으로메시지를전송하는데사용한다. clid 는 tpgetcliid() 라는 API 를써서얻어낼수있고, 일방적인메시지를전달할대상을구별하는값이다. data 는보낼 Buffer 의포인터이고 len 은 Buffer 의길이이다. <Ex>... int clid, ret;... clid = tpgetclid(); if (clid < 0) { 82
error processing routine... ret = tpsendtocli(clid, unsolmsg, strlen(unsolmsg), 0); if (ret < 0) { error processing routine 83
6.3 서버프로그램 개발자가서버프로그램을모두작성하였다면이제컴파일을할차례이다. 서버프로그램컴파일은유닉스프로그램과동일하지만미리준비되어야하는것들이있다. 서버프로그램을컴파일하는데필요한파일들은개발자가작성한서버프로그램, Tmax 서버라이브러리, 서비스테이블이다. 그리고구조체를사용한경우는구조체파일 ( 구조체파일명 _sdl.c, 구조체파일명.h) 이있어야하고 FIELD buffer 를사용한경우 FIELD 파일 (FIELD 파일명.h) 가있어야한다. 6.3.1 서버프로그램구성 6.3.1.1 서버프로그램 개발자가작성한서비스루틴이다. 클라이언트의요청을처리한다. 6.3.1.2 구조체파일 구조체파일을사용한다면 sdlc 명령어로컴파일된표준통신타입 ( 구조체파일명 _sdl.c) 과구조체헤더파일 ( 구조체파일명 _sdl.h) 를응용서버와함께컴파일한다. 구조체를사용하지않을경우에는 $TMAXDIR/lib/sdl.o 를넣어서컴파일한다. 6.3.1.3 FIELD 파일 FIELD 파일을사용한다면 fdlc 명령어로컴파일된 FIELD 헤더파일 (FIELD 파일명 _fdl.h) 를서버프로그램과함께컴파일한다. 6.3.1.4 Tmax 서버라이브러리 Tmax 에서제공하는서버라이브러리로, 서버 main() 과 tpsvrinit(), tpsvrdone() 그리고각종 Tmax 함수들이있다, 84
6.3.1.5 서비스테이블 서비스테이블은서버마다제공되는서비스이름들이나열되어있는파일로써 Tmax 환경파일을참조하여만든다. 서비스테이블은서비스수행시실제적으로서버내에서해당서비스루틴의위치를찾기위해사용된다. 서비스테이블은시스템관리자가제공한다. 이에대한자세한내용은 Tmax Administration Guide 를참조하라. 서비스테이블작성방법을간단하게알아보면다음과같다 : 이는이진화된 Tmax 환경파일 (ex: tmconfig) 을참조하여 gst(generate service table) 명령어를사용한다. gst [-f binary configuration file] gst 를수행하면 Tmax 디렉토리하위의 svct 디렉토리에 Tmax 환경파일의 *SERVER 절에등록된서버별로 서버이름 _ svctab.c 라는서비스테이블이생성된다. 이는 *SERVICE 절을참조하여서버별로제공하는서비스들이등록되어있다. 이진화된 Tmax 환경파일 (tmconfig) 은시스템관리자가작성한시스템전체구성에대한텍스트파일 (sample.m) 을 cfl 명령어로컴파일후생성된다.(Tmax Reference Guide 참조 ) $cfl [-i Tmax 환경파일 ] 6.3.2 서버프로그램컴파일 1. 응용서버프로그램을컴파일하여오브젝트파일 (.o 형식 ) 을생성한다. 서버프로그램은 Tmax 에서제공하는라이브러리헤더파일들을포함하며, 만약구조체를사용한서비스를한다면구조체파일 (ex:demo.s) 도함께포함해야한다. Ex ) cc -c -I/home/tmax/usrinc aptest.c -> aptest.o 2. 구조체통신인경우구조체파일을컴파일한다. 이는 sdlc 로컴파일하여암호화 / 복호화프로그램을생성하는단계와생성한프로그램을다시오브젝트파일로변환하는 2 단계로이루어진다. Ex ) Step 1 : sdlc -i demo.s -> demo_sdl.c Step 2 : cc -c -I/home/tmax/usrinc demo_sdl.c -> demo_sdl.o 85
구조체파일을사용하지않는다면 $TMAXDIR/lib/sdl.o 를사용한다. 3. 시스템관리자가제공해준서비스테이블을컴파일하여오브젝트파일형태를생성한다. Ex ) cc -c aptest_svctab.c -> aptest_svctab.o 4. 1,2,3 에서만들어진오브젝트파일들과 Tmax 시스템에서제공하는서버라이브러리를함께링크하여서버실행프로그램을생성한다. Ex ) cc -o aptest aptest.o demo_sdl.o aptest_svctab.o libsvr.a libnodb.a -> aptest 다음은서버프로그램컴파일과정이다 : 그림 2-6. 서버프로그램컴파일 (sdl) 86
그림 2-7. 서버프로그램컴파일 (fdl) 6.3.2.1 서버프로그램 makefile 다음은 Tmax 서버프로그램을위한샘플 makefile 이다. # for user program TARGET = <servername> APOBJS = $(TARGET).o SDLFILE = demo.s SDLOBJ = ${SDLFILE:.s=_sdl.o SDLC = ${SDLFILE:.s=_sdl.c #TMAXLIBS 는 OS 별로다르다. #Solaris : TMAXLIBS = -lsocket -lnsl lsvr -nodb #Compac, HP, IBM, Linux : TMAXLIBS= -lsvr -nodb 87
TMAXLIBS = -lsvr nodb #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) OBJS = $(SDLOBJ) $(APOBJS) $(SVCTOBJ) SVCTDIR = $(TMAXDIR)/svct SVCTOBJ = $(TARGET)_svctab.o #.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 88
$(SDLOBJ): $(TMAXDIR)/bin/sdlc -i../sdl/$(sdlfile) $(CC) $(CFLAGS) -c../sdl/$(sdlc) # clean: -rm -f *.o core $(TARGET) 89
6.3.3 서버프로세스생성및종료 서버프로세스생성은시스템관리자가해야할역할로써 Tmax Reference Guide 를참조하기바란다. Tmax 어플리케이션서버는단독으로유닉스실행파일처럼실행되지않는다. 이것은서버프로세스가생성되면서 Tmax 관련환경을참조하기때문이다. 따라서 tmboot 명령어로서버프로세스를생성하고, tmboot 명령어로종료시킨다. Tmax 어플리케이션서버프로세스를생성시키기전에, 시스템관리자가작성한 Tmax 환경파일 (ex: sample.m) 이컴파일 (cfl 명령어이용 ) 되어있어야한다. 컴파일된이진환경파일 (ex: tmconfig) 을참조하여서버프로세스를생성하게된다. $tmboot [-f 이진화된구성파일 ] Tmax 시스템프로세스와이진화된 Tmax 구성파일에등록된모든서버프로세스를생성한다. $tmboot [-s 서버프로그램이름 ] 특정서버프로세스만을생성시킨다. Tmax 시스템및서버프로세스종료는 tmdown 명령어를이용한다. $tmdown [-f 이진화된구성파일 ] Tmax 시스템프로세스와이진화된 Tmax 구성파일에등록된모든서버프로세스를종료시킨다. $tmdown [-s 서버프로그램 ] 특정서버프로세스만을종료시킨다. 90
7 대화형통신 7.1 대화형통신함수개요 대화형통신은클라이언트와서버사이의반이중통신이다. 클라이언트가데이터를보내면, 서버에서는데이터를받고, 다시서버에서데이터를보내고이를클라이언트가받는송 / 수신기능을바꾸어가면서통신하는방법이다. 대화형통신의시작은요청자가 tpconnect() 를호출함으로써시작된다. 이함수는선택적으로서비스에데이터를보내고, 어느프로그램이연결컨트롤을가질지를지정한다. 즉 tpconnect() 는연결설정이된후에어느쪽이데이터를보낼수있고, 어느쪽이데이터를받아야하는지를설정해야만한다. tpconnect() 가성공적으로수행되면연결구별자 (connection descriptor) 를반환하는데, 이것으로메시지를보내고 (tpsend()) 받는 (tprecv()) 것을다른연결들과구별한다. 대화형통신은문맥 (context) 을저장해야할경우에사용하면좋다. 하지만연결설정 (tpconnect()) 에서연결해제 (tpdiscon() 또는 tpreturn()) 까지다른통신과비교하여상대적으로장시간연결이유지되어야한다. 장시간연결유지는네트웍의부하를증가시키므로가능하면동기 / 비동기통신을이용할것을권한다. 로써연결이정상적으로끝난다. 만약강제적으로끝내려면 tpdiscon() 를사용한다. 이함수를호출하면통과중에있는데이터는잃을수도있으며, 진행중인트랜잭션은취소된다. 컨트롤을상대방에넘길때는 tpconnect() 또는 tpsend() 에서 flags 를 TPRECVONLY 로설정하여호출한다. 그러면상대방에서 TPEV_SENDONLY 라는이벤트가발생하여컨트롤이넘어왔음을알게된다. 이후부터 tpsend() 호출해서데이터를보낼수있게된다. 물론상대방은데이터를받을수만있다. 91
대화형모드에서사용하는 Buffer 도동기 / 비동기통신처럼 buffer 를써야하며, 미리 tpalloc() 으로할당하여야한다. Tmax 통신에서사용하는모든 Buffer 는 tpalloc() 으로할당되어야한다. 7.2 대화형통신함수 7.2.1 int tpconnect(char *svc, char *sbuf, long slen, long flags) 대화형모드로연결함. svc : 연결할대화형서비스의이름 sbuf : 보내질 Buffer 에대한포인터 (NULL 인경우가많다.) slen : 보내질 Buffer 의길이 flags : 연결시선택옵션 TPNOTRAN : 트랜잭션모드에서의호출이아님 TPNOTIME : Blocking time-out 을무시함 TPSIGSTRT : 시그널캐취를허가함 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 TPSENDONLY : 클라이언트에서데이터를보내기만함 TPRECVONLY : 클라이언트에서데이터를받기만함 tpconnect() 는연결을설정하고통신을시작하는함수이다. 여기서요청자는서비스를요청하기위해 Buffer 를서비스루틴에보낼수도있다. tpconnect() 는일반적으로연결설정만하고서비스는요청하지않는다. 서비스를요청한다면 Buffer 를보내기전에미리 tpalloc() 으로할당하여야한다. svc 는 Tmax 대화형응용서비스이름이다. svc 설정시대화형응용서비스이름이아니거나없으면실패로 1 를반환하고 tperrno 에 TPENOENT 가지정된다. 대화형모드서버는 Tmax 환경파일에등록되어 92
있으므로미리확인을하는것도좋은방법이다.(Tmax Administration Guide 참조 ) sbuf 는 tpalloc() 으로할당되어진 Buffer 이다. slen 은 Buffer 의길이이다. sbuf 가길이지정을요구하지않는 Buffer 유형 ( 예를들어 STRUCT 타입 Buffer) 이라면 slen 은무시될수있다. 즉 0 으로지정가능하다. 또한 slen 은서비스루틴에보낼데이터가없다면 NULL 로설정할수있고이때 slen 은무시된다. Buffer 와 Buffer 의크기에관련된더자세한내용은동기 / 비동기통신을참조하라. Buffer 의유형과하위유형은서비스루틴에서사용하는것과일치해야한다. 대화형서비스는 tpconnect() 에서보낸 data 와 len 를 TPSVCINFO 구조체를통해서받기때문에 tprecv() 를호출하지않는다. flags 는 tpcall() 과같이 TPNOTRAN, TPNOBLOCK, TPNOTIME, TPSIGSTRT 를포함한다. 게다가 TPSENDONLY, TPRECVONLY 가추가되어있다. TPSENDONLY tpconnect() 에서이플래그를설정하면, tpconnect() 를호출한프로그램에서연결컨트롤을계속가지며연결을요청받은상대방프로그램은받기만할수있다. 요청받는프로그램에서는 TPSVCINFO 구조체에 flags 의값이 TPRECVONLY 로설정되어컨트롤이넘어오지않았음을알게된다. TPRECVONLY 이플래그는연결컨트롤을상대방 ( 요청받는서비스 ) 에게넘긴다. 이제상대방은 tpsend() 로메시지를보낼수있다. 요청받는서비스가컨트롤이넘어왔음을알게되는것은 93
main() 에서서비스루틴을호출할때넘어오는구조체 TPSVCINFO 에 TPSENDONLY 로지정되어오기때문이다 플래그로 TPSENDONLY 와 TPRECVONLY 둘중하나는반드시지정되어야한다. CONV=Y 는서버프로그램의 Tmax 환경파일에설명되어야한다. 그렇지않으면 Segmentation Fault 가일어날수도있다. <Ex 1>... if ((cd = tpconnect( ACCOUNT, NULL, 0, TPSENDONLY)) == -1) { error processing routine; <Ex 2>... if ((cd = tpconnect( ACCOUNT, sndbuf, 0, TPRECVONLY)) == -1) { error processing routine; 7.2.2 int tpsend(int cd, char *sbuf, long slen, long flags, long *revent) 메시지보냄. cd : tpconnect() 함수를통해얻은연결핸들 sbuf : 보내질데이터 Buffer slen : 보낼데이터 Buffer 의길이 flags : 송신시선택될옵션 TPNOTIME : Blocking time-out 을무시함 TPSIGSTRT : 시그널캐취를허가함 94
TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 TPRECVONLY : 데이터를보낸후에데이터를받는모드로변경 revent : 이벤트가발생한경우, 이벤트유형이설정됨 TPEV_DISCONIMM : 대화시작자가 tpdiscon() 을사용하여연결을강제로종료하였다는것을의미함 TREV_SVCERR : TPEV_SVCFAIL 상황이외의경우에, 대화종속자가통신제어권없이 tpreturn() 을수행하였음을알림 TREV_SVCFAIL : 서비스가실패하였음을알림 tpsend() 는연결컨트롤을가진곳에서메시지를보낼때사용한다. 상대방은 tprecv() 으로메시지를받을수만있다. tpconnect() 의플래그값을 TPSENDONLY 또는 TPRECVONLY 로지정함으로써연결컨트롤의향방을가릴수있었다. tpsend() 에서는 TPRECVONLY 만을가지고컨트롤의향방을가린다. cd 는 tpconnect() 에서반환된연결구별자이다. sbuf 와 slen 는미리 tpalloc() 으로할당된값이다. revent 는이벤트가발생할경우이벤트유형이설정된다. flags 는 TPNOBLOCK, TPNOTIME, TPSIGRSTRT, TPRECVONLY 를포함한다. TPRECVONLY 이플래그는요청프로그램에서더이상 tpsend() 를호출하지않고, 상대방에게연결컨트롤을넘기겠다는것이다. 이때요청받는프로그램에서는 revent 로지시된주소에서 TPEV_SENDONLY 이벤트를받는다 <Ex>... 95
/* 연결컨트롤을상대방에게로넘김. */ if (tpsend(cd, line, 0, TPRECVONLY, &revent) == -1) { error processing routine 7.2.3 int tprecv(int cd, char **rbuf, long *rlen, long flags, long *revent) 메시지를받음. cd : 연결핸들 rbuf : 수신한 Buffer 에대한포인터 rlen : 데이터의길이에대한포인터 flags : 송신시선택될옵션 TPNOTIME : Blocking time-out 을무시함 TPSIGSTRT : 시그널캐취를허가함 TPNOCHANGE : 받는버퍼의타입이자동으로변경되지않음 TPNOBLOCK : 서비스나서버의실패에대한응답을받지않음 revent : 이벤트가발생한경우, 이벤트유형이설정됨 TPEV_DISCONIMM : 대화시작자가 tpdiscon() 을사용하여연결을강제로종료하였다는것을의미함 TREV_SVCERR : TPEV_SVCFAIL 상황이외의경우에, 대화종속자가통신제어권없이 tpreturn() 을수행하였음을알림 TREV_SVCFAIL : 서비스가실패하였음을알림 TPEV_SENDONLY : 연결된상대방프로그램쪽에서통신제어권을넘겼음을알림 TPEV_SVCSUCC : 대화시작자에게수신되는이이벤트는상대편인대화종속자서비스가성공적으로종료하였음을알림. 96
tprecv ( ) 는연결이설정된후연결컨트롤을가지지않은쪽에서데이터를받고자할때사용한다. cd 는 tpconnect() 에서반환된연결구별자이다. rbuf 는 tpalloc() 으로미리할당되어야하고 rlen 은 data Buffer 의길이이다. rlen 이처음할당된것보다응답시길이가크다면자동적으로커진다. revent 는어떤이벤트가존재하고에러를만나지않는다면이벤트유형이설정된다. 받을수있는이벤트유형은다음에나오는대화형모드에서의이벤트를참조하기바란다. flags 는 TPNOCHANGE, TPNOTIME, TPSIGRSTRT, TPNOBLOCK 를포함한다. TPNOBLOCK 이플래그는데이터의도착을기다리지않겠다는것이다. tprecv() 호출시데이터가도착해있으면데이터를가지고반환되고, 데이터가없다면실패와함께 tperrno 에 TPEBLOCK 를설정한다. 이플래그가설정되지않았다면, tprecv() 는데이터가도착하거나타임아웃될때까지기다린다 <Ex>... if (tprecv(msg->cd, &rcvbuf, &rlen, TPNOFLAGS, &revent)==-1) { /* 제어권이넘어온경우는정상 */ if (revent!= TPEV_SENDONLY) { tpreturn(tpfail, 0, rcvbuf, 0, 0); 97
7.3 대화형모드의연결끊기 일반적으로대화형통신에서연결을끊기위해서는연결컨트롤을서버가가질때 tpreturn() 을부르는것이다. 서버가 tpreturn () 을호출하면, 상대방 ( 클라이언트 ) 이 tprecv() 를호출할때 TPEV_SVCSUCC 또는 TPEV_SVCFAIL 이벤트가발생하여연결이끊김을알게된다. tpdiscon() 는통신을즉시끊고자하는경우에사용한다. 다음은간단한대화형통신의연결컨트롤을넘기는것과연결을끊는것에대한도표이다 : 그림 2-8. 대화형통신 7.3.1 int tpdiscon(int cd) 연결을끊음. cd : 연결핸들 tpdiscon() 은극히예외적인경우에사용하는대화형통신의연결끊기이다. tpdiscon() 은상대방에서 TPEV_DISCONIMM 이벤트를발생시키고 cd 를더이상유효하지않게한다. 만약트랜잭션이진행중이었다면그것은취소되고, 데이터는상실될수있다. 그러므로대화형모드에서연결을끊는적당한방법으로서버쪽에서 tpreturn() 를호출하는것을권장한다. 98
<Ex> if ((cd = tpconnect( ACCOUNT, NULL, 0, TPSENDONLY)) == -1) { error... if (error){ tpdiscon(cd); /* 예외적인경우발생 */ 99
7.4 대화형통신과관계있는이벤트 대화형통신에서는 5 가지의이벤트가존재한다. 아래의표는 5 개의이벤트가발생되는함수와의미를나타내고있다. Event 받는함수 의 미 TPEV_SENDONLY (0x0020) tprecv() 연결컨트롤이존재하는장소를알려줌. TPEV_DISCONIMN (0x0001) tesend() tprecv() tpreturn() 연결이비규칙적으로끊어졌을때받음. tpdiscon() 이호출되거나하위서비스들이여전히열린채남아있는데 tpreturn() 를호출할때발생한다. TPEV_SVCERR (0x0002) tpsend() tprecv() 연결의컨트롤을가지지않았는데 tpreturn() 를호출할때발생. tpreturn() 의인자는정당하지만어떤에러가생겼을때발생. TPEV_SVCFAIL (0x0004) tpsend() tprecv() 연결의컨트롤을가지지않은상태에서 tpreturn() 를호출하거나 tpreturn() 에서 TPFAIL, TPEXIT 로셋팅하여호출할때발생. TPEV_SVCSUCC (0x0008) tprecv() 성공적으로서비스를마침. TPSUCCES 로셋팅되어 tpreturn() 이호출됨. 표 2-3. 대화형통신시의이벤트 100
8 트랜잭션관리 이장에서는트랜잭션의개념과정의및처리방법를설명하려고한다. 트랜잭션처리와관련된표준으로 X/Open DTP 모델의 TX 규격을 따른다. 트랜잭션은자원을하나의일관된상태에서다른일관된상태로변화시키는일의단위로 ACID(Atomicity, Consistence, Isolation, Durability) 속성을지키며작업을처리한다는것이다. Atomicity 는일이완전히수행되거나전혀수행되지않는 (all or nothing) 지의두가지경우만존재해야하는것을말한다. Consistency 트랜잭션의성공적인수행결과를하나의일관된상태에서다른일관된상태의공유자원에갱신하는것을말한다. Isolation 은공유자원을바꿀때트랜잭션의결과가 commit 이될때까지트랜잭션외부로나타나지않는다는것을말한다. Durability 는하위시스템이나 media 오류를거친트랜잭션 commitment 의결과를바꾼다는것을말한다. 둘이상의동종및이종의데이터베이스가관련된전역트랜잭션에서는트랜잭션의속성을보장하기위해 2PC(Two-Phase Commit) 를사용한다. 2PC 란둘이상의데이터베이스가연동할때 ACID 속성을완전히보장하기위해 2 단계처리 (Prepare 단계, Commit 단계 ) 를하는것을말한다. 먼저 Prepare 단계는트랜잭션에관련된모든데이터베이스에트랜잭션을처리할준비가되었는지확인한다. 그래서모든데이터베이스로부터준비되었다는신호를받으면, Commit 단계에서모든데이터베이스로부터정상신호를받았으면 Commit 를, 하나라도비정상신호를받았다면 Rollback 를처리하여전역트랜잭션를완료한다. 트랜잭션범위는 tx_begin() 을호출해서 tx_commit() 또는 tx_rollback() 이호출이되는곳까지이다. 101
tx_begin() 은트랜잭션을시작하게하며, 이함수를부른프로세스는트랜잭션시작자가된다. 트랜잭션시작자는 tx_commit() 또는 tx_rollback() 를호출함으로써트랜잭션을완결하여야할의무를지닌다. tx_begin() 으로시작하여 tx_commit() 또는 tx_rollback() 으로완결되는하나의트랜잭션에포함되는프로세스들을트랜잭션참여자 (participant) 라부르며, 트랜잭션참여자들은 tpreturn() 으로반환하는값에의해서트랜잭션의결과에영향을줄수있다. 트랜잭션상태에서 tx_begin() 으로또다시트랜잭션을시작하려고할경우이는실패되며, tperrno 에 TPEPROTO 가설정된다. 하지만원래트랜잭션은계속수행되어야한다. 트랜잭션상태에있는클라이언트에서 tpcall() 이나 tpacall() 호출시 flags 인자를 TPNOTRAN 으로설정하여서버가트랜잭션참여에서제외되게할수있다. 다시말해, TPNOTRAN 플래그로요청받는서버는현재진행중인트랜잭션의결과에영향을줄수없다는것이다. 트랜잭션을선언하는방법은개발자가명시적으로트랜잭션관련함수 (ex: tx_begin and tx_commit 등 ) 를직접작성하는 explicit 트랜잭션방법과서버에서 Tmax 환경파일의 SVRGROUP 절에서데이터베이스관련항목을설정하여서비스를내재적으로트랜잭션으로처리하는 implicit 트랜잭션방법이있다. 8.1 전역트랜잭션처리 (Global Transaction Processing) 전역트랜잭션이란하나이상의자원관리자 ( 데이터베이스 ) 와하나이상의물리적인사이트가하나의논리적인단위로참여하는트랜잭션이다. Tmax 시스템에서는모든트랜잭션을일단전역트랜잭션으로간주하며, 데이터의무결성을위해 2PC( Two-Phase Commit) 를사용한다. 102
8.2 트랜잭션흐름 여기서는클라이언트에서명시적으로 (explicitly) 전역트랜잭션을시작하고완료하는흐름을보여주고있다. tpcall() 호출시 TPNOTRAN 으로 flag 를설정하지않으면요청받는서버의서비스루틴은트랜잭션의일부가된다. 그림 2-9. 전역트랜잭션흐름도 8.3 트랜잭션관련함수 8.3.1 int tx_begin() 전역트랜잭션을시작함. tx_begin() 은전역트랜잭션을시작하기위해사용하고, 트랜잭션에참여하는데이터베이스는미리열려있어야한다. 전역트랜잭션수행에들어간프로세스는 tx_commit() 이나 tx_rollback() 으로트랜잭션수행을완료해야한다. 103