Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

352
Tmax Application Development Guide Tmax v5.0 SP1 Copyright © 2009 TmaxSoft Co., Ltd. All Rights Reserved.

Transcript of Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

Page 1: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

Tmax

Application Development

Guide

Tmax v5.0 SP1

Copyright © 2009 TmaxSoft Co., Ltd. All Rights Reserved.

Page 2: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

Copyright Notice

Copyright © 2009 TmaxSoft Co., Ltd. All Rights Reserved.

대한민국 경기도 성남시 분당구 서현동 263 분당스퀘어(AK프라자) 12층

Restricted Rights Legend

All TmaxSoft Software (Tmax®) and documents are protected by copyright laws and the Protection Act of Com

puter Programs, and international convention. TmaxSoft software and documents are made available under the

terms of the TmaxSoft License Agreement and may only be used or copied in accordance with the terms of this

agreement. No part of this document may be transmitted, copied, deployed, or reproduced in any form or by any

means, electronic, mechanical, or optical, without the prior written consent of TmaxSoft Co., Ltd.

이 소프트웨어(Tmax®) 사용설명서의 내용과 프로그램은 저작권법, 컴퓨터프로그램보호법 및 국제 조약에 의해

서 보호받고 있습니다. 사용설명서의 내용과 여기에 설명된 프로그램은 TmaxSoft Co., Ltd.와의 사용권 계약 하에

서만 사용이 가능하며, 사용권 계약을 준수하는 경우에만 사용 또는 복제할 수 있습니다. 이 사용설명서의 전부 또

는 일부분을 TmaxSoft의 사전 서면 동의 없이 전자, 기계, 녹음 등의 수단을 사용하여 전송, 복제, 배포, 2차적 저

작물작성 등의 행위를 하여서는 안 됩니다.

Trademarks

Tmax®, Tmax WebtoB® and JEUS® are registered trademark of TmaxSoft Co., Ltd. Other products, titles or

services may be registered trademarks of their respective companies.

Tmax®, Tmax WebtoB® 와 JEUS®는 TmaxSoft Co., Ltd.의 등록 상표입니다. 기타 모든 제품들과 회사 이름은 각

각 해당 소유주의 상표로서 참조용으로만 사용됩니다.

Open Source Software Notice

This product includes various open source software that has been developed and/or licensed by “OpenSSL”, “RSA

Data Security, Inc.”, “Apache Foundation”, or “Jean-loup Gailly and Mark Adler.” TmaxSoft fully respects the

aforementioned parties and the open source software used in this product. More details can be found within the

directory “${INSTALL_PATH}/license/oss_licenses”

본 제품은 “OpenSSL”, “RSA Data Security, Inc.”, “Apache Foundation” 및 “Jean-loup Gailly와 Mark Adler”에 의

해 개발 또는 라이선스된 오픈 소스 소프트웨어를 포함합니다. 오픈 소스 소프트웨어와 개발자에 대해 경의를 표

합니다. 관련 상세 정보는 제품의 디렉터리 “${INSTALL_PATH}/license/oss_licenses”에 기재된 사항을 참고해 주

십시오.

안내서 정보

안내서 제목: Tmax Application Development Guide

발행일: 2009-08-10

소프트웨어 버전: Tmax v5.0 SP1

안내서 버전: v2.1.1

Page 3: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

내용 목차

안내서에 대하여 ........................................................................................................................... xi

제1장 Tmax 애플리케이션 소개 ................................................................................................... 1

1.1. 개요 ............................................................................................................................ 1

1.2. 구성 ............................................................................................................................ 1

1.3. 특징 ............................................................................................................................ 2

제2장 클라이언트 프로그램 ......................................................................................................... 5

2.1. 프로그램 흐름 .............................................................................................................. 5

2.2. 프로그램 특징 .............................................................................................................. 8

2.3. 개발 환경 ..................................................................................................................... 8

2.4. 프로그램 구성 .............................................................................................................. 9

2.5. 프로그램 컴파일 ........................................................................................................... 9

2.6. 프로세스 기동 및 종료 ................................................................................................ 12

제3장 서버 프로그램 ................................................................................................................. 17

3.1. 서버 프로세스 ............................................................................................................ 17

3.1.1. TCS ................................................................................................................ 18

3.1.2. UCS ............................................................................................................... 18

3.1.3. RDP ............................................................................................................... 21

3.2. 프로그램 흐름 ............................................................................................................ 22

3.2.1. TCS ................................................................................................................ 23

3.2.2. UCS ............................................................................................................... 24

3.3. 프로그램 특징 ............................................................................................................ 24

3.4. 개발 환경 ................................................................................................................... 25

3.5. 프로그램 구성 ............................................................................................................ 25

3.5.1. TCS ................................................................................................................ 25

3.5.2. UCS ............................................................................................................... 26

3.6. 프로그램 컴파일 ......................................................................................................... 28

3.6.1. TCS ................................................................................................................ 28

3.6.2. UCS ............................................................................................................... 32

3.7. 프로세스 생성 및 종료 ................................................................................................ 33

제4장 통신 유형 ........................................................................................................................ 35

4.1. 동기형 통신 ................................................................................................................ 36

4.2. 비동기형 통신 ............................................................................................................ 37

4.3. 대화형 통신 ................................................................................................................ 38

4.3.1. 대화형 통신과 관계 있는 이벤트 ....................................................................... 40

제5장 버퍼 유형 ........................................................................................................................ 41

5.1. 버퍼의 종류 ................................................................................................................ 41

5.2. 버퍼 관리 ................................................................................................................... 42

5.2.1. 구조체 버퍼 ..................................................................................................... 43

5.2.2. 필드 버퍼 ........................................................................................................ 43

Tmax iii

Page 4: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제6장 트랜잭션 ......................................................................................................................... 45

6.1. 특징 ........................................................................................................................... 45

6.2. 분산 트랜잭션 ............................................................................................................ 46

6.2.1. XA 모드 .......................................................................................................... 48

6.2.2. Non-XA 모드 ................................................................................................... 50

6.3. 트랜잭션 관련 에러 ..................................................................................................... 51

6.3.1. TX 에러 ........................................................................................................... 51

6.3.2. XA 에러 .......................................................................................................... 52

제7장 Multithread/Multicontext ................................................................................................ 53

7.1. 프로그램 흐름 ............................................................................................................ 53

7.1.1. Multithread ...................................................................................................... 53

7.1.2. Multicontext ..................................................................................................... 54

7.2. 프로그램 구현 ............................................................................................................ 54

7.2.1. 시작 구문 ........................................................................................................ 54

7.2.2. 구현 구문 ........................................................................................................ 55

7.2.3. 종료 구문 ........................................................................................................ 56

7.3. 프로그램 예제 ............................................................................................................ 56

제8장 보안 시스템 ..................................................................................................................... 65

8.1. 1단계 보안 ................................................................................................................. 65

8.2. 2단계 보안 ................................................................................................................. 66

8.3. 3단계 보안 ................................................................................................................. 68

제9장 클라이언트 API ............................................................................................................... 71

9.1. 연결 및 해제 ............................................................................................................... 74

9.1.1. tpstart ............................................................................................................. 74

9.1.2. tpend .............................................................................................................. 78

9.2. 동기형 통신 ................................................................................................................ 79

9.2.1. tpcall ............................................................................................................... 79

9.3. 비동기 통신 ................................................................................................................ 84

9.3.1. tpacall ............................................................................................................. 84

9.3.2. tpgetrply .......................................................................................................... 88

9.3.3. tpcancel .......................................................................................................... 91

9.4. 대화형 통신 ................................................................................................................ 93

9.4.1. tpconnect ........................................................................................................ 93

9.4.2. tpsend ............................................................................................................ 97

9.4.3. tprecv ............................................................................................................ 100

9.4.4. tpdiscon ........................................................................................................ 104

9.5. 비요청 메시지 처리 ................................................................................................... 106

9.5.1. tpsetunsol ..................................................................................................... 106

9.5.2. tpgetunsol ..................................................................................................... 108

9.6. 타임아웃 변경 .......................................................................................................... 111

9.6.1. tpset_timeout ................................................................................................. 111

9.7. 버퍼 관리 ................................................................................................................. 112

iv Tmax Application Development Guide

Page 5: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.7.1. tpalloc ........................................................................................................... 113

9.7.2. tprealloc ........................................................................................................ 115

9.7.3. tpfree ............................................................................................................ 116

9.7.4. tptypes .......................................................................................................... 118

9.8. 트랜잭션 관리 .......................................................................................................... 119

9.8.1. tx_begin ........................................................................................................ 119

9.8.2. tx_commit ..................................................................................................... 121

9.8.3. tx_rollback ..................................................................................................... 123

9.8.4. tx_set_transaction_timeout ............................................................................. 125

9.8.5. tx_set_transaction_control .............................................................................. 127

9.8.6. tx_set_commit_return .................................................................................... 129

9.8.7. tx_info ........................................................................................................... 132

9.9. RQ 시스템 ............................................................................................................... 134

9.9.1. tpenq ............................................................................................................ 134

9.9.2. tpdeq ............................................................................................................ 137

9.9.3. tpqstat ........................................................................................................... 140

9.9.4. tpextsvcname ................................................................................................ 142

9.10. 이벤트를 활용하는 API ............................................................................................ 144

9.10.1. tpsubscribe .................................................................................................. 144

9.10.2. tpunsubscribe .............................................................................................. 146

9.10.3. tppost .......................................................................................................... 147

9.11. 브로드 캐스트/멀티 캐스트 ...................................................................................... 148

9.11.1. tpbroadcast ................................................................................................. 148

9.12. 환경 프로그램 ......................................................................................................... 151

9.12.1. WinTmaxAcall ............................................................................................. 152

9.12.2. WinTmaxAcall2 ............................................................................................ 156

9.12.3. WinTmaxStart ............................................................................................. 161

9.12.4. WinTmaxEnd ............................................................................................... 162

9.12.5. WinTmaxSetContext .................................................................................... 162

9.12.6. WinTmaxSend ............................................................................................. 165

9.13. Multithread/Multicontext .......................................................................................... 168

9.13.1. tpgetctxt ...................................................................................................... 168

9.13.2. tpsetctxt ...................................................................................................... 169

제10장 서버 API ..................................................................................................................... 173

10.1. TCS ....................................................................................................................... 173

10.1.1. tpreturn ....................................................................................................... 176

10.1.2. tpforward ..................................................................................................... 180

10.1.3. tpsvrinit ....................................................................................................... 183

10.1.4. tpsvrdone .................................................................................................... 184

10.1.5. tpsendtocli ................................................................................................... 186

10.1.6. tpgetclid ...................................................................................................... 188

10.1.7. tpchkclid ...................................................................................................... 189

Tmax v

Page 6: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

10.2. UCS ...................................................................................................................... 190

10.2.1. tpschedule ................................................................................................... 192

10.2.2. tpuschedule ................................................................................................. 194

10.2.3. tpsetfd ......................................................................................................... 195

10.2.4. tpissetfd ...................................................................................................... 198

10.2.5. tpclrfd .......................................................................................................... 200

10.2.6. tpsavectx ..................................................................................................... 203

10.2.7. tpgetctx ....................................................................................................... 205

10.2.8. tpcancelctx .................................................................................................. 206

10.2.9. tprelay ......................................................................................................... 206

10.2.10. tpregcb ...................................................................................................... 209

10.2.11. tpunregcb .................................................................................................. 210

제11장 예제 ............................................................................................................................ 213

11.1. 통신 유형 예제 ........................................................................................................ 213

11.1.1. 동기형 통신 ................................................................................................. 213

11.1.2. 비동기형 통신 .............................................................................................. 216

11.1.3. 대화형 통신 ................................................................................................. 220

11.2. 전역 트랜잭션 프로그램 예제 ................................................................................... 225

11.3. 데이터베이스 적용 프로그램 .................................................................................... 233

11.3.1. Oracle Insert 프로그램 ................................................................................. 233

11.3.2. Oracle Select 프로그램 ................................................................................ 238

11.3.3. Informix Insert 프로그램 ............................................................................... 245

11.3.4. Informix Select 프로그램 .............................................................................. 253

11.4. 데이터베이스 연동 프로그램 .................................................................................... 261

11.4.1. 동기형 모드(동일 기종) ................................................................................. 261

11.4.2. 동기형 모드(이기종) ..................................................................................... 268

11.4.3. 비동기형 모드(동일 기종) ............................................................................. 271

11.4.4. 대화형 모드(동일 기종) ................................................................................. 277

11.5. TIP를 이용한 프로그램 ............................................................................................ 285

11.5.1. TIP 구조 ...................................................................................................... 285

11.5.2. TIP 사용 ...................................................................................................... 286

11.5.3. TIP 사용 예제 .............................................................................................. 289

11.5.4. 시스템 환경 정보 조회 프로그램 .................................................................... 299

11.5.5. 시스템 통계 정보 조회 프로그램 .................................................................... 302

11.5.6. 서버 프로세스 기동 및 종료 프로그램 ............................................................ 305

11.6. Local recursive call ................................................................................................. 314

제12장 에러 처리 .................................................................................................................... 317

12.1. API 레벨 에러 처리 ................................................................................................. 317

12.1.1. tpstrerror ..................................................................................................... 317

12.2. 시스템 레벨 에러 처리 ............................................................................................. 323

12.2.1. Uunixerr ...................................................................................................... 323

12.2.2. Uunix_err .................................................................................................... 323

vi Tmax Application Development Guide

Page 7: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

12.2.3. Ustrerror ...................................................................................................... 323

12.3. 디버그 .................................................................................................................... 324

12.3.1. 디버그 CLH ................................................................................................. 324

12.3.2. 디버그 라이브러리 ....................................................................................... 325

Appendix A. Tmax 환경 설정 .................................................................................................. 327

A.1. 환경파일 .................................................................................................................. 327

A.2. Makefile ................................................................................................................... 331

색인 .......................................................................................................................................... 333

Tmax vii

Page 8: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 9: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

그림 목차

[그림 1.1] Tmax 애플리케이션 프로그램 ....................................................................................... 2

[그림 2.1] 클라이언트 프로그램 흐름 ............................................................................................ 6

[그림 2.2] 클라이언트 프로그램 함수 프로세스 .............................................................................. 8

[그림 2.3] 클라이언트 프로그램 컴파일 과정(구조체 버퍼 사용) .................................................... 10

[그림 2.4] 클라이언트 프로그램 컴파일 과정(필드 버퍼 사용) ....................................................... 11

[그림 3.1] 프로세스 유형 ............................................................................................................ 17

[그림 3.2] 서버 프로그램 흐름 .................................................................................................... 22

[그림 3.3] TCS방식 서버 프로그램 흐름 ...................................................................................... 23

[그림 3.4] UCS방식 서버 프로그램 흐름 ...................................................................................... 24

[그림 3.5] 서버 프로그램 컴파일(sdl) .......................................................................................... 29

[그림 3.6] 서버 프로그램 컴파일(fdl) ........................................................................................... 29

[그림 4.1] 동기형 통신 ............................................................................................................... 36

[그림 4.2] 동기형 통신 모델 ........................................................................................................ 36

[그림 4.3] 비동기형 통신 ............................................................................................................ 37

[그림 4.4] 비동기형 통신 모델 .................................................................................................... 37

[그림 4.5] 대화형 통신 ............................................................................................................... 38

[그림 4.6] 대화형 통신 모델 ........................................................................................................ 39

[그림 5.1] Tmax 통신 버퍼 유형 .................................................................................................. 42

[그림 5.2] 구조체 버퍼를 이용한 애플리케이션 프로그램 컴파일 ................................................... 43

[그림 5.3] 필드 버퍼를 이용한 애플리케이션 프로그램 컴파일 ...................................................... 44

[그림 6.1] Two-phase commit (2PC) protocol ............................................................................... 46

[그림 6.2] X/Open DTP의 구조 ................................................................................................... 47

[그림 6.3] 분산 트랜잭션의 처리과정 .......................................................................................... 47

[그림 6.4] XA 모드 ..................................................................................................................... 49

[그림 6.5] Non-XA 모드 ............................................................................................................. 50

[그림 7.1] Tmax 클라이언트 Multithread 애플리케이션 ................................................................ 53

[그림 7.2] Tmax 클라이언트 Multicontext 애플리케이션 ............................................................... 54

[그림 10.1] tpforward ............................................................................................................... 181

[그림 10.2] UCS 방식 서비스 포워딩 ......................................................................................... 191

[그림 11.1] 2개의 데이터베이스 접속 ........................................................................................ 226

[그림 11.2] 동기형 모드 흐름도(동일 기종 데이터베이스) ........................................................... 261

[그림 11.3] 동기형 모드 흐름도(이기종 데이터베이스 접속) ........................................................ 268

[그림 11.4] 비동기형 모드 흐름도(동일 기종 데이터베이스 접속) ................................................ 271

[그림 11.5] 대화형 모드 흐름도(동일 기종 데이터베이스 접속) ................................................... 277

Tmax ix

Page 10: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 11: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

안내서에 대하여

안내서의 대상

본 안내서는 Tmax®(이하 Tmax)을 사용하여 프로그램을 개발하는 사용자를 위해 기술되었다. Tmax를 이

용해서 애플리이션을 개발하기 위한 기본 개념과 클라이언트/서버 프로그램의 기본 흐름과 API를 사용한

개발방법에 대해서 설명한다. Tmax를 사용해서 구축이 가능한 다양한 개발환경에 대한 설명과 해당 환경

에서 개발을 위한 방법을 제시한다. 프로그램의 이해를 돕기위해 다양한 예제를 수록해서 사용자의 이해

를 돕고자 한다.

안내서의 전제 조건

본 안내서는 Tmax 시스템에 대한 전반적인 이해와 Tmax 시스템이 제공하는 각종 기능 및 특성에 대한 습

득을 위한 기본서이다.

본 안내서를 원활하게 이해하기 위해서는 다음과 같은 사항을 미리 알고 있어야 한다.

● 미들웨어(Middleware) 및 UNIX 시스템에 대한 이해

● Tmax의 기본 개념 이해

● Java , C 프로그래밍의 이해

안내서의 제한 조건

본 안내서를 읽기 전에 Tmax의 기본 개념을 숙지하고 있어야 한다. 실무에서의 구체적인 사용방법이나

관리 및 운용에 관한 사항은 각 제품의 안내서를 참고한다.

참고

Tmax에 대한 기본적인 내용은 "Tmax Administration Guide"나 "Tmax Getting Started Guide"를 참

고한다. Tmax에서 제공하는 명령어와 C API에 대한 설명은 “Tmax Reference Guide”를 참고한다.

안내서에 대하여 xi

Page 12: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

안내서 구성

Tmax Application Development Guide 안내서는 총 12개의 장과 Appendix로 구성되어 있다.

각 장의 주요 내용은 다음과 같다.

● 제1장: Tmax 애플리케이션 소개

Tmax 애플리케이션의 개요와 구성 그리고 특징에 대해 기술한다.

● 제2장: 클라이언트 프로그램

클라이언트 프로그램의 구성, 컴파일, 프로세스에 대해 기술한다.

● 제3장: 서버 프로그램

서버 프로그램의 흐름과 특징, 구성에 대해서 기술한다.

● 제4장: 통신 유형

Tmax에서 제공하는 통신 유형에 대해 기술한다.

● 제5장: 버퍼 유형

Tmax에서 제공하는 버퍼 유형에 대해 기술한다.

● 제6장: 트랜잭션

트랜잭션의 개념과 정의 및 처리 방법에 대해 기술한다.

● 제7장: Multithread / Multicontext

Multithread / Multicontext의 프로그램 흐름과 구현에 대해 기술한다.

● 제8장: 보안 시스템

Tmax에서 제공되는 3단계 보안 시스템에 대해 기술한다.

● 제9장: 클라이언트 API

Tmax 클라이언트 프로그램에서 제공되는 함수에 대해 기술한다.

● 제10장: 서버 API

Tmax 서버 프로그램에서 제공되는 함수에 대해 기술한다.

● 제11장: 예제

Tmax 시스템에서 제공하는 고유의 기능을 사용하기 위한 예제를 기술한다.

xii Tmax Application Development Guide

Page 13: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 제12장: 에러 처리

Tmax의 API의 에러가 발생하는 경우 상황에 따른 에러 처리 방법에 대해 기술한다.

● Appendix A.: Tmax 환경파일

Tmax 환경파일의 구성 요소에 대해 기술한다.

안내서에 대하여 xiii

Page 14: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

안내서 규약

의미표기

프로그램 소스 코드의 파일명<AaBbCc123>

Ctrl과 C를 동시에 누름<Ctrl>+C

GUI의 버튼 또는 메뉴 이름[Button]

강조진하게

다른 관련 안내서 또는 안내서 내의 다른 장 및 절 언급" "(따옴표)

화면 UI에서 입력 항목에 대한 설명'입력항목'

메일계정, 웹 사이트하이퍼링크

메뉴의 진행 순서>

하위 디렉터리 또는 파일 있음+----

하위 디렉터리 또는 파일 없음|----

참고 또는 주의사항참고

그림 이름[그림 1.1]

표 이름[표 1.1]

명령어, 명령어 수행 후 화면에 출력된 결과물, 예제코드AaBbCc123

옵션 인수 값[ ]

선택 인수 값|

xiv Tmax Application Development Guide

Page 15: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

시스템 사용 환경

요구 사항

IBM AIX 5.xPlatform

HP-UX 11.xx

Solaris 7~9 (SunOS 5.7~5.9)

최소 120MB 하드디스크 공간Hardware

256MB 이상 메모리 공간

1GB 이상 하드디스크와 512MB 이상 메모리 공간 권장

Oracle 9i 또는 10gDatabase

안내서에 대하여 xv

Page 16: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

관련 안내서

설명안내서

Tmax를 이용하기 위한 환경설정 파일과 시스템 운영방식에 대해서

기술한 안내서이다.

Tmax

Administration Guide

4GL 언어를 사용해서 Tmax 애플리케이션을 개발하는 사용자를 위

해 기술된 안내서이다.

Tmax

Programming Guide(4GL)

Tmax를 사용하여 프로그램을 개발하는 사용자를 위해 기술된 안내

서로 Tmax 애플리케이션 개발에 사용하는 명령어의 개념 및 사용법

Tmax

Reference Guide과 예제에 대해서 설명한다. 클라이언트와 서버의 연결, 통신에서 사

용하는 함수에 대한 사용 방법과 예제에 대해서 기술한 안내서이다.

xvi Tmax Application Development Guide

Page 17: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

연락처

Korea

TmaxSoft Co., Ltd

263 BundangSquare (AK Plaza) 12th floor, Seohyeon-dong, Bundang-gu,

Seongnam-si, Gyeonggi-do, 463-824

South Korea

Tel: +82-31-8018-1000

Fax: +82-31-8018-1115

Email: [email protected]

Web (Korean): http://www.tmax.co.kr

기술지원: http://technet.tmaxsoft.com

USA

TmaxSoft, Inc.

560 Sylvan Avenue Englewood Cliffs, NJ 07632

U.S.A

Tel: 1-201-567-8266

Fax: 1-201-567-7339

Email: [email protected]

Web (English): http://www.tmaxsoft.com

Japan

TmaxSoft Japan Co., Ltd.

5F Sanko Bldg, 3-12-16 Mita, Minato-Ku, Tokyo, 108-0073

Japan

Tel: +81-3-5765-2550

Fax: +81-3-5765-2567

Email: [email protected]

Web (Japanese): http://www.tmaxsoft.co.jp

안내서에 대하여 xvii

Page 18: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

China

TmaxSoft China Co., Ltd.

Beijing Silver Tower, RM 1508, 2# North Rd Dong San Huan,

Chaoyang District, Beijing, China, 100027

China

Tel: +86-10-6410-6145~8

Fax: +86-10-6410-6144

Email: [email protected]

Web (Chinese): http://www.tmaxsoft.com.cn

ASEAN Office

TmaxSoft Pte. Ltd.

30 Cecil Street, Level 15 Unit 05 Prudential Tower, Singapore 049712

Singapore

Tel: +65-6232-2889

Fax: +65-6232-2919

Email: [email protected]

Web (English): http://asean.tmaxsoft.com

xviii Tmax Application Development Guide

Page 19: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제1장 Tmax 애플리케이션 소개

1.1. 개요Tmax 애플리케이션이란 개방형 환경에서 Tmax를 미들웨어로 사용해서 개발한 클라이언트/서버 프로그

램을 말한다. 고성능 PC의 등장과 프로그램 기법의 발달은 호스트 중심의 중앙 처리 방식에서 클라이언

트와 서버가 작업 처리를 분담하는 환경으로 변화를 가져왔다. 클라이언트/서버 환경은 작업을 분담하므

로 고성능 PC의 활용과 서버의 소형화, 각종 하드웨어 선택폭의 확대 등과 같이 자원의 효율적 활용을 가

능하게 하였다.

하지만 클라이언트/서버 환경은 다음과 같은 문제점이 있다.

● 개발자가 각 하드웨어, 운영체제, 네트워크 프로토콜에 대한 깊은 이해가 있어야만 프로그램이 가능하

다.

● 사용자 수와 데이터 양의 증가에 따라 처리 속도가 현저하게 저하된다.

● 과다한 네트워크 트래픽 발생으로 속도가 저하된다.

● 분산 환경에 따른 관리(프로세스 관리, 통신, 보안, 장애 대책 등)가 어렵다.

Tmax 애플리케이션은 클라이언트/서버 프로그램의 장점을 유지하면서, 위와 같은 단점을 획기적으로 보

완할 수 있다. Tmax를 미들웨어로 하여 애플리케이션을 작성할 경우 Tmax에서 제공하는 함수를 이용하

여 프로그램을 작성하기 때문에 통신 프로그램 및 프로세스 관리, 트랜잭션 관리 등 관리의 어려운 부분을

Tmax가 해결하게 한다. Tmax에서 제공하는 함수는 버퍼 및 통신, 기록 트랜잭션 관련 함수이며, 서버 라

이브러리(libsvr.a)와 클라이언트 라이브러리(libcli.a)로 나누어 제공된다. Tmax에서 제공하는 함수는 분

산처리 국제표준 X/Open DPT 모델을 준수한다.

1.2. 구성Tmax 애플리케이션은 크게 클라이언트 프로그램과 서버 프로그램으로 나누어지고 Tmax를 사용하기 위

한 환경설정 작업이 추가된다.

● 클라이언트 프로그램

클라이언트 프로그램은 서비스를 요청하고, 그 요청에 대한 응답을 서버에서 받아 사용자가 원하는 형

식으로 결과를 전달하는 역할을 하는 프로그램이다. Tmax 시스템에 접속하기 위해서는 Tmax 주소

(Address), 포트 번호 등을 설정한 UNIX 환경파일(예: .profile)이 필요하다. 클라이언트 프로그램은 사

용자 환경파일의 환경변수를 참조하여 Tmax 시스템에 접속하고 구조체 버퍼 혹은 필드 버퍼를 사용할

경우 각각에 해당되는 바이너리 파일을 참조한다.

제1장 Tmax 애플리케이션 소개 1

Page 20: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 서버 프로그램

서버 프로그램은 클라이언트의 요청을 받아서 처리하여 적절한 응답을 만드는 프로그램으로 시스템 자

원에 대한 접근 관리와 클라이언트의 요청을 받아서 처리하고 응답을 클라이언트에게 전달하는 역할을

한다.

서버 프로그램은 Tmax 시스템에서 main() 루틴을 관리하며 개발자는 서비스 루틴만을 작성하면 된다.

서비스 루틴은 Tmax의 유틸리티를 통해 생성되는 각각의 서비스 테이블과 같이 컴파일하며 구조체 버

퍼를 사용하는 경우 역시 유틸리티를 사용하여 얻어지는 컨버전 루틴도 같이 사용하여야 한다.

Tmax 응용 서버에서 반드시 필요한 파일은 Tmax 환경파일과 서버 프로그램이다. Tmax 환경파일은

Tmax가 사용하는 자원들에 대한 전체 시스템 구성을 설정하는 파일이며, Tmax 관리자가 작성한다. 이

파일은 Tmax 시스템과 서버 프로그램 기동할 때 참조되며, 서비스 테이블을 작성하는 경우도 참조된다.

다음은 Tmax 애플리케이션 프로그램의 구조이다.

[그림 1.1] Tmax 애플리케이션 프로그램

참고

클라이언트/서버 프로그램에 대한 자세한 내용은 “제2장 클라이언트 프로그램”과 “제3장 서버 프로

그램”을 참고한다.

1.3. 특징Tmax 애플리케이션은 UNIX 프로그램과 비교하여 다음과 같은 특징을 갖는다.

● 분산처리 국제 표준(X/Open DTP model)을 준수한다.

네트워크을 제어하는 루틴은 Tmax 함수를 사용하며 이 함수는 분산처리 국제 표준(X/Open DTP model)

을 준수한다. 규격을 준수하는 다른 미들웨어로 개발된 프로그램도 별다른 수정없이 사용할 수 있다.

● 클라이언트의 요청을 처리하는 순수한 서비스 루틴만 작성한다.

2 Tmax Application Development Guide

Page 21: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

서버 애플리케이션 프로그램을 작성할 때 클라이언트는 기본적인 C 언어 형식에 맞게 프로그램(내부에

main()을 포함)을 개발해야 하며, 서버 프로그램은 클라이언트의 서비스 요청을 처리하는 순수한 업무

서비스 루틴(내부에 main()이 없는)만 개발한다.

● 다양한 통신 유형을 제공한다.

서비스 요청에는 동기형 통신, 비동기 통신, 그리고 대화형 통신의 3가지 유형이 제공된다. 다양한 통신

유형을 제공하기 때문에 개발자는 통신 네트워크에 대한 깊은 이해없이도 쉽게 프로그램이 가능하게

된다.

다음은 서비스 요청의 유형에 대한 설명이다.

– 동기형 통신

서비스 요청(tpcall)후 응답이 올 때까지 기다린다.

– 비동기 통신

서비스를 요청(tpacall)하고 응답을 받고자(tpgetrply)할 때까지 다른 일을 할 수 있다.

– 대화형 통신

초기 연결설정(tpconnect) 후 메시지 송신(tpsend)과 수신(tprecv)을 반복적으로 수행할 수 있다.

참고

통신 유형에 대한 자세한 내용은 “제4장 통신 유형”을 참고한다.

● 다양한 버퍼를 사용할 수 있다.

서비스를 요청할 때 7가지 버퍼를 사용할 수 있다. 보통 개발자는 타 기종간 데이터 통신을 할 때 데이

터 무결성을 보장하는 데 어려움을 겪는다. 이기종 하드웨어와 운영체제에 따라 데이터를 메모리에 할

당하는 방식과 데이터 타입별로 정의된 길이가 서로 다를 수 있다. 따라서 특정 데이터 값을 송신했을

때 수신측에서는 다른 값으로 인식될 수 있으므로 일반적으로 모든 하드웨어나 운영체제에서 동일하게

인식될 수 있는 문자형으로 변환하여 데이터를 송,수신한다.

Tmax에서는 7가지 유형의 버퍼를 지원함으로써 개발자에게 선택의 폭을 넓혔을 뿐 아니라, 머신, 운영

체제, 네트워크에 대한 깊은 이해가 없이도 개발이 가능하다. 문자형 외에도 구조체 유형 등의 버퍼를

제공함으로써 시스템 성능 향상은 물론 네트워크 부하를 감소시킨다.

참고

버퍼에 대한 자세한 내용은 “제5장 버퍼 유형”을 참고한다.

● 개발이 용이하다.

– 하드웨어, 통신 네트워크에 대한 깊은 이해가 없어도 쉽게 프로그래밍을 가능하게 한다.

제1장 Tmax 애플리케이션 소개 3

Page 22: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

– 서비스 요청을 처리할 서버의 주소를 정확히 모르는 경우에도 서비스를 요청할 수 있다.

– 클라이언트는 이름만으로도 서비스를 요청할 수 있다.

● 트랜잭션 처리의 무결성을 제공한다.

프로그램에서는 트랜잭션의 범위만을 설정하면 Tmax는 2PC 방식으로 데이터의 무결성을 제공한다.

참고

2PC는 Two-Phase Commit의 약자로 둘 이상의 데이터베이스가 연동할 때 2단계 처리(Prepare 단

계, Commit 단계)를 하는 것을 말한다. 자세한 내용은 “제6장 트랜잭션”을 참고한다.

4 Tmax Application Development Guide

Page 23: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제2장 클라이언트 프로그램

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

2.1. 프로그램 흐름클라이언트 프로그램은 사용자의 요구를 받아서 서버에 전달하고, 서버에서 처리된 결과를 받아서 사용

자에게 보여주는 역할을 하는 프로그램이다.

클라이언트 프로그램은 다음의 절차에 따라 작성되어야 한다.

main()

{

tpstart Buffer 할당

tpstart Buffer 초기화

Tmax에 접속

송신/수신 메시지 Buffer 할당

while {

송신 메시지 Buffer에 사용자의 요구 입력

송신 메시지 Buffer를 서버에 보냄(서비스 요청)

서버로부터 응답을 송신 메시지 Buffer로 받음

송신 메시지 Buffer의 내용을 사용자에게 보여줌

}

송신/수신 메시지 Buffer 제거

Tmax 연결해제

}

제2장 클라이언트 프로그램 5

Page 24: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

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

[그림 2.1] 클라이언트 프로그램 흐름

● Tmax 통신 환경 함수

– tmaxreadenv

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

정 파일에 기술할 수 있다.

• tmaxreadenv() API를 호출하는 프로그램을 작성할 때 특정 파일의 경로명 및 파일명을 설정하면

해당 클라이언트 프로그램을 실행할 때 설정된 파일의 파일 포인터를 받은 후 내용을 파싱(parsing)

한다.

• 파싱한 내용 중 TMAX_HOST_ADDR, TMAX_HOST_PORT 등의 Tmax 환경변수는 클라이언트 프

로그램 실행할 때 확보된 메모리 공간 내에 적재한 후 관련 API 함수를 호출할 경우에 이용한다.

● 클라이언트와 서버 연결 함수

– tpstart

• CLL 프로세스로 소켓 연결을 요청한다.

• CLL은 Accept된 연결을 CLH 쪽으로 전달한다.

• tpstart()를 호출할 때 TMAX_HOST_ADDR, TMAX_HOST_PORT에 설정된 값을 사용한다.

– tpend

6 Tmax Application Development Guide

Page 25: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

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

● 통신 버퍼와 해제 함수

– tpalloc

• Tmax를 통한 클라이언트와 서버 사이의 데이터 송수신 때 사용하는 메모리를 동적으로 할당한다.

• 데이터 송수신할 때 필요한 길이 정보를 예측하여 그 크기만큼 미리 할당하여야 한다.

• 동적 할당된 메모리는 반드시 명시적으로 해제해야 한다.

– tpfree

• tpalloc()을 통해 할당된 동적 할당 메모리를 명시적으로 해제(반환)한다.

• 할당된 메모리 버퍼는 반환해야 하며, 그렇지 않을 경우 gabage(memory leakage)가 발생하게 된

다.

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

– tpcall

• CLH 쪽으로 서비스 요청 및 송신 데이터를 전달한다.

• CLH는 클라이언트의 요청 서비스를 확인 후 서버 애플리케이션 프로세스로 넘겨준다.

• 클라이언트는 서비스 요청에 대한 응답이 도착할 때까지 대기한다.

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

– tpacall

• CLH 쪽으로 서비스 요청 및 송신 데이터를 전달한다.

• CLH는 클라이언트의 요청 서비스를 확인한 후 서버 애플리케이션 프로세스로 서비스를 전달한다.

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

– tpgetrply

• CLH 쪽으로 tpacall()에 대한 파라미터(cd) 값을 통해서 응답 데이터를 요청한다.

제2장 클라이언트 프로그램 7

Page 26: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

• CLH에 이미 해당 클라이언트로 보낼 응답 데이터가 있으면 이를 클라이언트로 즉시 전달한다.

• 파라미터 중 flags 설정 값에 따라 응답 데이터가 올 때까지 기다리거나 혹은 기다리지 않고 즉시

응답 수신 에러를 클라이언트에 알려준다.

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

[그림 2.2] 클라이언트 프로그램 함수 프로세스

참고

Tmax에서 애플리케이션 개발을 위해서 제공하는 통신 네트워크, 버퍼 관리를 위한 함수에 대한 자

세한 사항은 “제9장 클라이언트 API”를 참고하거나 "Tmax Reference Guide"를 참고한다.

2.2. 프로그램 특징Tmax는 통신 네트워크, 버퍼 관리를 위한 함수를 제공하여 애플리케이션 개발을 용이하게 한다. Tmax에

서 제공하는 함수는 라이브러리 형태로 제공되고 애플리케이션과 같이 컴파일 된다. 개발자는 어느 머신

의 어느 서버에서 무슨 서비스를 제공하는지 관여하지 않아도 프로그램을 개발할 수 있다.

2.3. 개발 환경Tmax 클라이언트 프로그램의 개발환경은 UNIX, WindowNT, Windows95/98/2000, Windows 3.1, MS-

DOS 등이 운영체제에서 개발이 가능하다.

지원하는 개발 툴은 ANSI C, VC++, BC++, VB, VB .Net, C#, Delphi, PowerBuilder, Embedded VC 등이

다.

8 Tmax Application Development Guide

Page 27: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

참고

개발 툴을 이용한 프로그램의 자세한 내용은 Tmax 안내서 중에 "Tmax Programming Guide(4GL)"

를 참고한다.

2.4. 프로그램 구성클라이언트 프로그램의 코딩이 완료되면 컴파일하여 실행 파일을 만든다.

클라이언트 프로그램을 컴파일하기 위해서는 개발자가 작성한 클라이언트 프로그램, Tmax 클라이언트

라이브러리, 구조체 버퍼를 사용하는 경우 구조체 파일, 그리고 필드키 버퍼는 필드 테이블이 정의된 파일

이 준비되어야 한다.

클라이언트 프로그램은 다음과 같은 구성으로 이루어져있다.

● 클라이언트 프로그램

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

● Tmax 클라이언트 라이브러리(libcli.a /libcli.so)

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

이다.

● 구조체 파일(.s)

클라이언트 프로그램에서 구조체(STRUCT, X_C_TYPE, X_COMMON)를 사용하였다면 <파일명 .s>의

구조체 파일이 필요하다. 구조체 파일을 sdlc 명령어를 이용하여 미리 컴파일한다. 컴파일하면 구조체

의 각 데이터가 표준 통신형으로 변환되는데 필요한 정보를 담은 이진(binary)형태의 파일이 생성된다.

이는 클라이언트 프로그램 실행할 때에 표준 통신형으로 데이터가 송,수신 되는데 사용한다.

● 필드키 파일 (.f)

필드키 구조를 사용하였다면 <파일명.f>의 필드 정의 파일이 필요하다. 파일을 fdlc 명령어를 이용하여

컴파일하면 필드키 버퍼 파일은 Key Mapping을 이용하여 <필드키버퍼이름_fdl.h>를 만들어 프로그램

을 사용하게 된다. 기존의 구조체 파일과는 달리 사용자가 원하는 필드의 값만을 조작하고 전달할 수 있

어 자원의 낭비를 줄일 수 있다. 하지만 Key Mapping하는 과정에서의 오버헤드도 발생할 수 있으므로

주의한다.

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

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

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

제2장 클라이언트 프로그램 9

Page 28: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

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를 사용해서 필드키 파일을 컴파일한다.

다음 그림은 구조체 버퍼를 사용한 클라이언트 프로그램 컴파일 과정이다.

[그림 2.3] 클라이언트 프로그램 컴파일 과정(구조체 버퍼 사용)

10 Tmax Application Development Guide

Page 29: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음 그림은 필드 버퍼를 사용한 클라이언트 프로그램 컴파일 과정이다.

[그림 2.4] 클라이언트 프로그램 컴파일 과정(필드 버퍼 사용)

다음은 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:

제2장 클라이언트 프로그램 11

Page 30: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

$(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에서 make file의 EXE에 확장자를 뺀 클라이언트 이름을 넣으면 동일한 동작을 하게 된다.

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

2.6. 프로세스 기동 및 종료Tmax를 기동하기 위해서 환경변수를 설정해야 한다.

다음은 클라이언트를 위한 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 서버의 IP를 설정하는 부분으로 매우 중요한 역할을 한다.TMAX_HOST_ADDR

클라이언트가 요청한 서비스가 처음 연결이 설정된 서버에 있지 않다면 내부

적으로 다시 연결을 설정하여 서비스를 받게 된다. 클라이언트가 트랜잭션

처리를 요구했다면 처음 연결이 설정된 Tmax가 트랜잭션의 조정자가 되어

2PC를 주관하게 되기 때문이다. 따라서 가장 많이 사용되는 서비스가 위치

한 서버의 주소를 설정함으로써 네트워크 부하 경감은 물론 응답 시간의 단

축도 기대할 수 있다.

12 Tmax Application Development Guide

Page 31: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명항목

Tmax 서버의 포트를 설정하는 부분으로 Tmax 환경파일에 TPORTNO가 설

정되어 있지 않으면 기본값으로 8888이 사용된다.

TMAX_HOST_PORT

● TMAX_BACKUP_ADDR 및 TMAX_BACKUP_PORT

장애에 대비하여 TMAX_BACKUP_ADDR과 TMAX_BACKUP_PORT를 설정할 수 있다.

설명항목

클라이언트에서 서비스 요청하면 먼저 TMAX_HOST_ADDR가 지정하는 서

버로 연결을 시도하고, 그 서버가 장애라면 TMAX_BACKUP_ADDR가 지정

하는 서버로 다시 연결을 시도한다.

TMAX_BACKUP_ADDR

TMAX_BACKUP_ADDR이 지정되어 있지 않다면 클라이언트의 요청은 재접

속 시도 없이 바로 실패로 끝난다.

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

● TMAX_CONNECT_TIMEOUT

네트워크 장애에 대비하여 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 이름 { . . . };” 형식으로 구조

체가 하나 이상 정의되어야 한다.

설명옵션

생성될 SDL 파일 이름을 지정하는데 사용되며, SDLFILE 변수에 정의되는

이름이다.

[ -o sdl 파일 이름]

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

제2장 클라이언트 프로그램 13

Page 32: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명옵션

– 구조체 파일이 하나인 경우: <확장자를 제외한 구조체 파일 이름.sdl>

예) sdlc -c -i demo.s → demo.sdl

– 구조체 파일이 여러 개 나열된 경우: <맨 앞의 구조체 파일 이름.sdl>

예) sdlc -c -i stra.s bana.s orage.s → stra.sdl

sdlc -c -i *.s → a.sdl (현재 디렉터리에 존재하는 .s 파일이 a.s, b.s, c.s일

때)

구조체 정보를 단순히 헤더 파일 형식으로 생성한다.[ -h 헤더파일 이름]

[-h] 옵션이 생략될 경우 <이름_sdl.h>가 생성된다.

sdlc로 컴파일된 SDL 파일이 SDLFILE 변수에 정의되어야 한다. 구조체 통신을 실행할 때 구조체 정보

가 SDLFILE에 있으면 Tmax 서버와의 통신을 할 수 있다.

● FDLFILE

필드 버퍼 통신을 하는 클라이언트 프로그램인 경우, 반드시 설정되어야 하는 환경변수이다. 변수에는

클라이언트 프로그램에서 사용하는 FIELD 버퍼 파일이 fdlc로 컴파일된 FDL 파일이 정의되어야 한다.

FIELD 파일은 다음과 같은 형식으로 컴파일한다.

$ fdlc -c -i FIELD 파일 이름 [ -o fdl 파일 이름] [ -h 헤더파일 이름]

설명옵션

생성될 FDL 파일 이름을 지정하는데 사용되며, FDLFILE 변수에 정의되는

이름이다.

[ -o fdl 파일 이름]

[-o] 옵션이 생략될 경우 기본값으로 생성되는 FDL 파일은 <tmax.fdl>이 된

다.

구조체 정보를 단순히 헤더 파일 형식으로 생성한다.[ -h 헤더 파일 이름]

[-h] 옵션이 생략될 경우 <이름_fdl.h>가 생성된다.

fdlc로 컴파일된 FDL 파일이 FDLFILE 변수에 정의되어야 한다. 필드 버퍼 통신 실행할 때 필드 정보가

FDLFILE에 있으면 Tmax 서버와의 통신을 할 수 있다.

UNIX 환경파일에 Tmax 환경변수가 설정되어 있으면 클라이언트 프로세스를 생성시키는데 필요한 준

비는 완료되었다. 클라이언트 프로세스는 다른 실행 파일과 같은 방법으로 실행하고 종료시키면 된다.

14 Tmax Application Development Guide

Page 33: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

참고

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

제2장 클라이언트 프로그램 15

Page 34: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 35: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제3장 서버 프로그램

본 장에서는 서버 프로그램의 흐름과 특징, 구성에 대해서 설명한다. 서버 프로그램은 사용자의 요청을 받

아서 처리하고 그 응답을 클라이언트에게 반환한다. 서버 프로그램을 이해하기 위해서는 서버의 프로세

스에 대해 먼저 이해해야 한다.

3.1. 서버 프로세스Tmax 서버는 다음의 3가지 방법으로 프로세스를 제공한다.

● TCS(Tmax Control Server)

클라이언트 요청의 프로세스를 처리하는 전형적인 처리 방법이다.

● UCS(User Control Server)

TCS가 수동적인 방법인 반면, UCS는 능동적인 프로세스 처리 방법으로 클라이언트의 요청없이 클라

이언트에게 지속적으로 데이터를 보내는 방법이다.

● RDP(Realtime Data Processor)

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

[그림 3.1] 프로세스 유형

제3장 서버 프로그램 17

Page 36: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.1.1. TCS

TCS 프로세스는 보통의 3-Tier 개념을 가진 서버 프로세스이다. Tmax 시스템은 요청한 결과를 수신하고

그것을 클라이언트에게 반환하는 적절한 프로세스에 클라이언트의 요청을 스케줄한다.

Tmax는 TCS형의 서비스 프로그램을 위한 main() 함수를 제공하기 때문에 개발자는 서비스 루틴만을 개

발하면 된다. TCS형 프로그램은 지정된 서비스 이름을 함수로 하여 개발하는 것이다.

다음은 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);

}

참고

TCS형 서비스를 처리하기 위한 함수에 대한 자세한 사항은 "Tmax Reference Guide"를 참고한다.

3.1.2. UCS

전형적인 TCS형 프로세스는 단지 클라이언트에서 요구한 일을 처리하는 수동적인 타입이다. 하지만 UCS

는 클라이언트의 요청없이도 연결하여 서비스를 제공한다. UCS는 서비스를 신속하게 제공할 수 있고 TCS

타입을 지원하여 더 많은 기능들을 제공할 수 있다.

UCS 프로그램은 usermain()과 서비스 루틴을 구성하고 있다. 서비스 루틴은 TCS와 UCS 중에 하나와 동

일해야 하고 UCS 프로세스는 UCS 라이브러리(libsvrucs.a)와 링크되어 있어야 한다. UCS 타입 프로세스

가 tmdown 명령어를 사용하여 정상적으로 종료되기 위해서는 loop되는 동안 tpschedule()이 사용되어야

한다.

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

...

int usermain(int argc, char *argv[])

{

...

while (1) /* 무한 Loop */

18 Tmax Application Development Guide

Page 37: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

{

clid = tpgetclid();

ret = tpsendtocli(clid, sndbuf, slen, TPNOFLAGS);

if (ret < 0)

{

error processing routine

}

...

tpschedule(10); /* UCS 프로세스는 while loop에 이 함수를 추가해야 한다.*/

/* 만약 tmdown을 호출하면 이벤트를 여기로 보낸다. */

...

} /* end of while */

}

기본적으로 usermain()은 loop되고 있는 작업을 처리한다.

usermain()은 특정 클라이언트에게 데이터를 보내기 위해 tpsendtocli()를 사용하고 TCS형 서비스를 처리

하기 위해 tpschedule()을 사용한다.

tpschedule()은 UCS형 서버 프로세스에서만이 사용되는 함수이다. Timeout 인자를 가진 함수는 Timeout

(초)만큼 데이터를 기다리다 데이터가 도착하면 즉시 반환하고 그 시간 안에 도착하지 않으면 Timeout 적

용을 받는다. Timeout 인자는 초 단위이다. 인자가 –1로 설정된 경우에는 반환된 데이터가 있는지 없는지

에 대해 체크하고 만약 데이터를 받지 않았다면 다음 단계로 반환한다. 인자가 0으로 설정된 경우에는 클

라이언트 요청을 받을 때까지 기다린다.

tpschedule() 함수는 데이터가 도착했을 때 해당되는 서비스가 자동적으로 수행되고 난 후에 반환된다. 그

러므로 데이터가 도착한 후에 사용자가 임의로 서비스를 수행하지 말아야 한다. 서비스는 무조건 시스템

에 의해서 항상 수행됨으로 UCS 형태의 서비스 프로그램이라도 이점을 주의한다.

다음은 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

제3장 서버 프로그램 19

Page 38: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#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

}

}

}

참고

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

로 받아야 한다.

2.UCS형 서비스를 처리하기 위한 함수에 대한 자세한 사항은 "Tmax Reference Guide"나 "Tmax

Programming Guide(UCS)"를 참고한다.

20 Tmax Application Development Guide

Page 39: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.1.3. 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)"를 참

고한다.

제3장 서버 프로그램 21

Page 40: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.2. 프로그램 흐름서버 프로그램은 Tmax에서 제공하는 main()과 개발자가 개발하는 서비스 루틴으로 크게 나누어 볼 수 있

다.

[그림 3.2] 서버 프로그램 흐름

main()은 명령어 라인에 입력된 인수 처리, 연결된 데이터베이스 연결 및 해제 역할, 서비스 루틴에서 사

용할 버퍼를 할당한다. 그리고 클라이언트 요청을 처리하는 서비스 루틴을 호출하는 역할을 한다.

서비스 루틴은 클라이언트의 요청을 처리한다. 클라이언트의 요청은 먼저 main()에서 서비스 요청과 관련

된 정보를 가지고 있는 TPSVCINFO 구조체로부터 받는다. 클라이언트가 요구한 버퍼의 내용은

TPSVCINFO→DATA에 있다. 서비스 루틴에서는 TPSVCINFO→DATA에서 데이터를 받아서 요청 기능

을 처리한 후, 결과를 클라이언트에게 전달하거나, 또 다른 처리를 위하여 다른 서버에 서비스 처리를 요

구한다.

Tmax 서버 프로그램의 흐름은 TCS 방식과 UCS 방식이 다르게 진행된다. 일반적인 서버 프로그램인 TCS

방식의 경우 서비스 루틴 안에서 모든 처리가 일어나지만 UCS 방식 서버 프로그램의 경우는 서비스 루틴

과 usermain()을 적절히 사용하여 기존에는 구현하기 힘들었던 다양한 방식의 서비스를 제공할 수 있다.

22 Tmax Application Development Guide

Page 41: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.2.1. TCS

Tmax에서 관리하는 main() 루틴에서는 명령어 라인에 입력된 인수 처리, 필요할 경우 데이터베이스와의

연결과 해제 작업이 이루어지며 서비스 루틴에서 사용하는 TPSVCINFO 구조체 버퍼를 할당하고 관리한

다. TMM, CLH로부터 전해지는 메시지를 기다리며 서비스 요청이 오면 데이터를 받아 서비스 루틴을 호

출하여 실제 서비스가 이루어지도록 한다.

서비스 루틴은 클라이언트의 요청을 처리한다. main()에서는 클라이언트에게 받은 서비스 요청을 여러 가

지 정보와 함께 TPSVCINFO 구조체에 넣어 서비스 루틴에 넘기며 서비스 루틴은 서비스 수행의 결과를

클라이언트에게 넘겨준다.

[그림 3.3] TCS방식 서버 프로그램 흐름

제3장 서버 프로그램 23

Page 42: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.2.2. UCS

UCS 방식 서버 프로그램도 TCS 방식과 유사하며 추가적으로 usermain() 루틴을 갖고 있다. UCS 방식의

usermain() 루틴은 다른 명령이 없는 동안 독자적으로 반복적인 작업을 수행하며 스케줄링 API를 사용하

여 CLH나 TMM으로부터 오는 명령들을 처리해준다.

[그림 3.4] UCS방식 서버 프로그램 흐름

3.3. 프로그램 특징Tmax 응용 서버 프로그램은 Tmax에서 제공하는 main()과 개발자가 작성한 업무처리 서비스 루틴으로 구

성된다. 서버 프로그램은 응용 클라이언트 프로그램처럼 Tmax 함수를 이용하여 작성된다. 이 함수들은

라이브러리(libsvr.a, libsvr.so )로 제공되며 응용 서버 프로그램과 같이 컴파일된다.

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

● 서버는 하나 이상의 서비스로 이루어지고 서버 자신이 클라이언트가 되어 다른 서버에 서비스를 요청

할 수 있다.클라이언트의 정보와 결과를 모두 보내어 클라이언트의 관리를 넘길 수도 있다.

● Tmax 함수가 통신 및 데이터 변환을 제공하므로, 개발자는 UNIX 내부 시스템과 프로토콜을 만들거나

네트워크 프로그래밍에 대한 이해없이도 프로그램 개발이 가능하다.

● XA 모드의 경우 데이터베이스 연결과 해제가 Tmax가 관리하는 루틴에서 관리되기 때문에 개발자는 데

이터베이스 연결과 관리에 대해 신경쓰지 않아도 된다.

24 Tmax Application Development Guide

Page 43: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.4. 개발 환경Tmax 응용 서버 프로그램의 O/S 환경은 하드웨어와는 무관한 모든 UNIX 기종을 지원하고 UNIX 표준 편

집기 vi로 개발이 가능하다.

3.5. 프로그램 구성서버 프로그램 구성은 TCS형과 UCS형으로 나누어 설명한다.

3.5.1. TCS

TCS형 서버 프로그램은 다음과 같은 구성으로 이루어져있다.

● 서버 프로그램

개발자가 작성한 서비스루틴이다. 클라이언트의 요청을 처리한다.

SQL문을 사용하였다면 해당 데이터베이스 벤더가 제공하는 툴을 이용하여 프리 컴파일을 마쳐야 한다.

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

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

들이 있다.

● 서비스 테이블

서비스 테이블은 서버마다 제공되는 서비스 이름들이 나열되어 있는 파일로서 Tmax 환경파일을 참조

하여 만든다.

서비스 테이블은 서비스를 수행할 때 실제적으로 서버내에서 해당 서비스 루틴의 위치를 찾기 위해 사

용되며 시스템 관리자가 제공한다. 이에 대한 자세한 내용은 "Tmax Administration Guide"를 참고한다.

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

구조체형 버퍼(STRUCT, X_C_TYPE, X_COMMON)를 사용하였다면 이를 정의하는 <xxxx.s> 형식의

구조체 파일이 필요하다.

구조체 파일은 표준 통신 타입(구조체 파일명_sdl.c) 과 구조체 헤더 파일(구조체 파일명_sdl.h)이 있다.

구조체 파일은 sdlc –c 명령어를 이용하여 컴파일하며 그 결과 구조체의 멤버들을 표준 통신형으로 변

환하는데 필요한 바이너리 테이블 파일이 생성된다. 이는 서버 프로그램을 실행할 때에 구조체형의 데

이터를 표준 통신형으로 변환/역변환하는데 사용된다.

구조체를 사용하지 않을 경우에는 $TMAXDIR/lib/sdl.o을 응용 서버와 컴파일해야 한다.

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

제3장 서버 프로그램 25

Page 44: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

필드 버퍼를 사용하였다면 <xxxx.f> 형식으로 정의된 필드 버퍼 파일이 필요하다. 이 파일은 fdlc 명령어

를 이용하여 컴파일하며 그 결과 필드키와 데이터를 대응시켜주는 바이너리 테이블 파일과 필드키와

필드키 이름을 대응시켜주는 헤더 파일(xxxx_fdl.h)이 만들어진다. 기존의 구조체 파일과는 달리 사용자

가 원하는 필드의 값만을 조작하고 전달할 수 있으므로 다양한 타입의 데이터를 사용하는 경우 자원의

낭비를 줄일 수 있다. 하지만 데이터 값과 필드키 값을 같이 관리하므로 많은 필드를 사용하지 않는다면

역효과가 발생할 수도 있다.

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

서버 프로그램 내에서 구조체 버퍼를 사용하기 위해서는 sdlc 명령어로 만들어진 구조체-표준 버퍼 변

환/역변환 프로그램(xxxx_sdl.c, xxxx_sdl.h)을 컴파일하여 같이 링크해야 한다. 구조체를 사용하지 않

을 경우에는 TMAXDIR/lib/sdl.o를 링크하도록 한다.

다음은 서비스 테이블 작성 방법이다.

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 안내서 중에 "Tmax Administration Guide"를 참고한다.

3.5.2. UCS

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

● main()

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

● usermain()

특별한 메시지(서비스 요청이나 제어 메시지)가 없는 동안에 독자적인 작업을 수행한다.

26 Tmax Application Development Guide

Page 45: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 서비스 루틴

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

UCS 방식의 main() 루틴은 일반적인 초기화 작업을 하고 usermain() 루틴을 호출한다. TMM, CLH로부터

도착하는 메시지는 usermain()에서 처리된다. usermain()이 종료되면 main() 루틴은 tpsvrdone() 루틴을

수행하고 같이 종료된다.

usermain() 루틴은 독자적인 작업을 하다가 일정 시점에 스케줄링 API를 통하여 TMM, CLH로부터의 제

어 명령이나 서비스 수행 명령을 처리한다. usermain()이 종료될 경우 해당 서버 프로세스 역시 종료되므

로 일반적으로 무한 loop 형식으로 작성된다. 클라이언트의 서비스 요청이나 TMM, CLH 제어 메시지를

처리하기 위해 이 무한 loop 안에는 반드시 하나 이상의 스케줄링 API가 사용되어야 한다.

usermain()은 명령어 라인 인수를 받을 수 있으며 이 값은 Tmax 시스템 환경파일 SERVER 절의 CLOPT

에 설정된 값으로 tpsvrinit()에 전달되는 값과 동일하다.

int usermain(int argc, char *argv[])

{

.....

while(1) {

......

tpschedule(-1);

.....

}

return 0;

}

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

서비스 루틴은 일반적으로 다음과 같이 선언한다.

<서비스 이름>(TPSVCINFO *msg)

서비스 이름은 NULL 종료문자를 포함하여 16자 이내이며 언더스코어(_)로 시작되는 이름은 Tmax에서

내부적으로 사용하므로 사용하지 않도록 한다. UCS 방식 서버 프로그램의 경우 서비스 루틴은 존재하지

않아도 무관하며 이 경우 서버 프로세스는 데몬 프로세스와 비슷한 성격을 갖게 된다.

TOUPPER(TPSVCINFO *msg)

{

.....

}

참고

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

제3장 서버 프로그램 27

Page 46: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3.6. 프로그램 컴파일서버 프로그램 컴파일은 TCS형과 UCS형으로 나누어 설명한다.

3.6.1. TCS

개발자가 서버 프로그램의 작성이 완료되면 컴파일하여 실행 파일을 만든다.

서버 프로그램을 컴파일하기 위해서는 개발자가 작성한 서버 프로그램, Tmax 서버 라이브러리, 서비스

테이블이 필요하다. 구조체 버퍼를 사용한 경우는 구조체-표준 버퍼 변환/역변환 프로그램과 구조체 바이

너리 테이블이 있어야 하고 필드 버퍼를 사용하였다면 필드 버퍼 헤더 파일과 필드 버퍼 바이너리 테이블

이 있어야 한다.

일반적인 C 컴파일러를 이용한 컴파일 방법으로 이 과정은 기본적으로 Tmax를 설치하면 생성되는 셸 프

로그램을 사용하거나 mksvr 유틸리티를 이용하여 간단하게 할 수 있다.

다음의 예제는 리눅스에서의 실행 결과이며 개발 환경(32/64비트)과 플랫폼에 따라 사용되는 플래그 및

라이브러리가 조금씩 다르다.

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

28 Tmax Application Development Guide

Page 47: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음은 구조체 버퍼를 사용하는 서버 프로그램의 작성 순서이다.

[그림 3.5] 서버 프로그램 컴파일(sdl)

다음은 필드 버퍼를 사용하는 서버 프로그램의 작성 순서이다.

[그림 3.6] 서버 프로그램 컴파일(fdl)

제3장 서버 프로그램 29

Page 48: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

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

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 $<

30 Tmax Application Development Guide

Page 49: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#

# 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

제3장 서버 프로그램 31

Page 50: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

$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 안내서 중에 "Tmax Reference Guide"를 참고한다.

3.6.2. UCS

UCS 방식 서버 프로그램의 컴파일은 TCS 방식의 서버 프로그램과 크게 다르지 않다. 준비 사항과 컴파

일 순서는 완전히 동일하며 다만 서버 라이브러리를 libsvr.a (혹은 libsvr.so)가 아닌 libsvrucs.a (혹은 lib

svrucs.so)를 사용하면 된다.

다음은 일반적인 C 컴파일러를 이용한 컴파일 방법이다. 이 과정은 셸 프로그램을 사용하거나 mksvr 유

틸리티를 이용하면 간단하게 처리할 수 있다.

다음 예제는 리눅스에서의 실행 결과이며 개발 환경(32/64비트)과 플랫폼에 따라 사용되는 플래그 및 라

이브러리가 조금씩 다르다. 사용 라이브러리를 제외하고는 TCS 방식과 완전히 동일하므로 자세한 내용

은 “3.6.1. TCS”을 참고한다.

1. 서버 프로그램을 컴파일하여 오브젝트 파일을 생성한다. 서버 프로그램은 Tmax에서 제공하는 헤더 파

일들을 참조해야 하며 필요에 따라 구조체 파일이나 필드 버퍼 헤더 파일도 참조되어야 한다.

SQL 문을 사용하였다면 먼저 해당 데이터베이스 벤더가 제공하는 툴로 프리 컴파일을 마쳐야 한다.

$cc -c -I/home/tmax/usrinc app.c → app.o

2. 구조체 통신인 경우 구조체 파일을 컴파일한다. 이 단계는 sdlc을 이용하여 구조체-표준 버퍼 변환/역변

환 프로그램을 생성하는 단계와 생성한 프로그램을 다시 오브젝트 파일로 컴파일하는 2단계로 이루어

진다.

$sdlc -i demo.s -> demo_sdl.c

$cc -c -I/home/tmax/usrinc demo_sdl.c → demo_sdl.o

32 Tmax Application Development Guide

Page 51: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

3. 구조체 파일을 사용하지 않는다면 이 과정을 수행할 필요없이 TMAXDIR/lib 디렉터리 내의 <sdl.o>를

사용하여 같이 컴파일한다.

4. 시스템 관리자가 제공해준 서비스 테이블을 컴파일하여 오브젝트 파일 형태를 생성한다. 다음은 데이

터베이스를 사용하지 않는 경우의 예제로 데이터베이스를 사용하는 경우 데이터베이스에 따라 libo

ras.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 안내서 중에 "Tmax Reference Guide"를 참고한다.

3.7. 프로세스 생성 및 종료서버 프로세스 생성은 시스템 관리자가 해야할 역할이다. Tmax 애플리케이션 서버는 단독으로 UNIX 실

행 파일처럼 실행되지 않는다. 서버 프로세스가 생성되면서 Tmax 관련 환경을 참조하기 때문이다. 따라

서 tmboot 명령어로 서버프로세스를 생성하고, tmdown 명령어로 종료시킨다.

Tmax 애플리케이션 서버 프로세스를 생성시키기 전에 시스템 관리자가 작성한 Tmax 환경파일(예: sam

ple.m)이 컴파일(cfl 명령어 이용)되어 있어야 한다. 컴파일된 이진 환경파일(예: tmconfig)을 참조하여 서

버 프로세스를 생성하게 된다.

설명명령어

Tmax 시스템 프로세스와 이진화된 Tmax 구성파일에 등록된 모든

서버 프로세스를 생성한다.

$tmboot [-f 이진화된 구성파일]

특정 서버 프로세스만을 생성시킨다.$tmboot [-s 서버프로그램 이름]

Tmax 시스템 프로세스와 이진화된 Tmax 구성파일에 등록된 모든

서버 프로세스를 종료시킨다.

$tmdown [-f 이진화된 구성파일]

제3장 서버 프로그램 33

Page 52: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명명령어

특정 서버 프로세스만을 종료시킨다.$tmdown [-s 서버프로그램]

참고

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

34 Tmax Application Development Guide

Page 53: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제4장 통신 유형

Tmax 시스템에서 응용 서버와 클라이언트 사이의 통신은 동기형 통신, 비동기 통신, 대화형 통신 3가지

유형이 있다.

● 동기형 통신

클라이언트가 tpcall()을 호출하여 서버에 요청을 보내고 서버에서 응답이 올 때까지 블로킹되어 기다린

다.

● 비동기 통신

클라이언트가 tpacall()을 호출하여 서버에 요청을 보낸 후 서버에서 응답이 올 때까지 기다리지 않고,

다른 일을 처리할 수 있다. 응답을 받고자 할 경우 tpgetrply()를 호출하여 서버로부터 응답을 받는다.

● 대화형 통신

tpconnect() 서비스를 연결하고 tpsend()로 메시지를 보낸다. 메시지를 받을 때는 tprecv()로 받는다.

각각의 통신 유형에 따라 다음과 같은 특징을 가진다.

특징통신 유형

- 보통의 경우 동기형 통신을 가장 많이 사용한다.동기/비동기 통신

- tpcall()과 tpacall()로 서비스 요청을 한다.

- 데이터를 보내기 전에 반드시 tpalloc()으로 송수신 버퍼를 할당해야 한다.

- 클라이언트는 한번에 하나의 요청을 보내고 응답을 받는다.

- 서버는 요청을 처리할 때 1건씩 처리를 종료한 후 다른 요청을 받는다.

- 서버의 업무 처리 서비스 루틴은 tpreturn() 또는 tpforward()에 의해서 끝난

다.

- tpconnect()로 서비스 요청을 초기화한다.대화형 통신

- 데이터를 보내기 전에 반드시 tpalloc()으로 송,수신 버퍼를 할당해야 한다.

- 서버는 동기/비동기 통신과는 달리 반드시 대화형 서비스 함수만을 사용하

여 프로그램을 개발해야 한다.

- 데이터를 주고 받기 위해 tpsend()와 tprecv()를 이용한다.

제4장 통신 유형 35

Page 54: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

특징통신 유형

- 대화형 통신에서 tpforward()를 사용할 수 없다.

- 대화형 모드에서 보통 연결 유지 시간이 길어 잘 사용하지 않는다.

4.1. 동기형 통신동기형 통신은 클라이언트가 서비스를 요청하고, 그 응답이 오거나 타임아웃이 될 때까지 기다린다. 서비

스를 요청한 후 클라이언트는 블로킹 상태로 응답을 기다린다.

[그림 4.1] 동기형 통신

다음 그림은 동기형 통신을 사용하는 클라이언트/서버 프로그램의 동작원리를 보여준다.

[그림 4.2] 동기형 통신 모델

36 Tmax Application Development Guide

Page 55: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

참고

동기형 통신관련 함수에 대한 자세한 설명은 “9.2. 동기형 통신” 이나 "Tmax Reference Guide"를 참

고한다.

4.2. 비동기형 통신비동기형 통신은 클라이언트가 서비스를 요청하고 응답을 기다리지 않고 다른 일을 계속할 수 있다. 응답

을 받고자 할 때 해당 요청에 대한 응답을 받는다. 서비스를 요청하는 tpacall()은 호출할 때 즉시 반환되어

다른 서비스 요청을 처리할 수 있다. 하지만 응답을 받기 위해 호출하는 tpgetrply()는 응답이 도착하거나

타임아웃이 될 때까지 블로킹 상태로 기다린다.

[그림 4.3] 비동기형 통신

다음 그림은 비동기형 통신을 사용하는 클라이언트/서버 프로그램의 동작원리를 보여준다.

[그림 4.4] 비동기형 통신 모델

제4장 통신 유형 37

Page 56: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

참고

비동기 통신관련 함수에 대한 자세한 설명은 “9.3. 비동기 통신”이나 "Tmax Reference Guide"를 참

고한다.

4.3. 대화형 통신대화형 통신은 클라이언트와 서버 간에 이루어지는 반이중 통신이다. 처음 대화형 모드로 접속할 때 대화

주도권을 설정하며 대화 주도권을 잡는 쪽은 송신, 상대편은 수신만이 가능하다. 대화 주도권을 갖고 있는

쪽은 언제든지 상대편에게 주도권을 넘길 수 있으므로 메시지를 주고 받은 것이 가능하다. 이러한 대화 주

도권의 제어는 송신 측의 플래그를 사용하여 이루어지며 수신 측은 이러한 변화를 이벤트 값을 통해 알 수

있다. 다음은 간단한 대화형 통신의 연결 컨트롤을 넘기는 것과 연결을 종료하는 과정에 대한 설명이다.

[그림 4.5] 대화형 통신

대화형 통신은 tpconnect()로 연결을 한 후, tpsend()와 tprecv()를 호출하여 데이터를 주고 받는다. 데이터

를 보내려면 tpconnect()와 tpsend()에서 플래그 값의 설정으로만 움직이는 연결 컨트롤을 가져야만 가능

하다.

38 Tmax Application Development Guide

Page 57: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음 그림은 대화형 통신을 사용하는 클라이언트/서버 프로그램의 동작원리를 보여준다.

[그림 4.6] 대화형 통신 모델

참고

대화형 통신관련 함수에 대한 자세한 설명은 “9.4. 대화형 통신”이나 "Tmax Reference Guide"를 참

고한다.

● 대화형 통신은 tpconnect()를 호출함으로써 시작된다. 함수는 해당 대화형 서비스에 데이터를 보내는

동시에 대화 주도권을 설정하게 된다. tpconnect()가 성공적으로 수행되면 각각의 대화모드를 구분하기

위한 ‘연결 구분자(cd)’ 를 반환하며 이것을 이용하여 메시지를 송, 수신할 수 있게 된다.

대화형 통신은 서비스 중 문맥(context)에 따라 추가적인 정보가 필요한 경우에 사용한다. 그러나 연결

설정(tpconnect())에서 연결 해제(tpdiscon() 또는 tpreturn())까지 다른 통신과 비교하여 상대적으로 장

시간 연결이 유지되어야 한다. 장시간 연결 유지는 네트워크의 부하를 증가시키므로 가능하면 동기/비

동기 통신을 이용할 것을 권장한다.

● 일반적으로 대화형 통신은 서버 측에서 tpreturn()을 호출하여 완료된다. 이러한 경우 상대방은 데이터

와 함께 TPEV_SVCSUCC 이벤트를 수신하게 된다. 대화를 시도한 측에서 tpdiscon()를 호출함으로써

대화형 통신을 강제적으로 종료할 수도 있으며 전송 중의 데이터는 사라질 수도 있고 진행 중인 트랜잭

션은 rollback된다.

제4장 통신 유형 39

Page 58: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 대화 주도권은 주도권을 갖고 있는 쪽에서만 상대방에게 넘겨줄 수 있으며 tpsend()의 TPRECVONLY

플래그를 이용한다. 상대방은 데이터와 함께 TPEV_SENDONLY 이벤트를 수신하게 되고 대화 주도권

을 잡게 된다.

● 컨트롤을 상대방에 넘길 때는 tpconnect() 또는 tpsend()에서 flags 파라미터를 TPRECVONLY로 설정

하여 호출한다. 그러면 상대방에서 TPEV_SENDONLY라는 이벤트가 발생하여 컨트롤이 넘어왔음을

알게 된다. 이 후부터 tpsend()를 호출해서 데이터를 보낼 수 있다. 물론 상대방은 데이터 수신만 가능하

다.

● 대화형 모드에서 사용하는 버퍼도 동기/비동기 통신처럼 버퍼를 써야 하며, 미리 tpalloc()으로 할당하

여야 한다. Tmax 통신에서 사용하는 모든 버퍼는 tpalloc()으로 할당되어야 한다.

4.3.1. 대화형 통신과 관계 있는 이벤트

대화형 통신에서는 5가지의 이벤트가 존재한다.

아래의 표는 대화형 통신할 경우 5개의 이벤트가 발생되는 함수와 의미를 나타내고 있다.

설명받는 함수이벤트

연결 컨트롤이 존재하는 장소를 알려준다.tprecv()TPEV_SENDONLY

(0x0020)

연결이 비규칙적으로 끊어졌을 때 받는 이벤트로 tpdiscon()

이 호출되거나 하위 서비스들이 여전히 열린 채 남아 있는

데 tpreturn()를 호출할 때 발생한다.

tesend()

tprecv()

TPEV_DISCONIMM

(0x0001)

tpreturn()

연결의 컨트롤을 가지지 않았는데 tpreturn()를 호출할 때 발

생하는 이벤트로 tpreturn()의 인자는 정당하지만 어떤 에러

가 생겼을 때 발생한다.

tpsend()

tprecv()

TPEV_SVCERR

(0x0002)

연결의 컨트롤을 가지지 않은 상태에서 tpreturn()를 호출하

거나 tpreturn()에서 TPFAIL, TPEXIT로 셋팅하여 호출할 때

발생한다.

tpsend()

tprecv()

TPEV_SVCFAIL

(0x0004)

성공적으로 서비스를 마치는 경우에 발생하는 이벤트로

TPSUCCES로 설정되어 tpreturn()이 호출된다.

tprecv()TPEV_SVCSUCC

(0x0008)

참고

함수에 대한 자세한 설명은 "Tmax Reference Guide"를 참고한다.

40 Tmax Application Development Guide

Page 59: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제5장 버퍼 유형

다수의 서버를 운영하면서 서로 다른 하드웨어 및 운영체제 간에 데이터를 교환할 필요가 있을 경우 플랫

폼마다 메모리 할당 방식의 차이로 생기는 문제점을 극복하기 위해서는 모든 플랫폼에 대한 상세한 지식

과 더불어 데이터를 전환하는 복잡한 과정이 필요하다.

Tmax는 다양한 종류의 표준 버퍼를 제공하여 이러한 문제를 해결하며 불필요한 네트워크 부하를 줄이고

개발자의 선택의 폭을 넓히며 개발기간을 단축하는 등의 부가적인 장점이 있다.

5.1. 버퍼의 종류Tmax에서는 네트워크 부하의 감소와 개발의 용이성을 위하여 STRING, CARRAY, X_OCTET , STRUCT,

X_COMMON, X_C_TYPE, FIELD 7개의 버퍼를 지원한다.

● STRING 버퍼

NULL 값으로 끝나는 문자열로서 따로 버퍼의 길이를 명시할 필요가 없다. 플랫폼의 차이로 인한 문제

는 발생하지 않는다.

● CARRAY , X_OCTET 버퍼

길이가 지정된 Byte 열로서 보통 바이너리 타입의 데이터를 보낼 때 사용되며 데이터 교환할 때에는 반

드시 길이를 명시해야 한다. 플랫폼의 차이로 인한 문제는 발생하지 않는다.

● STRUCT , X_C_TYPE 버퍼

C 언어의 구조체를 데이터 통신에 사용할 때 사용한다. 구조체의 멤버로는 모든 원시 타입을 사용할 수

있으며 선언된 구조체 자체도 멤버로 사용할 수 있다. 또한 구조체의 배열도 사용할 수 있다.

● X_COMMON 버퍼

멤버 타입이 char, int, long으로 한정된 C 구조체이다.

● FIELD 버퍼

필드키와 데이터 값을 한 쌍으로 관리하는 데이터 버퍼로 모든 원시 타입의 데이터를 담을 수 있다. 교

환되는 데이터형이 유동적일 경우 사용하며 다양한 방법의 데이터 접근 및 변환 API를 제공한다.

제5장 버퍼 유형 41

Page 60: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

[그림 5.1] Tmax 통신 버퍼 유형

Tmax 애플리케이션 개발자는 Tmax에서 제공하는 다양한 버퍼를 사용하여 다음과 같은 효과를 얻을 수

있다.

● 애플리케이션은 다양한 버퍼로 업무 프로그램을 보다 유연하게 개발할 수 있도록 한다.

● 데이터 변환에 필요한 프로그램을 필요로 하지 않는다.

● 네트워크 부하를 감소시킨다. 초기에 설정한 데이터 유형을 송, 수신할 수 있게 함으로서 문자형 데이터

로 변환하는 데 따르는 네트워크 부하를 감소시킨다.

5.2. 버퍼 관리버퍼의 무결성을 보장하기 위해 표준 통신형 버퍼를 사용한다.

표준 통신형 버퍼는 통신 이전에 데이터 타입과 메모리 할당 방식에 기준을 정하여 사용하는 것이다. 송신

하기 전에 버퍼의 데이터를 표준 통신형으로 변환하고 수신하기 전에 역변환한다. 데이터의 변환/역변환

을 통해 Tmax는 이기종 간 통신할 경우 문자형 뿐만 아니라 구조체형의 버퍼도 사용 가능하다.

표준 통신형으로의 변환을 위해 Tmax에서는 sdlc 프로그램이 사용된다. sdlc 프로그램을 이용하면 클라

이언트에는 표준 통신형 데이터로의 변환을 위한 정보 테이블이, 서버에서는 표준 통신형으로의 변환/역

변환 프로그램이 생성된다. 이 과정을 통해 이기종 간의 통신할 경우에도 문자열이나 Byte 열 뿐만 아니라

플랫폼마다 다른 원시 타입의 데이터형을 사용하는 구조체 버퍼나 필드 버퍼를 아무런 제약없이 사용할

수 있게 된다.

42 Tmax Application Development Guide

Page 61: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

구조체 버퍼인 STRUCT, X_C_TYPE, X_COMMON은 표준 통신형으로 변환되어야 하고 컴파일할 때 추

가되어야 한다. STRING, CARRAY, X_OCTET 버퍼는 이기종 간에도 string형 통신이 가능하므로 표준 버

퍼형으로의 변환이 필요없다.

5.2.1. 구조체 버퍼

개발자는 사용하고자 하는 구조체를 구조체 파일에(xxx.s) 기록하며 이 파일은 변환 테이블과 변환 프로

그램을 만드는 기반이 된다. 구조체 파일에는 typdef나 include와 같은 명령어는 사용할 수 없으며 구조체

의 멤버는 모든 원시 타입 데이터와 구조체를 사용할 수 있다.

구조체 버퍼를 표준 통신형으로 사용하기 위해서는 Tmax에서 제공하는 sdlc 프로그램을 사용하여 표준

통신형 데이터로의 변환을 위한 정보 테이블과 표준 통신형 변환/역변환 프로그램을 생성해야 한다. 변환/

역변환 프로그램은 개발된 서비스 루틴과 함께 컴파일하여 사용하며 정보 테이블은 구조체 사용할 때 자

동으로 사용된다.

다음 그림은 구조체 버퍼(STRUCT, X_C_TYPE, X_COMMON)를 이용한 애플리케이션 개발할 때 서버/

클라이언트 프로그램의 컴파일 순서이다. 구조체 버퍼의 이름은 demo.s이다.

[그림 5.2] 구조체 버퍼를 이용한 애플리케이션 프로그램 컴파일

5.2.2. 필드 버퍼

개발자는 사용하고자 하는 필드 버퍼를 필드 버퍼 파일에(xxx.f) 기록하며 이 파일은 변환 테이블을 만드

는 기반이 된다.

필드 버퍼를 표준 통신형으로 사용하기 위해서는 Tmax에서 제공하는 fdlc 프로그램을 사용하여 정보 테

이블을 생성하며 이 테이블은 필드 버퍼 사용할 때 자동적으로 사용된다.

제5장 버퍼 유형 43

Page 62: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음 그림은 필드버퍼를 이용한 애플리케이션 개발할 때 서버/클라이언트 프로그램의 컴파일 순서이다.

필드 버퍼의 이름은 demo.f 이다.

[그림 5.3] 필드 버퍼를 이용한 애플리케이션 프로그램 컴파일

참고

버퍼 관련 함수에 대한 자세한 설명은 “9.7. 버퍼 관리”나 "Tmax Reference Guide"를 참고한다.

44 Tmax Application Development Guide

Page 63: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제6장 트랜잭션

본 장에서는 트랜잭션의 개념과 정의 및 처리 방법을 설명한다.

6.1. 특징트랜잭션은 자원을 하나의 일관된 상태에서 다른 일관된 상태로 변화시키는 일의 단위이다.

Tmax는 로컬 트랜잭션과 전역 트랜잭션을 지원한다. 현재 Tmax 시스템은 중첩(nested) 트랜잭션을 지원

하지 않는다. 로컬 트랜잭션(Local Transaction Processing)은 하나의 자원 관리자(데이터베이스)가 참여

하는 트랜잭션이다.

전역 트랜잭션(Global Transaction Processing)은 둘 이상의 자원 관리자가 참여하는 트랜잭션이다. 전역

트랜잭션이란 하나 이상의 자원 관리자(데이터베이스)와 하나 이상의 물리적인 사이트가 하나의 논리적

인 단위로 참여하는 트랜잭션이다. Tmax 시스템에서는 모든 트랜잭션을 일단 전역 트랜잭션으로 간주한

다.

Tmax의 트랜잭션 처리는 ACID(Atomicity, Consistence, Isolation, Durability) 속성을 지키며 작업을 처리

한다. 트랜잭션 처리와 관련된 표준으로 X/Open DTP 모델의 TX 규격을 따른다.

ACID의 특성은 다음과 같다.

● 원자성(Atomicity)

일이 완전히 수행되거나 전혀 수행되지 않는(all or nothing) 2가지 경우만 존재해야 한다.

● 일관성(Consistency)

트랜잭션의 성공적인 수행결과를 하나의 일관된 상태에서 다른 일관된 상태의 공유자원에 갱신한다.

● 고립성(Isolation)

공유자원을 바꿀 때 트랜잭션의 결과가 commit이 될 때까지 트랜잭션 외부로 나타나지 않는다.

● 영속성(Durability)

하위 시스템이나 media 오류를 거친 트랜잭션 commit의 결과를 바꾼다. 성공적으로 완료된 트랜잭션

의 결과는 영구적으로 반영된다.

전역 트랜잭션은 둘 이상의 동종 및 이종의 데이터베이스가 관련된 전역 트랜잭션에서는 트랜잭션의 속

성을 보장하기 위해 2PC(Two-Phase Commit)를 사용한다. 2PC란 둘 이상의 데이터베이스가 연동할 때

ACID 속성을 완전히 보장하기 위해 2단계 처리(Prepare 단계, Commit 단계)를 하는 것을 말한다.

제6장 트랜잭션 45

Page 64: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● Prepare 단계

트랜잭션에 관련된 모든 데이터베이스에 트랜잭션을 처리할 준비가 되었는지 확인한다. 모든 데이터베

이스로부터 준비가 완료되면 신호를 전달한다.

● Commit 단계

모든 데이터베이스로부터 정상 신호를 받았으면 Commit을, 하나라도 비정상 신호를 받았다면 rollback

을 처리하여 전역 트랜잭션를 완료한다.

[그림 6.1] Two-phase commit (2PC) protocol

6.2. 분산 트랜잭션분산 트랜잭션을 처리할 경우 2단계 Commit을 지원하여 데이터 무결성(Integrity)을 보장하고 간단한 몇

가지 함수(tx_begin, tx_commit, tx_rollback 등)를 제공하여 전역 트랜잭션을 용이하게 한다. 또한 Multithread

방식의 트랜잭션 매니저를 제공하여 적은 자원 대비 효율성을 제공하고 동적 로깅으로 에러 발생하는 경

우 신속히 대응하므로 Recovery/Rollback에 의한 안정성을 보장한다. 모든 트랜잭션은 중앙에서 관리하

므로 트랜잭션에 대한 스케줄링이나 관리가 용이하다.

Tmax의 분산 트랜잭션 처리방식은 기본적으로 국제 표준인 X/Open의 모델(DTP)을 기반으로 한다. X/Open

의 모델은 Application Program(AP), Transaction Manager(TM), Resource Manager(RM), Communication

Resource Manager(CRM)로 구성되어 있다. X/OPEN DTP를 준수하는 표준 함수의 집합체인 X/OPEN

ATMI를 따른다. X/OPEN DTP를 준수하는 서로 다른 종류의 DBMS 사이에 발생하는 트랜잭션을 묶어서

처리한다.

46 Tmax Application Development Guide

Page 65: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

X/Open DTP의 구조는 다음과 같다.

[그림 6.2] X/Open DTP의 구조

● AP (Application Program) : 분산 트랜잭션의 Boundary 제공

● RM (Resource Manager) : 데이터베이스 등의 자원에 접근 제공

● TM (Transaction Manager) : 각 데이터베이스별 ID를 생성하여 진행을 관리하고 완료 및 실패하는 경우

복구 제공

● CRM (Communication Resource Manager ) : 분산 AP간의 통신 제어

● OSI-TP (Open System Interconnection-Transaction Processing) : 서로 다른 TM 영역과의 통신 담당

다음은 분산 트랜잭션의 처리과정에 대한 설명이다.

[그림 6.3] 분산 트랜잭션의 처리과정

제6장 트랜잭션 47

Page 66: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

트랜잭션은 tx_begin()을 호출해서 tx_commit() 또는 tx_rollback()이 호출이 되는 곳까지이다.

tx_begin()은 트랜잭션을 시작하게 하며, 이 함수를 부른 프로세스는 트랜잭션 게시자가 된다. 트랜잭션

게시자는 tx_commit() 또는 tx_rollback()를 호출함으로써 트랜잭션을 완결하여야 할 의무를 지닌다.

tx_begin()으로 시작하여 tx_commit() 또는 tx_rollback()으로 완결되는 하나의 트랜잭션에 포함되는 프로

세스들을 트랜잭션 참여자(participant)라 부르며, 트랜잭션 참여자들은 tpreturn()으로 반환하는 값에 의해

서 트랜잭션의 결과에 영향을 줄 수 있다. 트랜잭션 상태에서 tx_begin()으로 또다시 트랜잭션을 시작하려

고 할 경우 이는 실패되며, tperrno에 TPEPROTO가 설정된다. 하지만 원래 트랜잭션은 계속 수행되어야

한다.

트랜잭션 상태에 있는 클라이언트에서 tpcall()이나 tpacall() 호출할 경우 flags 인자를 TPNOTRAN으로 설

정하여 서버가 트랜잭션 참여에서 제외되도록 할 수 있다. 다시 말해, TPNOTRAN 플래그로 요청받는 서

버는 현재 진행 중인 트랜잭션의 결과에 영향을 줄 수 없다.

트랜잭션을 선언하는 방법은 개발자가 명시적으로 트랜잭션 관련 함수(예: tx_begin and tx_commit 등)를

직접 작성하는 Explicit 트랜잭션 방법과 서버에서 Tmax 환경파일의 SVRGROUP 절에서 데이터베이스

관련 항목을 설정하여 서비스를 내재적으로 트랜잭션으로 처리하는 Implicit 트랜잭션 방법이 있다.

DBMS와의 연동하는 경우 확인해야 할 사항은 다음과 같다.

● DBMS 벤더에서 제공하는 클라이언트 모듈의 설치를 확인한다.

● DBMS 설정 항목 중 데이터베이스 클라이언트에 대한 세션 수 제한 등의 사항을 확인한다.

● Tmax 서버 애플리케이션 작성에 필요한 개발도구 모듈이 필요하다

● XA / Non-XA 사용 여부를 확인하여 적절하게 구성한다. XA와 Non-XA는 DBMS와 Tmax 간의 데이터베

이스 접속 및 분산 트랜잭션 처리방법의 차이에 따라 나뉜다.

– XA

Tmax 환경파일 설정을 통해 DBMS와 접속이 이루어진다. XA의 트랜잭션 종결 또는 취소는 X/OPEN

ATMI 함수를 사용하고 TMS를 통해서 종결 또는 취소 완결이 이루어진다.

– Non-XA

사용자(개발자)의 ESQL 문을 통해서 DBMS 접속 및 트랜잭션의 종결 및 종결 취소가 처리된다.

6.2.1. XA 모드

XA 모드의 Tmax 시스템은 따로 트랜잭션 관리자(TMS)를 두어 트랜잭션 전체를 관리하도록 한다. XA 모

드로 운영되는 경우 모든 트랜잭션은 일단 전역 트랜잭션으로 간주되며 데이터의 무결성 확보를 위해

2PC(Two-Phase Commit)를 사용한다.

48 Tmax Application Development Guide

Page 67: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

XA 모드인 경우 따로 Tmax 환경파일에 자원 관리자와의 접속과 접속 해제를 위한 설정이 필요하며 트랜

잭션 관리는 Tmax API를 사용하여 처리하게 되고 분산환경의 전역 트랜잭션을 관리하는데 사용된다.

다음은 XA 모드의 프로그램 처리 순서이다.

[그림 6.4] XA 모드

tpsvrinit()/tpsvrdone() logic의 데이터베이스 접속/해제 logic은 별도로 필요하지 않다.

Non-XA와 동일하게 tmboot될 때 데이터베이스와 Connection을 맺고, 별도로 TMS라는 전역 트랙잭션의

종결, 종결 취소를 담당하는 프로세스도 데이터베이스와 Connection을 맺는다. 전역 트랙잭션 시작 및 종

결, 종결 취소 요청은 반드시 Tmax의 TX API를 호출하거나 혹은 Tmax 환경설정에 따라 처리한다.

XA 모드를 설정하기 위해서 Tmax 환경파일 중 SVRGROUP 절에서 DBMS와 연동할 서버 애플리케이션

이 포함될 서버 그룹 이름을 확인하고, 그에 대한 XA 설정을 한다.

다음은 XA 모드의 SVRGROUP 절을 설정하는 예제이다.

*SVRGROUP

svg1 NODENAME = tmax,

DBNAME = ORACLE,

OPENINFO = “ORACLE_XA+Acc=P/scott/tiger+SesTm=600”,

TMSNAME = svg1_tms

*SERVER

svr1 SVGNAME = svg1

참고

서버 그룹 환경설정에 대한 자세한 내용은 "Tmax Administration Guide"를 참고한다.

제6장 트랜잭션 49

Page 68: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

6.2.2. Non-XA 모드

Non-XA 모드의 Tmax 시스템은 자원 관리자에 직접 트랜잭션 명령을 내리는 것으로 분산 환경에서의 전

역 트랜잭션은 사용할 수 없다. Non-XA 모드는 간단한 작업이나 수행시간이 긴 Batch 작업을 하는 데 적

당하다.

Non-XA 모드의 경우 특별히 다른 설정을 필요로 하지 않으나 애플리케이션에서 따로 자원 관리자와 연결

을 맺고 트랜잭션을 선언해 주어야 한다.

Non-XA 모드는 네이티브 SQL과 정확하게 RDBMS에 연결된 트랜잭션 제어를 가진 서버 프로그램 방식

이다. Non-XA 모드는 Tmax에서 제공하는 트랜잭션을 사용할 수 없다. 또한 로컬 트랜잭션만 가능하다.

Non-XA 모드 서버 프로그램은 Batch 타입이나 간단한 서버 프로세스의 쿼리에 적합하다. Non-XA 모드에

서도 트랜잭션 범위와 제어를 설정할 수 있다. 하지만 Non-XA 모드의 사용자 애플리케이션과

RDBMS(direct connection) 사이에서만 가능하다. Tmax와는 전혀 관련이 없다.

Non-XA 모드는 XA 모드와 다음 2가지 다른점이 있다.

● 사용자 애플리케이션의 SQL을 사용함으로써 RDMBS와 연결하거나 연결을 끊는다.

● 서버 프로그램은 트랜잭션을 요청할 수 있지만 클라이언트 프로그램은 할 수 없다. Non-XA 서버 프로

그램의 경우 데이터베이스와 연결하거나 해제할 때 tpsvrinit()와 tpsvrdone() 루틴을 사용하는 것을 추천

한다.

다음은 Non-XA 모드의 프로그램 처리 순서이다.

[그림 6.5] Non-XA 모드

50 Tmax Application Development Guide

Page 69: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

1. tpsvrinit() logic에 DBMS에 접속할 수 있는 logic을 작성한다.

2. tpsvrdone() logic에 명시적으로 DBMS 접속을 rollback 및 release logic을 추가한다.

3. tmboot 또는 tmboot -S svrname 등을 통하여 Tmax 서버 애플리케이션을 부팅하면 DBMS와 Tmax 서

버 애플리케이션 프로세스 간에 연결이 맺어진다.

4. 서비스 logic에서는 이미 연결된 DBMS와의 연결을 통하여 ESQL을 통한 로컬 트랜잭션 전달 및 종결,

종결취소 요청을 통하여 트랜잭션 처리를 할 수 있다.

다음은 Non-XA 모드의 SVRGROUP 절을 설정하는 예제이다.

*SVRGROUP

svg1 NODENAME = tmax

*SERVER

svr1 SVGNAME = svg1

서버 프로그램의 XA 모드 설정 여부는 애플리케이션 디자인 단계에서 결정되어야 한다. 위에서 언급한 것

과 같이 XA 모드는 분산 환경에서 하나 이상의 데이터베이스를 처리하는 데 필요하다. 그러나 Non-XA 모

드는 간단한 Select 쿼리나 수행시간이 긴 Batch 서버 프로그램에 적당하다.

참고

트랜잭션 관련 함수에 대한 자세한 설명은 “9.8. 트랜잭션 관리”나 "Tmax Reference Guide"를 참고

한다.

6.3. 트랜잭션 관련 에러트랜잭션에 관련해서 발생할 수 있는 에러의 경우는 TX와 XA에서의 에러를 연관지어 감시해야 한다.

TX에 관련된 에러는 <usrinc/tx.h>에 정의되어 있고 XA에 관련된 에러는 사용하는 데이터베이스 벤더에

서 제공하고 있다. Oracle의 경우 <$ORACLE_HOME/rdbms/demo/xa.h>를 참고한다.

6.3.1. TX 에러

다음은 트랙잭션 에러에 대한 설명이다.

기능Tmax Retcode

트랜잭션을 지원하지 않는 모드일 때 발생하는 에러이다.TX_NOT_SUPPORTED(1)

정상적으로 처리된 경우 발생한다.TX_OK(0)

로컬 트랜잭션이 실행 중인 경우 발생한다.TX_OUTSIDE(-1)

제6장 트랜잭션 51

Page 70: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

기능Tmax Retcode

Commit을 할 수 없는 경우 발행하는 에러로 Rollback한다.TX_ROLLBACK(-2)

일부 Commit되고 일부 Rollback된 경우이다.TX_MIXED(-3)

정상적으로 완료하지 못한 경우 발생한다.TX_HAZARD(-4)

트랜잭션이 비정상적으로 호출된 경우 발생한다.TX_PROTOCOL_ERROR(-5)

데이터베이스 장애가 발생한 경우이다.TX_ERROR(-6)

심각한 장애가 발생한 경우이다.TX_FAIL(-7)

잘못된 인수를 받은 경우 발생한다.TX_EINVAL(-8)

트랜잭션이 데이터베이스에 독자적으로 수행된 경우 발생한다.TX_COMMITTED(-9)

트랜잭션은 Commit되었지만 새 트랜잭션은 시작할 수 없는 경우 발생

한다.

TX_NO_BEGIN(-10)

6.3.2. XA 에러

다음은 XA 에러에 대한 설명이다.

기능Tmax Retcode

정상적으로 처리된 경우 발생한다.XA_OK(0)

OPENINFO 절에서 설정된 Resource Manager 에러가 발생한 경우이

다.

XAER_RMERR(-3)

부여된 XID가 유효하지 않는 경우 발생한다.XAER_NOTA(-4)

잘못된 인수를 받았은 경우 발생한다.XAER_INVAL(-5)

부적절한 단계에서 호출된 경우 발생한다.XAER_PROTO(-6)

데이터베이스와 연결에 실패한 경우 발생한다.XAER_RMFAIL(-7)

이미 부여된 XID를 사용한 경우 발생한다.XAER_DUPID(-8)

트랜잭션 모드에서 벗어난 경우 발생한다.XAER_OUTSIDE(-9)

52 Tmax Application Development Guide

Page 71: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제7장 Multithread/Multicontext

3.8.15 버전 이후부터는 클라이언트 라이브러리에 Multithread/Multicontext를 위한 부분이 추가되었다. 본

장에서는 Multithread/Multicontext를 사용하기 위해서 설정해 주어야 할 내용에 대해 설명한다.

7.1. 프로그램 흐름Tmax 시스템은 Multithread/Multicontext에 대해 다음과 같은 사항들을 지원한다.

● Kernel-level packages를 지원한다. 스레드를 생성하고 소멸하는 등의 프로그램은 개발자가 logic을 고

려하여 작성하여야 한다.

● C로 작성된 Multithead 애플리케이션은 지원하나 Cobol로 작성된 Multithread 애플리케이션은 지원하

지 않는다.

● C로 작성된 Multicontext 애플리케이션은 지원하나 Cobol로 작성된 Multicontext 애플리케이션은 지원

하지 않는다.

7.1.1. Multithread

Multithread은 하나의 프로세스 안에 하나 이상의 실행 unit을 가지고 있는 것이다. 따라서 Tmax Multithread

애플리케이션에서는 같은 프로세스에서 동시에 여러 개의 서비스를 요청할 수 있다.

다음은 클라이언트 Multithread 애플리케이션 프로그램의 흐름에 관한 그림이다. 하나의 클라이언트 프로

세스는 동시에 2개의 서비스를 호출할 수 있게 된다.

[그림 7.1] Tmax 클라이언트 Multithread 애플리케이션

제7장 Multithread/Multicontext 53

Page 72: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

7.1.2. Multicontext

Multicontext는 하나의 클라이언트가 Tmax 시스템과 여러 개의 연결을 맺고 통신할 수 있도록 하는 프로

그램 기법이다.

다음은 클라이언트 Multicontext 애플리케이션 프로그램의 흐름에 관한 그림이다. 하나의 클라이언트는

여러 개의 context를 가지며 각 context는 Tmax 시스템과 각각 하나씩의 연결을 맺고 통신하게 된다. 따라

서 Multicontext를 사용하는 경우 Tmax 시스템은 하나의 사용자로 인식하게 된다.

[그림 7.2] Tmax 클라이언트 Multicontext 애플리케이션

7.2. 프로그램 구현Multithread 및 Multicontext를 사용하기 위해서는 다음의 3가지 루틴을 따라 프로그램을 작성해야 한다.

1. 시작 구문

2. 구현 구문

3. 종료 구문

참고

프로그램 구현을 위해 사용되는 각 함수에 대한 자세한 내용은 "Tmax Reference Guide"를 참고한

다.

7.2.1. 시작 구문

Multithread/Multicontext는 다음과 같은 함수로 시작할 수 있다.

● tpstart()

int tpstart (TPSTART_T *tpinfo )

Tmax 시스템과의 연결을 하는 함수로서 첫번째 인자인 TPSTART_T의 멤버인 flags를 TPMULTICON

TEXTS 또는 TPSINGLECONTEXT로 설정하여 Multicontext 또는 Singlecontext로 Tmax시스템과 연결

54 Tmax Application Development Guide

Page 73: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

할 수 있다. flags에 아무런 값도 설정하지 않는다면 TPSINGLECONTEXT가 기본적으로 설정되어 Sin

glecontext로 동작하게 된다.

또한 클라이언트는 한번 Singlecontext로 설정하면 계속해서 Singlecontext로만 동작하게 되고, Multicon

text로 설정하면 계속해서 Multicontext로 사용하게 된다.

● tpsetctxt()

int tpsetctxt(int ctxtid, long flags)

클라이언트의 현재 context를 알기 위해서는 tpgetctxt()라는 함수를 사용하여 반환되는 값으로 확인할

수 있다.

함수를 사용하여 하나의 클라이언트가 기존에 만들어진 다른 context를 현재 클라이언트에 할당할 수

있다. 많은 대부분의 ATMI 함수들은 per-context 기반으로 되어 있다. 클라이언트는 여러 개의 context

를 사용할 수 있지만 해당하는 순간에는 단 하나의 context만을 갖게 된다.

예를 들면 context1에서 tpacall()을 한 경우 다른 context를 사용했다 하더라도 tpgetrply()를 정상적으로

하기 위해서는 tpgetrply()를 하는 시점에서는 context1을 현재 context로 설정해 주어야 한다.

7.2.2. 구현 구문

Multithread/Multicontext는 ATMI 함수들을 사용하여 구현한다. ATMI 함수들을 사용할 때는 반드시 현재

context인지를 알고 사용해야 정상적으로 사용할 수 있다.

● 동기형 통신

Tmax 시스템과 클라이언트가 동기형 통신을 하는 경우 현재 context가 TPINVALIDCONTEXT가 아닌

경우 정상적으로 수행된다. TPINVALIDCONTEXT란 현재 context가 다른 스레드에 의해서 free된 경우

를 말한다.

예를 들어 하나의 thread1에서 tpstart()를 한 후 context1을 갖고, thread2에서는 tpsetctxt()로 context1

을 같이 사용하는 경우, thread1에서 처리를 끝내고 tpend()를 하면 context1도 메모리에서 삭제 되므로

thread2는 TPINVALIDCONTEXT를 갖게 된다.

또한 Multicontext가 아닌 경우 tpstart()를 하지 않고도 tpcall() 등의 API를 호출하면 자동으로 Tmax 시

스템과 연결을 하였으나 Multicontext인 경우는 반드시 tpstart()를 한 후에 tpcall() 등의 API를 명시적으

로 사용하여야 한다.

● 비동기형 통신

Multicontext를 사용하는 경우 같은 context를 같은 2개의 스레드가 있는 경우 하나의 스레드에서 tpacall()

후 다른 스레드에서 tpgetrply()를 사용하여 결과를 가져올 수 있다. 이렇게 사용할 때는 tpacall()이 반

드시 먼저 호출되어야 하므로 2개의 스레드 사이에 우선 순위가 반드시 명확한 경우에 사용해야 올바른

결과를 받아올 수 있으므로 조심해서 사용해야 한다.

동기형 통신과 마친가지로 TPINVALIDCONTEXT가 아닌 경우에 정상적으로 수행된다.

제7장 Multithread/Multicontext 55

Page 74: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 트랜잭션

하나의 스레드에서 트랜잭션을 시작하였다면, 그 스레드와 같은 context를 쓰는 스레드들은 트랜잭션

을 시작한 이후부터 하나의 트랜잭션이 된다. 이렇게 사용하는 경우도 비동기형 통신과 마찬가지로 우

선 순위가 명확한 경우에 사용한다. 또한 TPINVALIDCONTEXT가 아닌 경우에 정상적으로 수행된다.

7.2.3. 종료 구문

tpend() 함수를 통하여 Multithread/Multicontext를 종료하게 된다. 이 함수를 사용하지 않는 경우 context

와 해당하는 스레드에 대한 정보가 메모리에서 지워지지 않으므로 나중에 문제가 발생할 수 있으므로, 반

드시 context를 다 사용한 후에는 tpend()를 해 주어야 한다.

7.3. 프로그램 예제클라이언트 프로그램, 서버 프로그램, Makefile의 예제를 설명한다.

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

/*******************************************************************/

/* Multi-thread/Multi-context Sample Program */

/* */

/* TmaxSoft Co. / QA */

/* remarks: Tmax의 TOUPPER 서비스가 구동되어 있어야 함. */

/*******************************************************************/

#include <pthread.h>

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <netdb.h>

#include <sys/types.h>

#include <usrinc/atmi.h>

#define MAX_CTID_CNT 400 /* 최대 context 수*/

#define MAX_CALL 1

#define NUM_THREADS 2 /* 한번에 생성할 스레드 수*/

#define NUM_CONTEXTS 40 /* 한 스레드에서 생성할 context수*/

void *mythread(void *arg);

56 Tmax Application Development Guide

Page 75: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

int svcCall(char* svc, char* arg);

int newContext();

int altContext(int id);

int delContext();

#define CTID_EMPTY 0

#define CTID_OCCUPIED 1

#define THRERR (void *)-1

#define THRSUC (void *)1

extern int errno;

extern int _init_wthr_flag;

int thr_id;

TPSTART_T* tpinfo;

int main()

{

void *retVal;

char argData[100];

int tcnt = 0;

int scnt = 0;

pthread_t p_thread[NUM_THREADS];

memset(argData, 0x00, sizeof(argData));

strcpy(argData,"...mtmc test...");

if (tmaxreadenv("tmax.env","TMAX") == -1)

{

printf( "tmax read env failed\n" );

return FALSE;

}

tpinfo = (TPSTART_T *)tpalloc("TPSTART", NULL, 0);

if (tpinfo == NULL)

{

printf("[THR:%d]tpinfo tpalloc fail[%d][%s]\n",pthread_self(),

tperrno,tpstrerror(tperrno));

}

제7장 Multithread/Multicontext 57

Page 76: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#ifdef _MULTI_THREAD_TEST_

while(scnt<MAX_CALL)

{

for ( tcnt=0 ; tcnt<NUM_THREADS ; tcnt++)

{

if (pthread_create(&p_thread[tcnt], NULL, mythread,argData))

{

fprintf(stderr, "mythread start fail...[%d]\n", errno);

return FALSE;

}

}

for(tcnt=0 ; tcnt<NUM_THREADS ; tcnt++)

{

pthread_join(p_thread[tcnt], &retVal);

}

scnt++;

sleep(1);

}

#else

if (pthread_create(&p_thread[tcnt], NULL, mythread, argData))

{

fprintf(stderr, "mythread start fail...[%d]\n", errno);

return FALSE;

}

pthread_join(p_thread[tcnt], &retVal);

#endif

tpfree((char *)tpinfo);

return TRUE;

}

/**********************************************************/

/* Sub Process : myhread */

/**********************************************************/

void *mythread(void *arg)

{

int i,j,k;

58 Tmax Application Development Guide

Page 77: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

printf("[THR:%d] thread start\n",pthread_self());

#ifdef _MULTI_CONTXT_TEST_

tpinfo->flags = TPMULTICONTEXTS;

for(i=0;i<NUM_CONTEXTS/2;i++)

{

j=newContext();

k=newContext();

svcCall("TOUPPER",arg);

delContext();

altContext(j);

svcCall("TOUPPER",arg);

delContext();

}

#else

tpinfo->flags = TPSINGLECONTEXT;

newContext();

svcCall("TOUPPER",arg);

delContext();

#endif

printf("[THR:%d] thread finish\n",pthread_self());

return THRSUC;

}

/**********************************************************/

/* Sub Process : delContext */

/**********************************************************/

int delContext()

{

int i;

int id;

i = tpgetctxt(&id,TPNOFLAGS);

if (i < 0)

{

printf("\t[delContext]tpgetctxt fail[%d][%s]\n",

tperrno,tpstrerror(tperrno));

return -1;

제7장 Multithread/Multicontext 59

Page 78: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

tpend();

printf("\t[THR:%d][CTXT:%d]tpend.\n",pthread_self(),id);

return 1;

}

/**********************************************************/

/* Sub Process : newContext */

/**********************************************************/

int newContext()

{

int i;

int id;

i = tpstart(tpinfo);

if (i < 0)

{

printf("\t[newContext]tpstart fail[%d][%s]\n", tperrno,

tpstrerror(tperrno));

tpfree((char *)tpinfo);

return -1;

}

i = tpgetctxt(&id,TPNOFLAGS);

if (i < 0)

{

printf("\t[newContext]tpgetctxt fail[%d][%s]\n", tperrno,

tpstrerror(tperrno));

return -1;

}

return id;

}

/**********************************************************/

/* Sub Process : altContext */

/**********************************************************/

int altContext(int id)

{

int i;

int ret;

ret = tpsetctxt(id, TPNOFLAGS);

60 Tmax Application Development Guide

Page 79: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (ret < 0)

{

printf("\t[altContext]tpsetctxt fail[%d][%s]\n", tperrno,

tpstrerror(tperrno));

tpfree((char *)tpinfo);

return -1;

}

return 1;

}

/**********************************************************/

/* Sub Process : svcCall */

/**********************************************************/

int svcCall(char* svc, char* arg)

{

int ret;

long rlen;

char *sbuf, *rbuf;

int id;

ret=tpgetctxt(&id,TPNOFLAGS);

sbuf = (char *)tpalloc("STRING", NULL, 0);

if (sbuf == NULL)

{

printf("\t[svrCall]tpalloc error[%d][%s]\n",tperrno,

tpstrerror(tperrno));

return -1;

}

rbuf = (char *)tpalloc("STRING", NULL, 0);

if (rbuf == NULL)

{

printf("\t[svrCall]tpalloc error[%d][%s]\n",tperrno,

tpstrerror(tperrno));

return -1;

}

strcpy(sbuf, (char *)arg);

ret = tpcall(svc, (char *)sbuf, strlen(arg), (char **)&rbuf, (long *)&rlen,

TPNOFLAGS);

if (ret < 0)

{

제7장 Multithread/Multicontext 61

Page 80: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

printf("\t[svcCall]tpcall fail.[%d][%s]\n",tperrno,

tpstrerror(tperrno));

}

else

{

printf("\t[THR:%d][CTXT:%d]tpcall success.\n",pthread_self(),id);

}

tpfree((char *)sbuf);

tpfree((char *)rbuf);

}

/**********************************************************/

/* END */

/**********************************************************/

서버 프로그램

다음은 서버 프로그램 예제이다.

#include <stdio.h>

#include <usrinc/atmi.h>

TOUPPER(TPSVCINFO *msg)

{

int i;

printf("\tTOUPPER service is started!\n");

printf("\tINPUT : data=%s\n", msg->data);

for (i = 0; i < msg->len; i++)

msg->data[i] = toupper(msg->data[i]);

printf("\tOUTPUT: data=%s\n", msg->data);

tpreturn(TPSUCCESS,0,(char *)msg->data, 0,0);

}

Makefile

TARGET = $(COMP_TARGET)

APOBJS = $(TARGET).o

62 Tmax Application Development Guide

Page 81: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TMAXLIBD = $(TMAXDIR)/lib64

TMAXLIBS = -lcli

#TMAXLIBS =/home/ancestor/tmax/lib/libclid.a

#multi_thread / multi_context 일 경우

CFLAGS = -q64 -O -I$(TMAXDIR) -D_ MULTI_THREAD_TEST_ -D _MULTI_CONTXT_TEST_

#single_thread / multi_context 일 경우

CFLAGS = -q64 -O -I$(TMAXDIR) -D _MULTI_CONTXT_TEST_

LDFLAGS = -brtl

#

.SUFFIXES : .c

.c.o:

$(CC) $(CFLAGS) $(LDFLAGS) -c $<

#

# client compile

#

$(TARGET): $(APOBJS)

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

#

clean:

-rm -f *.o core $(TARGET)

제7장 Multithread/Multicontext 63

Page 82: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 83: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제8장 보안 시스템

Tmax는 시스템 접속 제어, 사용자 인증, 서비스 접근 제어의 3단계로 보안 기능을 제공하고 있다.

단계별 보안 기능 설정은 Tmax 환경파일의 DOMAIN 절에서 이루어진다. DOMAIN 절의 SECURITY 항목

의 설정에 따라 보안 설정이 가능하다.

설명설정값

시스템 접속 제어DOMAIN_SEC

사용자 인증USER_AUTH

서비스 접근 제어 보안ACL | MANDATORY

보안 기능이 적용하지 않음NO_SECURITY

8.1. 1단계 보안1단계 보안은 시스템 접속 보안으로 사용자 클라이언트가 가장 처음 Tmax 시스템에 연결할 때 이를 제한

한다.

Tmax 시스템에 대한 단일 암호를 설정하는 것으로, 실질적으로 DOMAIN 절의 OWNER 항목에 정의된 계

정에 대한 암호가 된다.

Tmax 시스템 설정 전에 암호는 mkpw 유틸리티로 설정되어야 한다. 이 보안이 설정되면, 클라이언트는

tpstart() 함수를 호출하는 경우 TPSTART_T 구조체의 dompwd 항목에 해당 암호를 등록한다. 암호가 맞

는 경우에만 클라이언트는 Tmax 시스템 접속에 성공한다. 설정값이 'NO_SECURITY' 인 경우는 dompwd

항목에 값을 설정할 필요가 없으며, NULL 값이 전달된다.

참고

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

다음은 1단계 보안을 사용하는 Tmax 환경파일의 예제이다.

#시스템 인증인 경우 SECURITY항목에 “DOMAIN_SEC”라고 설정한다.

*DOMAIN

res1 SHMKEY = 66999, MAXUSER=256,

SECURITY = “DOMAIN_SEC”, OWNER=tmax

*NODE

Tmax TMAXDIR = “/home/tmax”,

제8장 보안 시스템 65

Page 84: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

APPDIR = “/home/tmax/appbin”

*SVRGROUP

svg1 NODENAME = tmax

*SERVER

upper SVGNAME = svg1, RESTART=Y, MAXRSTART=3

*SERVICE

TOUPPER SVRNAME = upper

TOLOWER SVRNAME = upper, PRIO=100

다음은 TPSTART_T 구조체의 dompwd를 사용해서 암호를 설정하는 예이다.

...

main(int argc, char *argv[])

{

...

TPSTART_T *tpinfo;

...

if ((tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T)))

== NULL){

error processing routine

}

strcpy(tpinfo->dompwd, “tmax1234”);

if (tpstart(tpinfo) == -1){

error processing routine

}

...

}

8.2. 2단계 보안2단계 보안은 사용자 인증 보안으로 Tmax 시스템에 인증된 사용자만이 Tmax 시스템 접속을 허락한다.

클라이언트는 tpstart() 함수 호출로 Tmax 시스템에 접속하려고 할 때, TPSTART_T 구조체의 usrname과

usrpwd 항목을 등록한다.

usrname은 Tmax 시스템에 인증된 사용자 계정이며, usrpwd는 그에 대한 암호가 된다. 사용자 계정과 암

호는 설정 전에 mkpw 유틸리티에 의해 설정되어야 한다. 이러한 사용자 인증 보안이 설정되었다면, usrname

과 usrpwd가 Tmax 시스템에 인증된 것으로 확인되어야만 Tmax 시스템 접속에 성공한다.

사용자 인증 보안은 시스템 접속 제어 보안의 다음 단계로써 시스템 접속 제어 보안을 포함한다. 클라이언

트는 dompwd 항목도 바르게 등록하여야 한다. dompwd도 역시 mkpw에 의해 설정되어야 한다.

66 Tmax Application Development Guide

Page 85: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

주의

암호 파일은 반드시 Tmax 시스템 설정 전에 생성되고 갱신되어야 한다.

다음은 2단계 보안을 사용하는 Tmax 환경파일의 예제이다.

#사용자 인증인 경우 SECURITY항목에 “USER_AUTH”라고 설정한다.

*DOMAIN

res1 SHMKEY = 66999, MAXUSER=256,

SECURITY = “USER_AUTH”, OWNER=tmax

*NODE

tmax TMAXDIR = “/home/tmax”,

APPDIR = “/home/tmax/appbin”

*SVRGROUP

svg1 NODENAME = tmax

*SERVER

upper SVGNAME = svg1, RESTART=Y, AXRSTART=3

*SERVICE

TOUPPER SVRNAME = upper

TOLOWER SVRNAME = upper, PRIO=100

다음은 TPSTART_T 구조체의 usrname, usrpwd를 사용해서 암호를 설정하는 예이다.

...

main(int argc, char *argv[])

{

...

TPSTART_T *tpinfo;

if ((tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL,sizeof(TPSTART_T)))

== NULL){

error processing routine

}

strcpy(tpinfo->dompwd, “tmax1234”);

strcpy(tpinfo->usrname, “gdhong”) ;

strcpy(tpinfo->usrpwd, “hong0000”) ;

if (tpstart(tpinfo) == -1){

error processing routine

}

제8장 보안 시스템 67

Page 86: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

...

}

8.3. 3단계 보안3단계 보안은 서비스 접근 제어 기능으로서, Tmax 시스템에 접속한 사용자들 중에서 서비스별로 사용자

접근을 제한할 수 있는 기능이다.

서비스 접근 권한 제어는 사용자 그룹별로 이루어진다. 하나의 서비스는 그 서비스에 대해 접근 권한이 허

용된 그룹에 해당되는 사용자만이 접근이 가능하다. 따라서 이 기능을 사용하기 위해서는 그룹 파일을 만

들어 주어야 하며, 해당 그룹에 속하는 사용자 파일이 있어야 한다.

그리고 서비스별 접근 가능한 사용자 그룹을 지정해 주는 acl이라고 불리는 파일도 있어야 한다. 해당 기

능을 사용하기 위해서는 DOMAIN 절의 SECURITY 항목에 ACL 또는 MANDATORY 값을 설정해 주어야

한다.

3단계 보안 기능은 1단계 시스템 접속 제어, 2단계 사용자 인증 기능까지 모두 포함하고 있다. 따라서 SE

CURITY 항목이 ACL(또는 MANDATORY)로 설정되어 있는 경우 TPSTART_T 구조체에 dompwd, usrname,

usrpwd 필드를 사용하여 1, 2단계 인증을 거쳐 Tmax 시스템에 접속 성공한 경우에만 서비스 접근 권한이

가능해진다.

다음은 3단계 보안을 사용하는 Tmax 환경파일의 예제이다.

*DOMAIN

tmax1 SHMKEY=78350,

TPORTNO=8350, SECURITY=ACL, OWNER=starbj0, RACPORT=3155

*NODE

tmaxh4 TMAXDIR = "/EMC01/starbj81/tmax",

APPDIR = "/EMC01/starbj81/tmax/appbin"

tmaxh2 TMAXDIR = "/data1/starbj81/tmax",

APPDIR = "/data1/starbj81/tmax/appbin",

*SVRGROUP

svg1 NODENAME = "tmaxh4", COUSIN = "svg2", LOAD = 1

svg2 NODENAME = "tmaxh2", LOAD = 5

svg3 NODENAME = "tmaxh4"

*SERVER

svr01001 SVGNAME = svg1

svr_ucs1 SVGNAME = svg3, CLOPT = "-u 35", SVRTYPE=UCS, MIN=1, MAX=2

svr_ucs2 SVGNAME = svg3, CLOPT = "-u 37", SVRTYPE=UCS, MIN=1, MAX=2

68 Tmax Application Development Guide

Page 87: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

*SERVICE

TOUPPER1 SVRNAME = svr01001

TOUPPER2 SVRNAME = svr01001

LOGIN1 SVRNAME = svr_ucs1

LOGIN2 SVRNAME = svr_ucs2

<그룹 파일>

grp0:x:1001

grp1:x:1

grp2:x:2

grp3:x:3

grp4:x:4

grp5:x:5

<사용자 파일>

starbj0:1002:1

starbj1:1:1

starbj2:2:2

starbj3:3:3

starbj4:4:4

starbj5:5:5

<acl 파일>

TOUPPER1:SERVICE:1

TOUPPER3:SERVICE:5

TOUPPER5:SERVICE:5

<클라이언트 프로그램>

int main()

{

...

strcpy(tpinfo->usrname, "starbj1");

strcpy(tpinfo->dompwd, "starbj0");

strcpy(tpinfo->usrpwd, "starbj1");

...

if(tpcall("TOUPPER1", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){

error routine..

}

제8장 보안 시스템 69

Page 88: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

참고

각 파일(그룹, 사용자, acl) 에 대한 생성 방법 및 자세한 설명은 “Tmax Reference Guide”의 mkgrp,

mkpw, mkacl 항목을 참고한다.

70 Tmax Application Development Guide

Page 89: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제9장 클라이언트 API

다음은 클라이언트에서 사용하는 함수에 대한 설명이다.

● 연결 및 해제

기 능함수

클라이언트가 Tmax 시스템에 연결하는 함수이다.tpstart

클라이언트에서 Tmax 시스템과의 연결을 해제하는 함수이다.tpend

● 동기형 통신

기 능함수

클라이언트가 서비스를 요청하고 응답이 올 때까지 기다리는 동기형 통신 함

수이다.

tpcall

● 비동기 통신

기 능함수

클라이언트에서 서비스를 요청하고 바로 반환하는 함수이다.tpacall

tpacall에 의해서 보낸 요청에 대한 응답 버퍼의 데이터를 받는 함수이다.tpgetrply

서버/클라이언트의 응답을 취소하는 함수이다.tpcancel

● 대화형 통신

기 능함수

연결을 설정하고 통신을 시작하는 함수이다.tpconnect

연결 컨트롤을 가진 곳에서 메시지를 보낼 때 사용하는 함수이다.tpsend

연결이 설정된 후 연결 컨트롤을 가지지 않은 쪽에서 데이터를 받고자 할 때

사용하는 함수이다.

tprecv

서버/클라이언트에서 대화형 통신 연결 종료하는 함수이다.tpdiscon

● 비요청 메시지 처리

제9장 클라이언트 API 71

Page 90: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

기 능함수

클라이언트에서 사용되는 함수로 비요청 수신 메시지를 처리하는 루틴 설정

하는 함수이다.

tpsetunsol

클라이언트의 요청 없이 일방적으로 전달받은 메시지를 처리하는 함수이다.tpgetunsol

● 타임아웃 변경

기 능함수

서버/클라이언트에서 사용되는 함수로 블로킹 타임아웃 시간을 설정하는 함

수이다.

tpset_timeout

● 버퍼 관리

기 능함수

서버/클라이언트에서 버퍼를 할당하는 함수이다.tpalloc

서버/클라이언트에서 버퍼를 재할당하는 함수이다.tprealloc

서버/클라이언트에서 버퍼에 할당된 메모리를 해제하는 함수이다.tpfree

서버/클라이언트에서 사용되는 함수로 버퍼의 유형 및 하위 유형에 대한 정

보를 제공한다.

tptypes

● 트랜잭션 관리

설명함수

서버/클라이언트에서 사용하는 함수로 트랜잭션을 시작한다.tx_begin

서버/클라이언트에서 사용하는 함수로 트랜잭션을 commit한다.tx_commit

서버/클라이언트에서 사용하는 함수로 트랜잭션을 rollback한다.tx_rollback

서버/클라이언트에서 transaction_timeout 설정 함수로 transaction_timeout

특성을 타임아웃 값으로 설정한다.

tx_set_transaction_time

out

서버/클라이언트에서 transaction_control 특성을 컨트롤값으로 설정하는 함

수이다.

tx_set_transaction_con

trol

서버/클라이언트에서 commit_return 특성을 설정하는 함수로 when_return값

으로 반환한다.

tx_set_commit_return

서버/클라이언트에서 전역 트랜잭션 정보를 반환하는 함수이다.tx_info

● RQ 시스템

기 능함수

서버/클라이언트에서 RQ에 데이터를 저장하는 함수이다.tpenq

72 Tmax Application Development Guide

Page 91: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

기 능함수

서버/클라이언트에서 RQ로부터 데이터를 로드하는 함수이다.tpdeq

서버/클라이언트에서 사용되는 함수로 RQ에 저장된 데이터의 통계를 요청

하는 함수이다.

tpqstat

서버/클라이언트에서 tpdeq로 RQ에서 데이터를 읽은 경우, 해당 데이터의

서비스명을 알고자 할 때 사용하는 함수이다.

tpextsvcname

● 이벤트를 활용하는 API

기 능함수

서버/클라이언트에서 사용되는 함수로 특정 사건의 메시지에 대한 요청을 등

록한다.

tpsubscribe

서버/클라이언트에서 사용하는 함수로 특정 사건의 메시지에 대한 등록을 해

제한다

tpunsubscribe

서버/클라이언트에서 특정 사건을 발생시키고 메시지를 전달하는 함수이다.tppost

● 브로드 캐스트/멀티 캐스트

기 능함수

클라이언트나 서버가 다른 클라이언트에게로 비요청 메시지를 보내고자 할

때 사용하는 함수이다.

tpbroadcast

● Windows 환경 프로그래밍

– tmaxmt.dll

기 능함수

Tmax 시스템에 접속하여 서비스를 요청하고 결과를 받아 다시 원하는 Window

의 프로시저로 넘긴 후 연결을 종료하는 함수이다.

WinTmaxAcall

Tmax 시스템에 접속하여 서비스를 요청하며 응답은 지정한 콜백 함수로 받

는 함수이다.

WinTmaxAcall2

– WinTmax.dll

기 능함수

메시지를 처리하는 스레드를 만들고 사용 메모리를 초기화하는 함수이다.WinTmaxStart

메시지를 처리하는 스레드를 종료하고 사용 메모리를 해제하는 함수이다.WinTmaxEnd

Tmax 시스템에서 도착한 데이터를 보낼 Window와 메시지 번호를 지정하는

함수이다.

WinTmaxSetContext

제9장 클라이언트 API 73

Page 92: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

기 능함수

클라이언트에서 서비스를 호출하고 즉시 다른 일을 할 수 있도록 하는 함수

이다.

WinTmaxSend

● Multithread/Multicontext API

기 능함수

현재 context를 반환하는 함수이다.tpgetctxt

현재 context를 설정하는 함수이다.tpsetctxt

참고

함수와 관련 함수에 대한 자세한 사항은 Tmax 안내서 중 "Tmax Reference Guide"를 참고한다.

9.1. 연결 및 해제Tmax와 연결 및 해제하는데 사용하는 함수에 대한 설명이다.

9.1.1. tpstart

클라이언트가 Tmax 시스템에 연결하는 함수이다. 클라이언트는 서비스 요청이나 트랜잭션 처리 등의

ATMI 함수들을 사용하기 전에, tpstart()를 이용하여 Tmax 시스템에 연결해야 한다. tpstart()를 호출하기

전에 다른 ATMI 함수들(tpalloc()이나 tpcall() 등)이 먼저 호출되면, 내부적으로 tpstart(NULL) 함수가 호출

된다.

tpstart()가 성공적으로 반환되면 클라이언트는 최초 서비스 요청이나 트랜잭션 정의 등을 할 수 있다. 성

공적으로 Tmax 시스템에 연결이 된 후에 다시 tpstart()가 호출되면 TPEPROTO가 발생한다.

● 프로토타입

#include <atmi.h>

int tpstart (TPSTART_T *tpinfo )

● 파라미터

tpinfo는 TPSTART_T라는 구조체에 대한 포인터(pointer)이다. 이 구조체는 TPSTART라는 버퍼 타입을

사용하며, tpstart()를 호출하기 전에 반드시 tpalloc()에 의해 할당되어야 한다. 할당된 버퍼는 tpstart()

함수 호출 후에 tpfree()를 통해 제거되는 것이 바람직하다. 클라이언트는 시스템 연결할 때에 구조체 형

식인 tpinfo 인수를 통해 필요한 정보를 넘긴다. tpinfo 인수는 클라이언트 정보, 비요청 메시지 처리 여

부, 보안 정보(source 환경파일의 SECURITY 항목 참고)등을 포함한다.

74 Tmax Application Development Guide

Page 93: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpinfo로서 NULL값을 사용할 수 있다. NULL인 경우, cltid, dompwd, usrname, usrpwd는 기본값으로 길

이 0인 string이 주어짐으로써 Tmax 보안 특징을 사용하지 않게 되고 flags는 선택되지 않는다.

다음은 TPSTART_T 구조체의 구성이다.

char cltid[MAXTIDENT+2]; /*클라이언트 이름 (tpbroadcast())*/

char dompwd[MAX_PASSWD_LENGTH+2]; /*시스템 접속 보안에 대한 암호*/

char usrname[MAXTIDENT+2]; /*사용자 인증 보안에 대한 계정*/

char usrpwd[MAX_PASSWD_LENGTH+2]; /*사용자 인증 보안에 대한 암호*/

int flags; /*비요청 메시지 유형과 시스템 접근 방법결정*/

설명멤버

최대길이 30자까지 가능한 NULL로 끝나는 문자열이다.cltid

cltid는 애플리케이션에서 정의한 이름이고, tpbroadcast()에서 비요청 메시

지를 보낼 클라이언트를 지정하기 위해 사용된다.

Tmax에서 제공하는 보안 단계 중 시스템 접속 제어를 위해 사용된다. Tmax

환경파일 중 DOMAIN 절의 OWNER 항목에 설정된 계정에 대한 암호를 등

록한다.

dompwd

Tmax에서 제공하는 보안 단계 중 사용자 인증을 위해 사용된다. usrname

은 Tmax 시스템의 passwd 파일에 등록된 계정 이름이다.

usrname

usrname에 해당하는 암호이다. 사용자 인증 보안이 설정된 경우 클라이언

트는 usrname과 usrpwd를 등록하여야만 Tmax 시스템에 연결되고 시스템

에서 제공하는 서비스를 받을 수 있다.

usrpwd

보안 설정에 대한 내용은 source 환경파일의 DOMAIN 절에 있는 SECURITY

항목을 참고한다.

비요청(notification) 메시지 처리와 시스템 접근 방법을 결정하기 위해 사용

된다. 비요청 메시지 처리를 위해 사용할 수 있는 flags이다.

flags

비요청 메시지 처리를 위해 사용할 수 있는 flags 값은 다음과 같다.

설명설정값

비요청 메시지를 수신한다.TPUNSOL_POLL

비요청 메시지를 수신할 함수를 지정한다. (자세한 내용은 “9.5.1. tpsetunsol”

을 참고한다. )

TPUNSOL_HND

비요청 메시지를 무시한다. 기본값이 정의 되지 않으면 TPUNSOL_IGN이

설정된다.

TPUNSOL_IGN

tpstart() 함수는 Tmax 시스템과 연결하기 위해서는 Tmax 시스템이 설치된 서버의 IP와 포트번호를 알

아야 한다. 이런 정보를 환경변수로 등록하여 사용한다.

제9장 클라이언트 API 75

Page 94: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음은 환경변수로 등록하여 사용하는 변수에 대한 설명이다.

설명변수명

클라이언트가 연결될 노드의 IP주소이다. 클라이언트가 tpstart() 호출할 경

우에 내부적으로 서버 시스템에 연결되는데 사용된다.

TMAX_HOST_ADDR

- 클라이언트가 연결될 노드의 포트 번호를 지정한다. 클라이언트가 tpstart()

호출할 경우에 내부적으로 서버 시스템과의 연결을 위해

TMAX_HOST_PORT

TMAX_HOST_ADDR과 함께 사용된다. Tmax 환경파일에 TPORTNO로 정

의된 값이어야 한다.

- 클라이언트와 서버가 같은 노드에 존재하는 경우 TCP/IP 소켓을 이용하

지 않고 도메인 소켓을 이용하여 더 효과적인 처리를 할 수 있다. 이 경우에

는 Tmax 환경 파일에 TPORTNO로 정의된 값 대신에 PATHDIR을 지정하

면 된다.

- Tmax 환경파일의 DOMAIN 절과 NODE 절의 TPORTNO 항목을 참고한

다.

TMAX_HOST_ADDR주소의 노드에 장애가 생겼을 경우에 대비하여 또 다

른 Tmax 시스템 노드를 지정한다. 클라이언트는 TMAX_HOST_ADDR 주

TMAX_BACKUP_ADDR

소의 노드로 연결을 시도하고, 그 노드와의 연결에 실패하면

TMAX_BACKUP_ADDR 주소의 노드로 접속을 시도한다.

TMAX_BACKUP_ADDR 주소의 노드에 대한 Tmax 시스템 포트 번호이다.TMAX_BACKUP_PORT

Tmax 시스템 연결할 때의 타임아웃 시간이다. (micro-seconds resolution

제공된다. 예:3.5 )

TMAX_CONNECT_TIME

OUT

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

함수 호출에 성공한 경우0 또는 1

(primary host에 0을 반환하고 backup host에 1을 반환한다.)

● 오류

tpstart()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

76 Tmax Application Development Guide

Page 95: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

인수가 유효하지 않다. 예를 들어 tpinfo가 NULL이나 TPSTART_T 구조체

에 대한 포인터가 아니다.

[TPEINVAL]

tpinfo가 TPSTART_T 구조체에 대한 포인터가 아니다.[TPEITYPE]

tpstart()가 부적절한 곳에서 호출되었다. 예를 들어, 서버 프로그램에서 사

용되었거나 이미 연결된 상황에서 재호출된 경우에 발생한다

[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하거나 환경변수 설정이 잘못된 경우이다.[TPEOS]

예를 들어 TMAX_HOST_ADDR나TMAX_HOST_PORT가 잘못 설정되어

연결이 실패한 경우에 발생한다.

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret;

char *buf;

long len;

TPSTART_T *tpinfo;

tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T));

if (tpinfo==NULL) { error processing }

strcpy(tpinfo->cltname, “cli1”);

strcpy(tpinfo->usrname, “navis”);

strcpy(tpinfo->dompwd, “tmax”);

tpinfo->flags = TPUNSOL_HND;

ret=tpstart(tpinfo);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

ret=tpcall(“SERVICE”, buf, 20, &buf, &len, TPNOFLAGS);

if (ret==-1) { error processing }

data process....

tpfree((char *) buf);

tpend();

}

● 관련 함수

tpend()

제9장 클라이언트 API 77

Page 96: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.1.2. tpend

클라이언트에서 Tmax 시스템과의 연결을 해제하는 함수이다.

클라이언트가 트랜잭션 모드에 있다면, 트랜잭션은 자동으로 rollback된다. tpend()가 성공적으로 반환하

면, 호출자는 더 이상 어떤 프로그램과도 통신할 수 없고, 어떤 트랜잭션에도 참여할 수 없다. 또한 유지되

고 있는 대화형 연결은 즉시 종료된다. tpend()가 한 번 이상 호출된다면(이미 Tmax시스템과 연결이 해제

된 후에 또 다시 호출된다면) -1값을 반환하지만 시스템에는 아무런 작동도 하지 않는다.

● 프로토타입

# include <atmi.h>

int tpend (void)

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpend()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

tpend()가 부적절한 상황에서 호출되었다.[TPEPROTO]

예를 들어, 호출자가 서버인 경우나 혹은 연결이 해제된 후에 다시 호출된 경

우에 발생한다.

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

char *sndbuf, *rcvbuf;

long rcvlen, sndlen;

int ret;

78 Tmax Application Development Guide

Page 97: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tpstart((TPSTART_T *)NULL)

if (ret==-1) {error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0)

if (buf=NULL) { error processing }

data process …

ret=tpcall(“SERVICE”, buf, 0, &buf, &len, TPNOFLAGS);

if (ret==-1) { error processing }

data process …

printf(“ data: %s\n”, buf);

tpfree((char *)buf);

tpend();

}

● 관련 함수

tpstart()

9.2. 동기형 통신동기 통신할 때 사용하는 함수에 대해 설명한다.

9.2.1. tpcall

서버/클라이언트의 동기형 서비스 요청 송수신 함수로 동기형 통신으로 svc로 명명된 서비스에게 서비스

요청을 송신하고 이에 대한 응답을 수신한다. tpacall() 호출 후 연속적으로 tpgetrply()를 호출하는 것과

동일하다.

● 프로토타입

# include <atmi.h>

int tpcall (char *svc, char *idata, long ilen, char **odata, long *olen,

long flags)

● 파라미터

제9장 클라이언트 API 79

Page 98: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

호출되는 서비스 이름을 의미한다. 이 서비스는 Tmax 응용 서버 프로그램에

서 제공되고 있는 것이어야 한다.

svc

서비스 요청의 데이터에 대한 포인터이다. 반드시 이전에 tpalloc()에 의해 할

당된 버퍼이어야 한다.

idata

idata의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.

송신할 데이터의 길이를 지정한다.ilen

- idata가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 버퍼 유형(STRING,

STRUCT, X_COMMON, X_C_TYPE)인 경우 ilen은 무시되고 기본으로 0을

사용한다.

- idata가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET,

CARRAY, MULTI STRUCTURE)인 경우 ilen은 0이 될 수 없다.

- idata가 NULL인 경우 ilen은 무시된다.

*odata는 수신될 응답 버퍼에 대한 포인터로 버퍼는 *olen으로 반환된 길이

만큼의 응답이 수신된다.

*odata

*odata는 반드시 이전에 tpalloc()에 의해 할당된 버퍼이어야 한다. 동일한 버

퍼가 송신과 수신 역할을 모두 한다면, *odata는 idata의 주소로 설정되어야

한다.

응답 버퍼의 크기 변경 여부를 결정하기 위해서, tpcall()이 완료되기 전에

*odata로 할당된 응답 버퍼의 크기와 수신된 *olen을 비교한다. 수신된 *olen

이 더 크다면 할당된 응답 버퍼의 크기가 증가되며, 그렇지 않으면 크기는 변

경되지 않는다.

idata와 *odata로 동일한 버퍼가 사용되어 tpcall()이 호출된 경우, *odata가

변경되었다면 idata가 가리키는 주소는 더 이상 유효하지 않다. *odata는 수

신 데이터가 커서 변경 될 수도 있고, 이 외에 다른 이유에 의해서도 변경될

수 있다.

*olen이 0으로 반환되었다면, 어떤 데이터도 수신되지 않고 *odata와 *odata

가 가리키는 버퍼 모두 아무런 변화가 없다.

*odata나 olen이 NULL이 되는 것은 에러이다 .

*odata에 반환될 응답에 대한 길이이다.*olen

호출할 때 사용되는 옵션으로 어떤 방식으로 통신할 것인지를 지정한다.flags

80 Tmax Application Development Guide

Page 99: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

flags로는 다음 값들을 사용할 수 있다.

설명설정값

tpcall() 함수 호출자가 트랜잭션 모드 상태에서 이 플래그를 설정하여 svc 서

비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된다.

TPNOTRAN

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpcall() 함

수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TPNOTRAN으로

설정해야 한다. 트랜잭션 모드 내에서의 tpcall() 함수 호출할 때, TPNOTRAN

으로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다.

TPNOTRAN으로 호출된 서비스가 실패하였을 경우, 호출자의 트랜잭션에는

영향을 미치지 않는다.

TPNOBLOCK 플래그를 설정한 상태에서, 내부 버퍼가 송신할 메시지들로

가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패한

다. TPNOCHANGE은 tpcall()의 Tx 부분에만 적용된다.

TPNOCHANGE

TPNOBLOCK 플래그 설정 없이 tpcall()호출할 때, 블로킹 상황이 발생하면

함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블

로킹 타임아웃)이 발생할 때까지 대기한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기

다리겠다는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpcall()을 한 경우에는

여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 내부에서 시그널 인

터럽트가 발생하여 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실

행된다.

TPSIGRSTRT

TPSIGRSTRT 플래그가 설정되지 않은 경우 시그널 인터럽트가 발생하였다

면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpcall()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

제9장 클라이언트 API 81

Page 100: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

인수가 유효하지 않거나 플래그가 유효하지 않다.[TPEINVAL]

예를 들어, svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가

리킨다.

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다.[TPEITYPE]

[TPEOTYPE] – 수신된 응답버퍼의 유형이나 하위 유형이 호출자가 알지 못하는 유형이다.

– 플래그가 TPNOCHANGE로 설정되었는데 *odata가 가리키는 버퍼의 유형

및 하위 유형이 수신된 응답 버퍼의 유형 및 하위 유형과 맞지 않은 경우

*odata의 내용과 *olen은 모두 변경되지 않는다.

– 호출자가 트랜잭션 모드에서 서비스를 요청하였다면, 그 트랜잭션은 응답

이 무시되었기 때문에 rollback된다.

트랜잭션 서비스를 호출할 때 데이터 베이스에 문제가 발생하여 xa_start가

실패하였다.

[TPETRAN]

타임아웃이 발생하였다.[TPETIME]

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그

트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK

어느 것도 지정되지 않았다면, 블로킹 타임아웃이 발생한다. 이 두 경우에,

*odata의 내용과 *olen은 변경되지 않는다.

트랜잭션 타임아웃이 발생하였다면, 새로운 서비스 요청을 송신한다거나 응

답을 대기하는 일은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패하

게 된다.

서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션에서 에러

가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신 되었다

면, 그 내용들은 *odata가 가리키는 버퍼를 통하여 사용될 수 있다.

[TPESVCFAIL]

트랜잭션 타임아웃이 발생해서 트랜잭션이 rollback되기 전에 다른 통신들이

시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할

수도 있다. 통신이 정상적으로 수행되기 위해서는 TPNOTRAN이 설정되어

야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션을 완료할

때에 모두 rollback된다.

[TPESVCERR] – 서비스 루틴 수행중이나 tpreturn()(예를 들어, 잘못된 인수가 전달된 경우)

수행 중에 에러가 발생하였다. 에러가 발생하면 어떠한 응답 데이터도 반

환되지 않고 *odata의 내용 또는 *olen 모두 변경되지 않는다.

82 Tmax Application Development Guide

Page 101: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

– tpalloc로 생성되지 않은 버퍼를 사용하였거나 할당된 버퍼의 Tmax 헤더가

잘못된 포인터(memcpy 등)의 영향을 받았거나, tpacall이나 tpconnect의

cd로 반환하였을 경우, Recv모드에서 서비스가 유효하지 않은 대화형 내

용일 경우에 발생한다. 단, tpreturn을 시도하면 클라이언트는 TPESVCERR

를 받게 된다.

– 클라이언트가 강제로 대화를 해제하여 서비스 프로그램이 TPEV_DISCOMN

을 받는 것과 같은 TPEV_DISCOMN 이벤트가 발생하였을 경우, 클라이언

트는 서비스의 tpreturn에 TPESVCERR tperrno를 전송 받게 된다.

– 함수 호출자가 트랜잭션 모드에 있을 경우, 트랜잭션 타임아웃이 발생하기

전까지는, 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그

러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 이들

이 제대로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의

트랜잭션 모드에서 수행된 작업들은 트랜잭션 완료 시에 모두 rollback된

다.

– Tmax 환경파일에 서비스별로 SVCTIMEOUT을 설정할 수 있는데 서비스

의 수행 시간이 이 시간을 초과하게 되면 서비스는 수행을 멈추고

TPESVCERR를 반환한다. SVCTIMEOUT이 발생하면 tpsvctimeout()을 불

러주는데 이 함수내에서 버퍼해제, 로깅 작업 등 업무별로 적당한 작업을

할 수 있다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

tpcall()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret;

char *sndbuf, *rcvbuf;

long sndlen, rcvlen;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

제9장 클라이언트 API 83

Page 102: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

sndbuf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (sndbuf==NULL) {error processing };

rcvbuf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (rcvbuf==NULL) {error processing };

data process....

sndbuf=strlen(sndbuf);

ret=tpcall(”SERVICE”, sndbuf, sndlen, &rcvbuf, &rcvlen, TPNOCHANGE);

if (ret==-1) { error processing }

data process....

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

9.3. 비동기 통신비동기 통신에서 사용하는 함수에 대해 설명한다.

9.3.1. tpacall

서버/클라이언트에서 비동기 서비스 요청을 송신하는 함수다.

tpacall() 함수는 svc로 명명된 서비스에게 서비스 요청 메시지를 송신한다. 비동기 통신으로 메시지를 송

신한 후에 결과를 받을 때까지 기다리지 않고 바로 반환된다. 결과는 tpgetrply() 함수를 이용하여 응답을

받을 수도 있고, 또는 tpcancel() 함수를 이용하여 응답을 취소할 수 있다.

● 프로토타입

# include <atmi.h>

int tpacall (char *svc, char *data, long len, long flags)

● 파라미터

설명파라미터

호출되는 서비스 이름을 의미한다. 이 서비스는 Tmax 응용 서버 프로그램에

서 제공되고 있는 것이어야 한다.

svc

NULL 값인 경우를 제외하고, 반드시 tpalloc()으로 할당된 버퍼에 대한 포인

터이어야 한다.

data

송신되는 데이터 길이다.len

84 Tmax Application Development Guide

Page 103: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

- data가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 버퍼 유형(STRING,

STRUCT, X_COMMON, X_C_TYPE)이라면 len은 무시되고 보통 0이 사용

된다.

- data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET,

CARRAY, MULTI STRUCTURE)이라면 len은 0이 될 수 없다.

- data가 NULL이라면 len은 무시되고 데이터 없이 서비스 요청이 송신된다.

data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.

서비스 요청이 트랜잭션 모드에서 송신되었다면, 해당 응답들은 결과적으로

반드시 수신되어야 한다.

호출할 때 사용되는 옵션으로 호출 모드를 결정한다.flags

flags로 사용 가능한 값은 다음과 같다.

설명설정값

플래그없이 tpacall() 함수가 사용되었다면, svc에 호출된 서비스가 없거나 잘

못된 결과가 반환되었어도 정상적인 결과가 반환된다.

TPBLOCK

tpgetrply() 함수를 호출할 때 에러가 반환 된다. TPBLOCK 플래그를 이용해

tpacall() 함수 호출할 경우 서비스 상태의 정상 여부를 확인 할 수 있다.

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpacall()함

수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TPNOTRAN으로

설정해야 한다.

TPNOTRAN

tpacall() 함수 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc

서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된

다. 트랜잭션 모드 내에서의 tpacall()함수를 호출할 때, TPNOTRAN로 설정

되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다.

TPNOTRAN으로 호출된 서비스가 실패하였을 경우, 호출자의 트랜잭션에는

영향을 미치지 않는다.

tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과

는 나중에 tpacall() 함수에서 반환한 구별자를 이용하여 tpgetrply() 함수로 결

TPNOREPLY

과를 수신한다. flags가 TPNOREPLY로 설정하면 서비스에 대한 응답을 받

지 않는겠다고 설정된다. TPNOREPLY로 설정하면 tpacall() 함수는 서비스

가 정상적으로 호출되면 0을 반환한다.

함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN 플래그

와 함께 설정해야만 TPNOREPLY 플래그를 사용할 수 있다.

제9장 클라이언트 API 85

Page 104: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

TPNOREPLY 플래그인 경우 서비스 상태의 정상 여부를 체크하기 위해서는

TPBLOCK 플래그를 함께 설정해야 한다. TPBLOCK 플래그를 설정하지 않

으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다.

내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황

을 만나면 서비스 요청은 실패하도록 설정하는 플래그이다.

TPNOBLOCK

TPNOBLOCK 플래그 설정없이 tpacall() 함수가 호출된 경우 블로킹 상황이

발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아

웃 또는 블로킹 타임아웃)이 발생할 때까지 대기한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기하도록 설정하는 플래그이다. 트랜잭션 타임아웃 내에서 tpacall()을 한 경

우에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용하는 플래그이다.TPSIGRSTRT

시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT

가 설정되지 않은 상태에서 신호 인터럽트가 발생하였다면, 함수는 실패하고

tperrno에 TPGOTSIG가 설정된다

● 반환값

설명반환값

함수 호출에 성공한 경우구별자(descriptor)

(반환된 구별자는 송신된 서비스 요청에 대한 응답을 수신하는데 사용된다.)

함수 호출이 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpacall()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않은 경우 발생한다.[TPEINVAL]

예를 들어, svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가

리키거나, 또는 플래그가 유효하지 않다.

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

86 Tmax Application Development Guide

Page 105: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우

사용된 구조체가 SDLFILE 파일에 선언되어 있지 않은 경우 발생한다.

[TPEITYPE]

처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에, 호

출자의 서비스 요청이 송신되지 않은 경우 발생한다.

[TPELIMIT]

타임아웃이 발생하였다.[TPETIME]

-함수 호출자가 트랜잭션 모드인 경우 : 트랜잭션 타임아웃이 발생한 것이며

트랜잭션은 rollback된다.

- 함수 호출자가 트랜잭션 모드가 아닌 경우 : TPNOTIME이나 TPNOBLOCK

이 모두 설정되지 않은 상황에서 블로킹 타임아웃이 발생한다.

트랜잭션 타임아웃이 발생하는 경우 트랜잭션이 rollback될 때까지 새로운

서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두

[TPETIME] 에러로 실패한다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

트랜잭션 모드에서의 TPNOREPLY 서비스 호출할 때 TPNOTRAN 플래그를

설정하지 않는 경우 등 부적절한 상황에서 발생한다.

[TPEPROTO]

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

char *buf;

int ret,cd;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret<0) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing }

data process…

cd = tpacall(“SERVICE”, sndbuf, 20, TPNOTIME);

if (cd<0) {error processing }

data process…

ret=tpgetrply(&cd, (char **)&buf, &len, TPNOTIME);

제9장 클라이언트 API 87

Page 106: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (ret<0) { error processing }

data process....

tpfree((char *)buf);

tpend();

}

● 관련 함수

tpalloc(), tpacall(), tpgetrply(), tpreturn()

9.3.2. tpgetrply

서버/클라이언트에서 비동기적으로 요청한 서비스에 대한 응답을 수신하는 함수로 tpacall()로 요청한 서

비스에 대한 응답을 수신한다.

● 프로토타입

# include <atmi.h>

int tpgetrply(int *cd, char **data, long *len, long flags)

● 파라미터

설명파라미터

tpacall()에 의해 반환된 호출 구별자를 가리킨다. 보통 cd와 일치하는 응답이

수신되거나 또는 타임아웃이 발생할 때까지 기다린다. 일반적으로 cd는 응답

이 수신된 후에는 더 이상 유효하지 않다.

cd

반드시 이전에 tpalloc()에 의해 할당된 버퍼에 대한 포인터이어야 한다.*data

tpgetrply()가 성공적으로 수신한 데이터의 길이이다. 필요하다면 응답 내용

이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다. *data는 수신

len

데이터가 커서 변경 될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수

있다. len이 호출 전 버퍼의 총 크기보다 크다면, len이 그 버퍼의 새로운 크기

가 된다.

len이 0으로 반환되는 경우 어떤 응답도 수신되지 않고 *data와 len이 지시하

는 버퍼 모두 아무런 변화가 없다. *data나 len이 NULL이 되는 것은 에러이

다.

응답 버퍼의 크기에 대한 포인터이다.flags

88 Tmax Application Development Guide

Page 107: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

flags로 사용 가능한 값은 다음과 같다.

설명설정값

입력 값으로 준 cd를 무시하고, 이에 상관없이 수신 가능한 응답을 반환하도

록 한다.

TPGETANY

cd는 반환된 응답에 대한 호출 구별자가 된다. 아무런 응답이 없으면, 일반적

으로 tpgetrply()는 응답이 도착할 때까지 대기한다.

*data가 가리키는 버퍼의 유형은 변경되지 못한다.TPNOCHANGE

수신된 응답버퍼와 *data가 가리키는 버퍼의 유형이 다른 경우 *data의 버퍼

유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답버퍼의 유형으로

변경되는데 TPNOCHANGE 플래그가 설정되는 경우 변경이 안된다 . 수신된

응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버퍼의 유형 및 하위 유

형과 반드시 일치해야 한다.

응답이 도착할 때까지 대기하지 않는다. 수신 가능한 응답이 있는 경우는 반

환을 한다.

TPNOBLOCK

TPNOBLOCK 플래그가 지정되지 않았고 수신 가능한 응답이 없다면, 함수

호출자는 응답이 도착하거나 또는 타임아웃(트랜잭션 타임아웃이나 블로킹

타임아웃)이 발생할 때까지 대기한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기한다. 트랜잭션 모드에서 tpgetrply()를 한 경우에는 트랜잭션 타임아웃이

적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 시스템 함수 호출이

방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT 플래그가 설정되

TPSIGRSTRT

지 않은 경우 시그널 인터럽트가 발생하였다면, 함수는 실패하고 tperrno에

TPGOTSIG가 설정된다.

● 반환값

설명반환값

함수 호출에 성공한 경우1

(tpreturn()으로 전달되는 tpurcode 전역 변수는 tpgetrply()가 성공적으로 반

환되었거나 tperrno가 [TPESVCFAIL]인 경우, 응용 프로그램(application)에

서 정의한 값을 갖게 된다. )

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

제9장 클라이언트 API 89

Page 108: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 오류

TPGETANY가 설정되지 않은 경우, 특별한 언급이 없는 한 *cd는 무효화됨에 유의해야 한다. TPGETANY

가 설정되었다면, cd는 에러가 발생한 응답에 대한 구별자가 된다. 응답이 반환되기 전에 에러가 발생했

다면, cd는 0이 된다. 특별한 언급이 없다면, 호출자의 트랜잭션에 영향을 미치지 않는다.

설명에러 코드

인수가 유효하지 않다. 예를 들어, cd나 data, *data, len 등이 NULL이거나 또

는 flags가 유효하지 않다.

[TPEINVAL]

cd가 NULL이 아니면, 에러 발생 후에도 cd는 유효하며, 그에 대한 응답을 계

속 기다리게 된다.

cd가 유효하지 않은 구별자이다[TPEBADDESC]

[TPEOTYPE] – 수신된 응답의 유형 또는 하위 유형이 호출자가 알지 못하는 유형이다.

– flags가 TPNOCHANGE로 설정되었는데, *data의 유형 및 하위 유형이 서

비스가 송신한 응답의 것과 맞지 않는 경우로 *data의 내용과 *len은 모두

변경되지 않는다.

– 응답이 호출자의 트랜잭션 모드에서 수신되었다면, 그 트랜잭션은 응답이

무시되었기 때문에 rollback된다.

[TPETIME] – 타임아웃이 발생한 경우이다.

– 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고

그 트랜잭션은 rollback된다.

– 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지

않았다면, 블로킹 타임아웃이 발생하였다. 이 두 경우에, *data의 내용과

*len은 변경되지 않는다. 트랜잭션 타임아웃이 발생하였다면, 새로운 서비

스 요청을 송신한다거나 응답을 기다리는 일은 트랜잭션이 rollback될 때

까지 [TPETIME] 에러로 실패하게 된다.

서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션상의 에러

가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신 되었다

[TPESVCFAIL]

면, 그 내용들은 *data가 가리키는 버퍼를 통하여 사용될 수 있다. 함수 호출

자가 트랜잭션 모드에 있다면, 그 트랜잭션은 rollback된다.

트랜잭션 타임아웃이 발생하기 전까지는, 트랜잭션이 rollback 되기 전에 다

른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고,

또는 실패할 수도 있다. 이들이 제대로 수행되기 위해서는 TPNOTRAN이 설

90 Tmax Application Development Guide

Page 109: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션 완료

시에 모두 rollback된다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다. 구별자(cd)는

유효하다.

[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.[TPGOTSIG]

tpgetrply() 함수가 부적절한 상황에서 호출되었다.[TPEPROTO]

트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가

실패하였다.

[TPETRAN]

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret;

long len;

char *buf;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process …

cd = tpacall(“SERVICE”, buf, 0, TPNOFLAGS);

if (cd==-1) { error procesing }

data process....

ret=tpgetrply(&cd, &buf, &len, TPNOTIME);

if (ret==-1) { error processing }

data process....

tpfree(buf);

tpend();

}

9.3.3. tpcancel

서버/클라이언트의 응답을 취소하는 함수로 tpacall()이 반환한 호출 구별자인 cd를 취소한다.

제9장 클라이언트 API 91

Page 110: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 프로토타입

# include <atmi.h>

int tpcancel (int cd)

● 파라미터

설명파라미터

tpacall()이 반환한 호출 구별자로 취소 대상을 설정한다.cd

전역 트랜잭션 (global transaction)과 관련된 서비스는 취소할 수 없다. 서비

스 응답이 성공적으로 취소되면, cd는 무효화되고 cd를 통해 받은 응답들도

모두 무시된다.

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당되는 값이 설정된다. )

● 오류

tpcancel()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

cd가 유효하지 않은 구별자이다.[TPEBADDESC]

cd가 호출자의 전역 트랜잭션과 관련되어 있다. cd는 여전히 유효하고, 호출

자의 현재 트랜잭션은 영향을 받지 않는다.

[TPETRAN]

tpcancel()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

char *test[2];

int ret, i, cd[2];

long len;

92 Tmax Application Development Guide

Page 111: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (argc != 4) { error processing }

ret=tpstart((TPSTART_T *)NULL;

if (ret==-1) { error processing }

for (i=0; i<3; i++)

{

test[i] = tpalloc(“STRING”,NULL,0);

if (test[I])==NULL} { error processing }

strcpy(test[i],argv[i+1]);

cd[i]=tpacall(“SERVICE”, test[i], 0, TPNOTIME);

)

ret=tpcancel(cd[1]); /* 2번째 응답을 취소한다. */

if (ret==-1) { error processing }

for (i=0; i<3; i++)

{

ret=tpgetrply(&cd[i], (char **)&test[i], &len, TPNOTIME)

if (ret==-1) printf(“Can’t rcv data from service of %d\n”,cd[i]);

else prtinf(“%dth rcv data : %s\n”, I+1, test[I]);

tpfree(test[I]);

}

tpend();

}

● 관련 함수

tpacall()

9.4. 대화형 통신대화형 통신에서 사용되는 함수에 대해 설명한다.

9.4.1. tpconnect

서버와 클라이언트에서 프로그램이 대화형 서비스 svc와 통신을 연결하는 함수이다. 통신은 동시에 수신

또는 송신만 가능한 반 이중(half-duplex)형태이다. 연결을 설정하는 과정에서, 함수 호출자는 서비스 루틴

에게 데이터를 전달할 수 있다.

대화형 서비스는 TPSVCINFO 구조체를 통하여 data와 len을 수신하기 때문에, tpconnect()로 전달된 데

이터들을 수신하기 위하여 tprecv()를 호출할 필요가 없다.

● 프로토타입

제9장 클라이언트 API 93

Page 112: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

# include <atmi.h>

int tpconnect (char *svc, char *data, long len, long flags)

● 파라미터

설명파라미터

연결할 대화형 서비스의 이름이다.svc

호출자가 데이터를 전달하려는 경우, 반드시 tpalloc()에 의해 이전에 할당된

버퍼이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는

유형이어야 한다.

data

전달할 데이터 길이를 지정한다.len

- data가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 버퍼 유형(STRING,

STRUCT, X_COMMON, X_C_TYPE)이라면, len은 무시되고 보통 0이 사용

된다.

- data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET,

CARRAY, MULTI STRUCTURE)이라면, len은 0이 될 수 없다.

- data가 NULL이라면, len은 무시되고, 이 경우 아무런 데이터도 대화형 서비

스에게 넘겨지지 않는다.

tpcall()과 같이 TPNOTRAN, TPNOBLOCK, TPNOTIME, TPSIGSTRT를 포

함하고 TPSENDONLY, TPRECVONLY가 추가된다.

flags

flags로 사용할 수 있는 값들은 다음과 같다.

설명설정값

tpconnect() 함수 호출자가 트랜잭션 모드 상태에서 이 플래그를 설정하여

svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행

된다.

TPNOTRAN

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpconnect()

함수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TPNOTRAN으로

설정해야 한다. 트랜잭션 모드 내에서의 tpconnect() 함수를 호출할 때, TPNO

TRAN으로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는

다.

TPNOTRAN으로 호출된 서비스가 실패하였을 경우, 호출자의 트랜잭션에는

영향을 미치지 않는다.

연결이 완료된 후, 함수 호출자는 처음 데이터를 송신만 할 수 있고 요청된 서

비스만 할 수 있도록 설정하는 플래그이다. 호출자가 처음 통신 제어권을 가

진다.

TPSENDONLY

94 Tmax Application Development Guide

Page 113: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

TPSENDONLY나 TPRECVONLY 중 하나는 반드시 지정되어야 한다.

연결이 완료된 후, 함수 호출자는 데이터를 수신할 수만 있고 요청된 서비스

가 처음 데이터를 송신을 시작하도록 하는 플래그이다. 즉, 요청된 서비스가

처음 통신 제어권을 가진다.

TPRECVONLY

TPSENDONLY나 TPRECVONLY 중 하나는 반드시 지정되어야 한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기하겠다는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpconnect()를 한 경우

에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다.TPSIGRSTRT

내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 시스템

함수가 재호출된다.

TPSIGRSTRT 플래그가 설정되지 않고 시그널 인터럽트가 발생하였다면, 함

수는 실패하고 tperrno에 TPGOTSIG가 설정된다.

● 반환값

설명반환값

함수 호출에 성공한 경우구별자(descriptor)

(차후 연결을 위하여 참조될 구별자(descriptor)를 반환한다. )

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpconnect()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다. 특별한 언급이 없다면, 함수 호출

을 실패할 경우 호출자의 트랜잭션에 영향을 미치지 않는다.

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

예를 들어, svc가 NULL인 경우, data가 NULL인 경우, 지시하는 버퍼가 tpalloc()

으로 할당되지 않았거나, 플래그가 TPSENDONLY 또는 TPRECVONLY로

지정되지 않은 경우 또는 플래그가 유효하지 않은 경우에 발생한다.

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

제9장 클라이언트 API 95

Page 114: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

data의 유형 및 하위 유형이 svc가 지원할 수 있는 유형 및 하위 유형이 아니

다.

[TPEITYPE]

연결 개수가 최대 한계에 도달했기 때문에, 서비스를 요청할 수 없다.[TPELIMIT]

트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가

실패하였다.

[TPETRAN]

타임아웃이 발생하였다.[TPETIME]

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그

트랜잭션은 rollback될 것이다. 트랜잭션 모드가 아니고 TPNOTIME과TP

NOBLOCK 어느 것도 지정되지 않았다면, 블로킹 타임아웃이 발생하였다.

트랜잭션 타임아웃이 발생하였다면, 새로운 서비스 요청은 트랜잭션이 rollback

될 때까지 [TPETIME] 에러로 실패하게 된다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.[TPGOTSIG]

tpconnect()가 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

char *buf;

int ret, cd;

long len, revent;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=tpalloc(“STRING”,NULL,0);

if (buf=NULL) { error procesing }

data process ....

cd = tpconnect(“SERVICE”,sndbuf,0,TPRECVONLY);

if (cd==-1) { error processing }

data process....

ret=tprecv(cd, &buf, &len, TPNOFLAGS, revent);

if (ret==-1) { error processing }

96 Tmax Application Development Guide

Page 115: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpfree(buf);

tpend();

}

● 관련 함수

tpalloc(), tpdiscon(), tprecv(), tpsend()

9.4.2. tpsend

서버/클라이언트에서 사용하는 함수로 대화형 통신에서 상대방 프로그램에게 데이터를 송신하는데 사용

된다. 호출자는 반드시 통신 제어권을 가지고 있어야 한다.

● 프로토타입

# include <atmi.h>

int tpsend ( int cd, char *data, long len, long flags, long *revent )

● 파라미터

설명파라미터

데이터가 송신되는 연결을 지정하는 것으로써, tpconnect()나 TPSVCINFO

매개변수로부터 반환되는 구별자이다.

cd

tpalloc()에 의해 할당된 버퍼이다. 애플리케이션 데이터가 아무것도 송신되

지 않을 경우. 예를 들어, 어떤 데이터도 전달하지 않고 통신 제어권만을 넘기

data

는 경우는 data는 NULL이 될 수 있다. data의 유형 및 하위 유형은 연결된 상

대방이 인식할 수 있는 유형 및 하위 유형이어야 한다.

송신하는 버퍼의 길이로 data가 길이 명시가 필요없는 버퍼를 가리키면 len

은 무시되고 보통 0이 사용된다. data가 길이 명시가 반드시 필요한 버퍼를

가리킨다면 len은 0이 될 수 없다.

len

TPNOBLOCK, TPNOTIME, TPSIGRSTRT, TPRECVONLY를 포함한다.flags

구별자인 cd에 대한 이벤트가 존재한다면, tpsend()는 실패하게 되며, 이때

데이터는 송신되지 않는다. 이벤트 유형은 revent로 반환된다.

revent

flags로 사용 가능한 값은 다음과 같다.

설명설정값

내부 버퍼가 전달될 메시지들로 꽉 찬 경우와 같은 블로킹 상황이 발생하면

데이터와 이벤트들은 송신되지 않는다. TPNOBLOCK 플래그 설정 없이

TPNOBLOCK

tpsend() 호출할 떄, 블로킹 상황이 발생하면 호출자는 타임아웃(트랜잭션 또

는 블로킹 타임아웃 중 하나)이 발생하거나 상황이 완화될 때까지 기다린다.

제9장 클라이언트 API 97

Page 116: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기하는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpsend()를 한 경우에는 여

전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

호출자가 데이터를 송신한 후, 통신 제어권을 상대방에게 넘긴다는 의미이

다. 호출자는 다시 통신 제어권을 넘겨 받기 전까지 tpsend()를 호출할 수 없

TPRECVONLY

다. 대화 상대방 수신자는 tprecv()로 데이터를 수신하면서, 통신 제어권을 갖

게 됨을 의미하는 TPEV_SENDONLY 이벤트를 수신하게 된다. 수신자 또한

다시 통신 제어권을 상대방에게 넘기기 전까지 tprecv()를 호출할 수 없다.

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 내부에서 시그널 인

터럽트가 발생하여 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실

TPSIGRSTRT

행된다. 플래그가 설정되지 않은 경우 시그널 인터럽트가 발생하였다면, 함

수는 실패하고 tperrno에 TPGOTSIG가 설정된다.

revent에 전달되는 이벤트들은 다음과 같다.

설명이벤트 유형

대화 종속자에게 수신되는 이 이벤트는 대화 시작자가 tpdiscon()을 사용하여

연결을 강제로 종료하였다는 것을 의미한다. 또한 이 이벤트는 통신 에러, 예

TPEV_DISCONIMM

를 들어 서버, 노드, 네트워크 장애 등으로 인하여 연결이 끊어졌을 때에도 반

환된다.

대화 시작자에게 수신되는 이 이벤트는 아래의 TPEV_SVCFAIL 상황이외의

경우에, 대화 종속자가 통신 제어권없이 tpreturn()을 수행하였음을 알린다.

TREV_SVCERR

대화 시작자에게 수신되는 이 이벤트는 대화 종속자가 통신 제어권없이

tpreturn()을 수행하였으며, 이때 tpreturn()은 아무 데이터 없이 TPFAIL로 호

출되었다. rval은 TPFAIL이며 data는 NULL로 수행되었음을 알린다.

TREV_SVCFAIL

● 반환값

반환할 경우 revent가 TREV_SVCFAIL이면, tpurcode 전역변수는 tpreturn() 호출 할 때에 전달된 rcode

값이 된다 .

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpsend()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

98 Tmax Application Development Guide

Page 117: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

인수가 유효하지 않다. 예를 들어, data가 가리키는 버퍼가 tpalloc()으로 할당

되지 않았거나 또는 flags가 유효하지 않다.

[TPEINVAL]

구별자(cd) 가 유효하지 않다.[TPEBADDESC]

타임아웃이 발생하였다.[TPETIME]

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그

트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK

어느 것도 지정되지 않았다면, 블로킹 타임아웃이 발생하였다. 이 두 경우에,

*data의 내용과 len은 변경되지 않는다. 트랜잭션 타임아웃이 발생하였다면,

트랜잭션이 rollback될 때까지 대화형 통신상으로 메시지를 송신하거나 수신

하는 일, 또는 새로운 연결을 시작하는 일은 모두 [TPETIME] 에러로 실패하

게 된다.

이벤트가 발생하였다. 이 에러가 발생하면 data는 송신되지 않고, 이벤트 유

형은 revent로 반환된다.

[TPEEVENT]

TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.[TPGOTSIG]

tpsend()가 부적절한 상황에서 호출되었다. 예를 들어 수신자 모드에서 사용

하는 경우에 발생한다.

[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

main(int argc,char* argv[])

{

int ret, cd;

struct dat *buf;

long revent, len;

if (argc!=3) {error processing }

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=(struct dat *)tpalloc(“STRUCT”, “dat”, 0);

if (buf==NULL) { error processing }

strcpy(buf->sdata, argv[1]);

data process….

cd=tpconnect(“SERVICE”, buf, 0, TPSENDONLY);

제9장 클라이언트 API 99

Page 118: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (cd==-1) { error processing }

strcpy(buf->sdata, argv[2]);

data process….

ret=tpsend(cd, buf, 0,TPRECVONLY,&revent);

if (ret==-1) { error processing }

ret=tprecv(&cd,(char**)&buf,&len,TPNOTIME,&revent);

if (ret==-1) { error processing }

data process....

tpfree(buf);

tpend();

}

9.4.3. tprecv

서버/클라이언트에서 대화형 통신을 하는 경우 메시지를 수신하는 함수이다. 대화형 통신으로 연결된 상

대방 프로그램으로부터 송신된 데이터를 수신하기 위해 사용된다. tprecv()는 클라이언트나 서버 중 통신

제어권을 갖지 않은 프로그램에서만 사용될 수 있다.

● 프로토타입

# include <atmi.h>

int tprecv ( int cd, char **data, long *len, long flags, long *revent )

● 파라미터

설명파라미터

데이터를 수신할 연결을 지정한다. tpconnect()나 TPSVCINFO 매개변수 중

하나로부터 반환된 구별자(descriptor)이다.

cd

tpalloc()에 의해 이전에 할당된 버퍼에 대한 포인터 주소이다. 함수가 성공적

으로 반환되면, *data는 수신된 데이터를 가리킨다.

data

데이터 길이로 len이 호출 전 버퍼의 총 크기보다 더 크다면, 버퍼의 새로운

크기는 len이 된다.

len

len이 0이면, 어떤 데이터도 수신되지 않았고 *data나 *data가 가리키는 버퍼

모두 아무런 변화 없다. *data나 len이 NULL이면 data는 에러이다.

TPNOCHANGE, TPNOTIME, TPSIGRSTRT, TPNOBLOCK를 포함한다.flags

이벤트가 발생할 경우 이벤트 유형이 설정된다.revent

100 Tmax Application Development Guide

Page 119: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

flags에는 다음 값이 사용할 수 있다.

설명설정값

수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다르다면, *data의 버퍼

유형은 수신자가 인식할 수 있는 한도내에서 수신된 응답버퍼의 유형으로 변

TPNOCHANGE

경된다. 그러나 이 플래그가 설정되었다면, *data가 가리키는 버퍼의 유형은

변경되지 못한다. 수신된 응답버퍼의 유형 및 하위 유형은 *data가 가리키는

버퍼의 유형 및 하위 유형과 반드시 일치하여야 한다.

데이터가 도착할 때까지 기다리지 않는다. 수신가능한 데이터가 있으면 이를

반환한다. TPNOBLOCK 플래그가 지정되지 않고 수신 가능한 데이터가 없

으면 호출자는 데이터가 도착할 때까지 대기한다.

TPNOBLOCK

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기한다는 것을 의미한다. 그러나 트랜잭션 타임아웃 내에서 tprecv()를 한 경

우에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다.TPSIGRSTRT

내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 시스템

함수 호출이 재실행된다. 플래그가 설정되지 않은 경우 시그널 인터럽트가

발생하였다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.

다음은 revent에 반환되는 이벤트 유형에 대한 설명이다.

설명이벤트 유형

대화 종속자에게 수신되는 이 이벤트는 대화 시작자가 tpdiscon()으로 대화형

연결을 강제로 종료했음을 의미한다. 또한 이 이벤트는 통신 에러, 예를 들어

TPEV_DISCONIMM

서버, 노드, 네트워크 장애 등으로 인하여 연결이 끊어졌을 때 대화 시작자나

종속자에게 반환될 수 있다. 이것은 강제적인 연결 해제 통보이기 때문에, 전

달 중인 데이터는 분실될 수도 있다. 2개의 프로그램이 동일한 트랜잭션에 참

여하고 있었다면, 그 트랜잭션은 rollback된다.

대화형 통신에 사용되었던 구별자(cd)는 더 이상 유효하지 않다.

연결된 상대방 프로그램 쪽에서 통신 제어권을 포기하였다.

TPEV_SENDONLY 이벤트의 수신자는 데이터를 송신할 수는 있지만 수신자

가 제어권을 넘길 때까지는 어떤 데이터도 수신할 수 없다.

TPEV_SENDONLY

대화 시작자에게 수신되는 이 이벤트는 대화 종속자가 tpreturn()수행 중에 에

러가 발생하였음을 알린다.

TPEV_SVCERR

예를 들어, tpreturn()에 잘못된 인수들이 전달되었거나, 서비스가 다른 종속

자들과 연결을 유지하고 있는 동안에 tpreturn()이 호출되었을 수 있다. 이 경

우, return 코드나 데이터 일부는 사용이 불가능하다.

제9장 클라이언트 API 101

Page 120: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명이벤트 유형

대화형 연결이 종료되고 cd는 더 이상 유효하지 않다. 만약 이 이벤트가 수신

자의 트랜잭션 과정에서 발생하였다면, 그 트랜잭션은 rollback된다.

대화 시작자에게 수신되는 이 이벤트는 상대편인 대화 종속자 서비스가 애플

리케이션에서 실패로 서비스를 종료하였음을 알린다. TPFAIL로 tpreturn()을

호출하였다.

TPEV_SVCFAIL

대화 종속자 서비스가 tpreturn()을 호출하였을 때 통신 제어권을 가지고 있었

다면, 서비스는 연결된 상대방에게 데이터를 전달할 수 있다.

서비스가 종료하면서 서버 프로세스는 대화형 연결을 끊는다. 그러므로 cd는

더 이상 유효지 않다. 만약 이 이벤트가 수신자의 트랜잭션 과정에서 발생하

였다면, 그 트랜잭션은 rollback된다.

대화 시작자에게 수신되는 이 이벤트는 상대편인 대화 종속자 서비스가 성공

적으로 종료하였음을 알린다. TPSUCCESS로 tpreturn()을 호출하였다.

TPEV_SVCSUCC

● 반환값

revent 값이 TREV_SVCSUCC이거나 TREV_SVCFAIL인 경우, tpreturn()으로 전달되는 tpurcode 전역

변수는 애플리케이션에서 정의한 값을 갖게 된다. 그렇지 않으면 -1을 반환하고, tperrno에 에러 상황에

해당하는 값이 설정된다. 에러 없이 이벤트가 존재한다면, tprecv()는 -1을 반환하고 tperrno는 [TPEEVENT]

가 된다.

● 오류

다음과 같은 상황에서 tprecv()는 실패하고, tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

구별자(cd) 가 유효하지 않다.[TPEBADDESC]

TPNOBLOCK가 설정된 상태에서 블로킹 상황이 발생하였다.[TPEBLOCK]

이벤트가 발생하였고 revent로 이벤트 유형을 알 수 있다.[TPEEVENT]

인수가 유효하지 않다. 예를 들어, *data가 가리키는 버퍼가 tpalloc()으로 되

지 않았거나 flags가 유효하지 않다.

[TPEINVAL]

운영 시스템에 에러가 발생하였다.[TPEOS]

입력된 버퍼의 유형이나 하위 유형이 호출자가 알지 못하는 것이거나, flags

로 TPNOCHANGE가 설정되었는데 *data의 유형 및 하위 유형이 입력되는

[TPEOTYPE]

버퍼의 유형 및 하위 유형과 일치하지 않는다. 이런 경우, *data의 내용과 *len

은 모두 아무 변화 없다.

대화형 통신이 트랜잭션의 한 부분이라면, 그 트랜잭션은 응답이 무시되었기

때문에 rollback된다.

102 Tmax Application Development Guide

Page 121: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

이 에러가 발생하면, cd에 대한 이벤트는 무시되고 대화형 통신 상태는 보장

할 수 없다. 따라서 호출자는 대화형 통신을 종료해야 한다.

tprecv()가 부적절한 상황에서 호출되었다. 예를 들어 송신자 모드에서 사용

한 경우에 발생한다.

[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

타임아웃이 발생하였다.[TPETIME]

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그

트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK

어느 것도 지정되지 않았다면, 블로킹 타임아웃이 발생하였다. 이 두 경우에,

*data의 내용과 len은 변경되지 않는다.

트랜잭션 타임아웃이 발생하였다면, 트랜잭션이 rollback될 때까지 대화형

통신상으로 메시지를 송신하거나 수신하는 일, 또는 새로운 연결을 시작하는

일은 모두 [TPETIME]에러로 실패하게 된다.

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

main(int argc,char* argv[])

{

int ret, cd;

struct dat *buf;

long revent, len;

if (argc!=3) {error processing }

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=(struct dat *)tpalloc(“STRUCT”, “dat”, 0);

if (buf==NULL) { error processing }

strcpy(buf->sdata, argv[1]);

data process….

cd=tpconnect(“SERVICE”, buf, 0, TPSENDONLY);

if (cd==-1) { error processing }

strcpy(buf->sdata, argv[2]);

data process….

ret=tpsend(cd, buf, 0,TPRECVONLY,&revent);

if (ret==-1) { error processing }

제9장 클라이언트 API 103

Page 122: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tprecv(cd,(char**)&buf,&len,TPNOTIME,&revent);

if (ret==-1) { error processing }

data process....

tpfree(buf);

tpend();

}

9.4.4. tpdiscon

대화형 모드의 연결 끊는 함수로 서버/클라이언트에서 대화형 통신 연결 종료한다.

일반적으로 대화형 통신에서 연결을 끊기 위해서는 연결 컨트롤을 서버가 가질 때 tpreturn()을 부른다. 서

버가 tpreturn()을 호출하면, 상대방(클라이언트)이 tprecv()를 호출할 때 TPEV_SVCSUCC 또는

TPEV_SVCFAIL 이벤트가 발생하여 연결이 끊김을 알게 된다.

tpdiscon()는 통신을 즉시 끊고자 하는 경우에 사용하는 함수이다.

tpconnect()으로 연결한 서비스일 경우 극히 예외적인 경우에 연결을 즉시 종료하고 연결된 상대방에게

TPEV_DISCONIMM 이벤트를 발생시킨다.

tpdiscon() 함수는 단지 대화형 통신을 시작한 쪽에서만 호출할 수 있고 구별자(descriptor)를 제공한 서비

스 측에서는 호출할 수 없다. 대화형 서비스와 통신하는 프로그램은 대화형 통신을 종료할 수 있는데 올바

른 결과를 보장하기 위해서는 서비스 쪽에서 tpreturn()으로 연결을 종료하는 것이 좋다.

tpdiscon() 함수는 연결을 강제적으로 종료시킨다. 강제 종료되는 경우 목적지에 전달되지 못한 일부 데이

터는 분실될 수 있다. tpdiscon()은 연결된 상대방 프로그램이 호출자의 트랜잭션에 참여하고 있는 상황에

서 호출될 수도 있다. 이 경우 트랜잭션은 취소되고 데이터는 상실될 수 있다. tpdiscon()을 호출하는 함수

호출자가 통신 제어권을 가져야 할 필요는 없다.

● 프로토타입

# include <atmi.h>

int tpdiscon (int cd)

● 파라미터

설명파라미터

tpconnect()에서 반환한 참조 구별자(descriptor)이다.cd

● 반환값

설명반환값

함수 호출에 에러가 발생한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

104 Tmax Application Development Guide

Page 123: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 오류

tpdiscon()가 실패하는 경우 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

cd가 유효하지 않거나 이미 대화형 서비스에서 사용되고 있는 구별자(descrip

tor)이다.

[TPEBADDESC]

타임아웃이 발생하였다. cd는 더 이상 유효하지 않다.[TPETIME]

tpdiscon() 함수가 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <stdlib.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret, cd;

char *buf

long len, revent;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

cd=tpconnect(“SERVICE”,buf,0,TPRECVONLY);

if (cd==-1) { error processing }

data process....

ret=tprecv(cd, (char **)&buf, &len, TPNOFLAGS, &revent);

if (ret==-1 && revent != TPEV_SENDONLY && revent != TPEV_SVCSUCC)

{ error processing }

printf(“received data = %s\n”, buf);

if (atoi(buf)>90) {

ret=tpdiscon(cd);

if (ret==-1) {error processing }

tpfree(buf);

tpend();

exit(1);

제9장 클라이언트 API 105

Page 124: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

data process....

tpfree(buf);

tpend();

}

● 관련 함수

tpconnect(), tprecv(), tpreturn(), tpsend()

9.5. 비요청 메시지 처리비요청 메시지 처리 함수는 메시지를 무조건 보내거나, 일방적으로 보내는 메시지를 처리하기 위한 함수

이다. 서버에서 보내는 일방적인 메시지(tpbroadcast ())를 항상 모든 클라이언트가 받을 수 있는 것은 아

니다. 비요청 메시지를 받기 위해서는 먼저 클라이언트가 Tmax에 접속되어 있어야 하고, Tmax에 접속할

때 비요청 메시지를 받겠다는 정보를 주어야 한다.

tpstart()를 호출할 때 사용하는 TPSTART_T 구조체의 flags 값을 TPUNSOL_POLL이나 TPUNSOL_HND

로 설정해야만 서버에서 보내는 일방적인 데이터를 Tmax가 중계하여 준다.

9.5.1. tpsetunsol

클라이언트에서 사용되는 함수로 비요청 수신 메시지를 처리하는 루틴 설정하는 함수이다. tpsetunsol()

이 처음으로 호출되기 전에, Tmax 라이브러리에 의해 수신된 비요청 메시지는 무시된다. NULL 함수 포인

터의 tpsetunsol() 호출도 마찬가지로 무시된다.

시스템이 비요청 메시지를 통지 받는데 사용되는 방법은 애플리케이션에 임의로 결정되며, 이는 각 클라

이언트별로 변경이 가능하다. tpsetunsol() 호출로 전달된 함수 포인터는 주어진 인수 정의에 적합하여야

한다.

● 프로토타입

# include <atmi.h>

Unsolfunc *tpsetunsol ( void ( *disp ) ( char *data, long len, long flags ) )

● 파라미터

설명파라미터

수신된 버퍼를 지시한다.data

데이터도 수반되지 않았다면, data는 NULL이 될 수 있다. 데이터가 클라이언

트가 알지 못하는 버퍼 유형 및 하위 유형인 경우, 데이터는 이해되지 못한다.

106 Tmax Application Development Guide

Page 125: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

애플리케이션은 data를 제거할 수 없으며, 대신 시스템이 이를 제거하고 데

이터 영역을 무효화하여 반환한다.

데이터의 길이를 나타낸다.len

현재 사용되지 않는다.flags

● 반환값

설명반환값

함수 호출에 성공한 경우포인터 / NULL

(이전에 설정된 비요청 메시지 처리 루틴의 포인터를 반환한다. NULL은 이

전에 어떤 메시지 처리 함수도 설정되지 않았음을 나타내는 것으로 성공적인

반환이다. )

함수 호출에 실패한 경우TPUNSOLERR를

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpsetunsol()이 실패한 경우, 나타날 수 있는 tperrno값들은 다음과 같다.

설명에러 코드

tpsetunsol()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

void get_unsol(char *data, long len, long flags)

{

printf(“get unsolicited data = %s\n”, data);

data process....

}

void main(int argc, char *argv[])

{

제9장 클라이언트 API 107

Page 126: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

int ret;

char *buf;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

ret=tpsetupsol_flag(TPUNSOL_HND);

if (ret==-1) { error processing }

ret=tpsetunsol(get_unsol);

if (ret==TPUNSOLERR) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process...

ret=tpcall(“SERVICE”, buf, 20, (char **)&buf, &len, TPNOFLAGS);

if (ret==-1) { error processing }

data process...

tpfree((char *)buf);

tpend();

}

● 관련 함수

tpstart(), tpend(), tpgetunsol()

9.5.2. tpgetunsol

클라이언트의 요청없이 일방적으로 전달받은 메시지를 처리하는 함수이다. 메시지를 보내는 쪽에서 tp

broadcast() 또는 tpsendtoci(), tppost()를 통해 전달한다.

tpgetunsol() 호출 전에 전달된 일방적인 메시지들은 무시된다. tpgetunsol()을 통하여 비요청 메시지를 받

으려면 tpstart()를 통해 Tmax 시스템에 연결할 때에 flags를 TPUNSOL_POLL이나 TPUNSOL_HND로 지

정하여야 한다. tpgetunsol()이 프로그램에 호출되면 tpstart()의 플래그가 TPUNSOL_IGN로 설정되었다

하더라도 내부적으로 TPUNSOL_POLL로 전환되어 서버로부터 비요청 메시지를 받게 된다.

● 프로토타입

#include <tmaxapi.h>

int tpgetunsol (int type, char **data, long *len, long flags)

● 파라미터

108 Tmax Application Development Guide

Page 127: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

전달된 메시지에 대한 포인터이다. 클라이언트가 알지 못하는 버퍼 유형 및

하위 유형(subtype)일 수 있는데 이 경우 데이터는 사용할 수 없다.

data

메시지의 총 길이이다.len

메시지의 블로킹 처리 여부를 결정한다.flags

서버에서 전달된 메시지의 형식으로 UNSOL_TPPOST, UNSOL_TPBROAD

CAST, UNSOL_TPSENDTOCLI 등이 있다.

type

flags로 사용 가능한 값은 다음과 같다.

설명설정값

tpgetunsol() 호출할 때에 블로킹 상태로 일방적인 메시지가 올 때까지 기다

린다.

TPBLOCK

보통 수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다르다면 *data의

버퍼 유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답 버퍼의 유형

TPNOCHANGE

으로 변경된다. 플래그가 설정된 경우 *data가 가리키는 버퍼의 유형은 변경

되지 못한다. 수신된 응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버

퍼의 유형 및 하위 유형과 반드시 일치하여야 한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기

다리겠다는 것을 의미한다.

TPNOTIME

트랜잭션 모드에서 tpgetrply()를 한 경우에는 여전히 트랜잭션 타임아웃이

적용된다.

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다.TPSIGRSTRT

시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT

플래그가 설정되지 않은 경우 시그널 인터럽트가 발생하였다면 함수는 실패

하고 tperrno에 TPGOTSIG가 설정된다.

입력값으로 구별자(cd)를 무시하고, 이에 상관없이 수신 가능한 응답을 반환

하도록 한다. cd는 반환된 응답에 대한 호출 구별자가 된다. 응답이 없으면

일반적으로 tpgetrply()는 응답이 도착할 때까지 대기한다.

TPGETANY

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 상황에 해당하는 값이 설정된다.)

● 오류

제9장 클라이언트 API 109

Page 128: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpgetunsol()이 실패한 경우, 나타날 수 있는 tperrno값들은 다음과 같다.

설명에러 코드

tpgetunsol()가 부적절한 상황에서 호출되었다. 예를 들어 서버 내에서 호출

되었다.

[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <string.h>

#include <usrinc/tmaxapi.h>

void main(int argc, char *argv[])

{

int ret;

char *buf;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

while(1)

{

ret=tp_sleep(2);

if (ret==-1) { error processing }

if (ret==0) printf(“nothing happened\n”);

else {

ret=tpgetunsol(UNSOL_TPSENDTOCLI, (char **)&buf, &len, TPNOCHANGE);

if (ret==-1) { error processing }

printf(“received data : %s\n”, buf);

}

data process....

if (strncmp(buf, “end”, 3)==0) break;

}

data process....

tpfree(buf);

tpend();

}

110 Tmax Application Development Guide

Page 129: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 관련함수

tpbroadcast(), tpsetunsol(), tpstart(), tpend()

9.6. 타임아웃 변경

9.6.1. tpset_timeout

서버/클라이언트에서 사용되는 함수로 블로킹 타임아웃 시간을 설정하는 함수이다. 서버에 설정되어 있

는 서비스 제한 시간인 블로킹 타임아웃 시간을 변경할 때 사용된다.

tpset_timeout() 함수로 서비스 제한 시간을 설정한 경우, sec초 동안 서비스 요청에 대한 응답을 기다린다.

sec초가 지나도록 응답을 수신하지 못하면 타임아웃 에러를 발생하고, 요청한 서비스에 대한 응답을 기다

리지 않고 서비스 실패로 반환된다.

tpset_timeout()는 해당 함수가 호출된 이후의 서비스 요청들에 적용된다. 다시 tpset_timeout() 함수가 호

출되거나, 클라이언트나 서버 프로세스가 종료될 때까지 함수는 유효하다. tpset_timeout()이 사용되지 않

는다면, 블로킹 타임아웃으로 Tmax 환경파일에 설정된 BLOCKTIME이 적용된다.

● 프로토타입

#include <tmaxapi.h>

int tpset_timeout (int sec)

● 파라미터

설명파라미터

블로킹 타임아웃으로 초단위로 설정한다.sec

● 반환값

설명반환값

함수 호출에 성공한 경우0

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpset_timeout()이 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

제9장 클라이언트 API 111

Page 130: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

void main(int argc, char *argv[])

{

int ret;

char *sndbuf, *rcvbuf;

long sndlen, rcvlen;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

sndbuf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (sndbuf==NULL) {error processing };

rcvbuf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (rcvbuf==NULL) {error processing };

data process....

sndbuf=strlen(sndbuf);

ret=tpset_timeout(4);

if (ret==-1) { error processing }

ret=tpcall(“SERVICE”, sndbuf, sndlen, &rcvbuf, &rcvlen, TPNOCHANGE);

if (ret==-1) { error processing }

data process....

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

9.7. 버퍼 관리서로 다른 하드웨어나 운영체계에 있어서 메모리 할당 방식과 데이터 유형의 크기 차이로 송신한 데이터

와 다른 데이터 값을 가질 수 있다. 따라서 일반적인 클라이언트/서버 환경에서 이기종 간의 통신은 주로

문자형으로 변환하여 통신하게 된다. 이것은 네트워크 부하를 증가시키는 원인이 되기도 한다.

버퍼 관리에 사용되는 API에 대해 설명한다.

112 Tmax Application Development Guide

Page 131: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.7.1. tpalloc

서버/클라이언트에서 버퍼를 할당하는 함수이다.

함수는 C 라이브러리의 malloc()이나 realloc() 또는 free()와 함께 사용될 수 없다. 예를 들어, tpalloc()으로

할당된 버퍼를 free()로 제거할 수 없다. 이 경우에는 tpfree()를 사용한다.

tpalloc() 함수는 type으로 지정된 유형의 버퍼를 할당하고 그에 대한 포인터를 반환한다. 유형에 따라

subtype과 size는 선택적으로 지정할 수 있다. 일부 버퍼 유형은 사용되기 전에 초기화가 필요하기 때문

에, tpalloc()은 버퍼를 할당한 후 이를 초기화하여 반환한다. 그러므로, 호출자에게 반환된 버퍼는 즉시 사

용 가능하다. 초기화 작업에 실패하면 tpalloc()은 버퍼를 0값으로 초기화하지 못하고 할당된 버퍼는 제거

(free)된다.

● 프로토타입

# include <atmi.h>

char * tpalloc (char *type, char *subtype, long size)

● 파라미터

설명파라미터

지정할 수 있는 버퍼 유형은 STRING, STRUCT, X_COMMON,

X_C_TYPE,X_OCTET, CARRAY, FIELD이다.

type

- STRING : NULL로 끝나는 문자열의 데이터를 전송할 때 사용한다.

- CARRAY, X_OCTET : 길이가 지정된 문자형의 데이터를 전송할 때 사용한다.

- STRUCT, X_C_TYPE : C 언어 구조체 타입의 데이터를 전송할 때 사용한다.

- X_COMMON : char, int, long만 가능한 C 구조체일 때 사용한다.

- FDL : 데이터를 식별자와 식별자에 해당하는 값 형태로 저장할 때 사용한다.

STRUCT, X_C_TYPE, X_COMMON인 경우 반드시 하위 유형을 지정하여야 한

다. type의 처음 8Bytes와 subtype의 처음 16Bytes만이 사용되고 지정된 길이를

초과해서 사용하면 초과한 길이는 무시된다.

subtype

지정된 버퍼 유형이 하위 유형을 사용하지 않는다면, subtype은 무시되고 보통

NULL이 사용된다. 할당된 버퍼의 크기는 기본 크기 (1024 Bytes) 이상이다.

버퍼 크기이다.size

CARRAY와 X_OCTET에서는 반드시 지정하여야 하며 이를 제외하고는 생략 가

능하다. 0으로 지정하면 각 버퍼의 기본 크기가 사용된다. STRING, STRUCT,

X_C_TYPE, X_COMMON의 기본 크기는 1024 Byte이다. CARRAY의 기본 크

기는 0이지만 버퍼를 할당할 때에는 반드시 0보다 커야 한다.

제9장 클라이언트 API 113

Page 132: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 반환값

설명반환값

함수 호출에 성공한 경우버퍼 포인터

(적절한 버퍼에 대한 포인터를 반환한다. )

함수 호출에 실패한 경우NULL

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpalloc()이 실패하는 경우 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다. 예를 들어, NULL 형식이다.[TPEINVAL]

알 수 없는 유형 혹은 하위 유형이다. STRUCT 버퍼 유형인 경우 하위 유형이(구

조체의 태그명) SDLFILE에 존재하지 않는 경우 발생한다.

[TPENOENT]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

메모리를 할당 받지 못하는 운영 시스템에 에러가 발생하였다.[TPEOS]

요청되는 서버의 자료형이 구조체 버퍼인데 해당 서버가 컴파일할 때 구조체 파

일과 함께 컴파일이 되지 않은 경우에 발생한다.

[TPEOTYPE]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

void main(int argc, char *argv[])

{

int ret;

struct data *buf;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret<0) { error processing }

buf=(struct data *)tpalloc(“STRUCT”, “data”,0);

data process....

ret=tpcall(“SERVICE”, (char *)sndbuf, 0, (char **)&rcvbuf, &len, TPNOFLAGS);

if (ret<0) {error processing }

data process....

tpfree((char *)buf);

114 Tmax Application Development Guide

Page 133: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

}

● 관련 함수

tpfree(), tprealloc(), tptypes()

9.7.2. tprealloc

서버/클라이언트에서 버퍼의 재할당하는 함수이다.

tprealloc() 함수는 ptr이 가리키는 버퍼의 크기를 Byte로 재할당하고, 버퍼가 변경되었을 경우 새 버퍼에

대한 포인터를 반환한다. tpalloc()과 동일하게 버퍼의 크기는 기본 사이즈(1024Byte) 이상이다. 버퍼의 유

형은 재할당이 된 후에도 동일하게 유지된다. 함수가 성공적으로 반환되면, 반환된 포인터가 버퍼를 참조

하기 위해서 사용되고 ptr은 더 이상 사용될 수 없다. 재할당된 버퍼의 크기가 축소되는 경우 원래 ptr의 내

용은 보장할 수 없다.

일부 버퍼 유형들은 사용되기 전에 초기화될 필요가 있다. tprealloc()은 버퍼 재할당 이후 다시 초기화하

여 반환한다. 그렇기 때문에 호출자에게 반환된 버퍼는 즉시 사용가능하다. 버퍼가 재초기화에 실패하면,

tprealloc()은 NULL을 반환하고 ptr이 지시하는 버퍼의 내용은 유효하지 않다.

C 라이브러리의 malloc(), realloc() 또는 free()와 함께 사용될 수 없다. 예를 들어, tprealloc()으로 할당된

버퍼를 free()로 해제할 수 없다.

● 프로토타입

# include <atmi.h>

char * tprealloc ( char *ptr, long size )

● 파라미터

설명파라미터

할당할 버퍼에 대한 포인터이다.ptr

할당할 버퍼의 크기이다.size

● 반환값

설명반환값

함수 호출에 성공한 경우버퍼 포인터

(적절한 버퍼에 대한 포인터를 반환한다.)

함수 호출에 실패한 경우NULL

( tperrno에 에러 상황에 해당하는 값이 설정된다.)

제9장 클라이언트 API 115

Page 134: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 오류

tprealloc()이 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다. 예를 들어, ptr이 가리키는 버퍼가 tpalloc()으로 할당된 것

이 아니다 .

[TPEINVAL]

tprealloc()이 부적절한 상황에서 호출되었다.[TPEPROTO]

ptr이 가리키는 버퍼가 tpalloc()으로 할당되지 않은 버퍼이다.[TPENOENT]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

char *buf;

buf=tpalloc(“STRING”,NULL,10);

if (buf==NULL) { error processing }

buf=tprealloc(buf,20); /* ok */

if (buf==NULL) { error processing }

buf=”test”;

buf=tprealloc(buf,30); /*error : TPEINVAL */

if (buf==NULL) { error processing }

}

● 관련 함수

tpalloc(), tpfree(), tptypes()

9.7.3. tpfree

서버/클라이언트에서 버퍼에 할당된 메모리를 해제하는 함수로 이전에 tpalloc()이나 tprealloc()으로 얻

어진 버퍼를 해제한다.

● 프로토타입

# include <atmi.h>

void tpfree(char *ptr)

116 Tmax Application Development Guide

Page 135: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 파라미터

설명파라미터

tpalloc()이나 tprealloc() 으로 얻어진 버퍼에 대한 포인터이다.ptr

ptr이 NULL이면, 아무 일도 일어나지 않는다. ptr이 버퍼를 가리키지 않거나, tpfree()

로 이미 해제된 공간을 가리킨다면 그 결과는 알 수 없다. 서비스 루틴 내부에서 ptr이

서비스 루틴에게 전달된 버퍼라면 tpfree()는 버퍼를 해제하지 않고 그냥 반환한다.

버퍼를 제거하는 과정에서, 일부 버퍼 유형은 관련 데이터나 상태 정보를 해제할 필요

가 있다. tpfree()는 버퍼를 해제하기 전에 이와 관련된 정보도 제거한다.

tpfree() 함수가 수행되면 ptr은 XATMI 루틴에 인수로 전달될 수 없으며 어떤 다른 방

식으로 사용될 수 없다.

● 반환값

tpfree() 함수는 함수 호출자에게 아무런 값도 반환하지 않는다.

● 예제

#include <usrinc/atmi.h>

#include <stdio.h>

#include “../sdl/demo.s”

void main(int argc, char *argv[])

{

int ret;

struct data *buf;

char *message, *message2;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=(struct data *)tpalloc(“STRUCT”, “data”,0);

if (buf==NULL) { error processing }

message=tpalloc(“STRING”, NULL, 0);

if (message==NULL) { error processing }

message2=tpalloc(“CARRAY”, NULL, 20);

if (message==NULL) { error processing }

data process....

tpfree((char *)buf);

tpfree(message);

tpfree((char *)message2);

제9장 클라이언트 API 117

Page 136: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

}

● 관련 함수

tpalloc(), tprealloc()

9.7.4. tptypes

서버/클라이언트에서 사용되는 함수로 버퍼의 유형 및 하위 유형에 대한 정보를 제공한다. tptypes() 함수

는 ptr로 데이터 버퍼에 대한 포인터를 입력 받아 type과 subtype에 각각 버퍼의 유형과 하위 유형을 반환

한다.

● 프로토타입

#include <atmi.h>

long tptypes ( char *ptr, char *type, char *subtype )

● 파라미터

설명파라미터

반드시 tpalloc()으로 할당된 버퍼를 가리켜야 한다.ptr

- NULL이 아니라면 가리키고 있는 문자열에 각각 버퍼의 type과 subtype이름을

갖는다. subtype이 존재하지 않으면, subtype이 가리키는 배열은 NULL 스트링

(""")을 포함하고 있다.

type / subtype

- 이름이 최대 길이라면, 문자열은 NULL로 끝나지 않는다. (최대 길이는 type은

8자, subtype은 16자이다.)

- type의 처음 8Byte와 subtype의 처음 16Byte만이 유효한 값을 갖는다.

● 반환값

설명반환값

함수 호출에 성공하는 경우버퍼크기

함수 호출에 실패하는 경우-1

(에러 상황을 나타내는 tperrno를 설정한다.)

● 오류

tptypes()가 실패하는 경우 tperrno에 에러 상황에 해당하는 값이 설정된다.

118 Tmax Application Development Guide

Page 137: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

인수가 유효하지 않다. 예를 들어, ptr이 가리키는 버퍼가 tpalloc()으로 할당되지

않았다.

[TPEINVAL]

tptypes()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

main(int argc, char *argv[])

{

int ret;

struct sel_o *rcvbuf;

char type[9], subtype[17];

long size;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf=(struct sel_o*)tpalloc(“STRUCT”,”sel_o”,0);

if (buf==NULL) {error processing };

size =tptypes((char*)buf, type,subtype);

if (size==-1) {error processing };

printf (“buf : size %d, type %s, subtype %s\n\n”, size, type, subtype);

/*rcvbuf : size 1024, type STRUCT, subtype sel_o */

data process...

tpfree((char *)buf);

tpend();

}

● 관련 함수

tpalloc(), tpfree(), tprealloc()

9.8. 트랜잭션 관리

9.8.1. tx_begin

서버/클라이언트에서 사용하는 함수로 전역 트랜잭션을 시작한다.

제9장 클라이언트 API 119

Page 138: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tx_begin()은 전역 트랜잭션을 시작하는 것으로 함수 호출자는 트랜잭션 모드가 된다. 호출 프로세스가

트랜잭션을 시작하기 전에, 먼저 tx_open()으로 자원 관리자와 연결되어 있어야 한다. tx_begin() 함수는

호출자가 이미 트랜잭션 모드에 있거나 또는 tx_open()이 호출되지 않았다면 실패하게 되고, [TX_PROTO

COL_ERROR]를 반환한다.

트랜잭션이 시작되면, 호출 프로세스는 현재 트랜잭션을 완료하기 위해서 tx_commit() 이나 tx_rollback()

를 호출한다. 트랜잭션을 시작하기 위하여 반드시 tx_begin()을 직접적으로 호출할 필요가 없는 연속

(chaining) 트랜잭션의 경우도 존재한다. 자세한 내용은 “9.8.2. tx_commit”과 “9.8.3. tx_rollback”을 참고한

다.

● 프로토타입

#include <tx.h>

int tx_begin (void)

● 반환값

설명반환값

함수 호출에 성공한 경우TX_OK

함수 호출에 실패한 경우음수

● 오류

tx_begin()이 실패하는 경우 음수값을 반환한다.

설명에러 코드

현재 호출 프로세스가 외부의 전역 트랜잭션에 참여하고 있기 때문에 트랜잭

션 관리자가 전역 트랜잭션을 시작할 수 없다. 해당 작업들이 모두 완료되어

[TX_OUTSIDE]

야만 전역 트랜잭션을 시작할 수 있다. 참여하고 있는 트랜잭션에는 영향을

주지 않는다.

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 이미 트랜잭션

모드에 있는 경우이다. 현재 트랜잭션에는 영향을 주지 않는다.

[TX_PROTOCOL_ER

ROR]

트랜잭션 관리자 또는 리소스 관리자가 트랜잭션을 시작하는 중에 일시적으

로 에러를 만났다. 이 에러가 반환되면, 호출자는 트랜잭션 모드에 있지 않게

된다. 에러의 정확한 원인은 제품의 특성에 따라 결정된다.

[TX_ERROR]

치명적인 에러가 발생하여 트랜잭션 관리자나 리소스 관리자는 더 이상 애플

리케이션을 위하여 작업을 실행할 수 없다. 에러가 반환되면, 호출자는 트랜

[TX_FAIL]

잭션 모드에 있지 않게 된다. 에러의 정확한 원인은 제품의 특성에 따라 다르

다.

● 예제

120 Tmax Application Development Guide

Page 139: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

void main(int argc, char *argv[])

{

char *buf;

int ret,cd;

long len, revent;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process.…

ret=tx_set_transaction_timeout( 5 );

if (ret<0) { error processing }

ret=tx_begin();

if (ret<0) { error processing }

cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY);

if (cd==-1) { error processing }

ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)};

if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback();

else tx_commit();

data process....

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_commit(), tx_open(), tx_rollback(), tx_set_transaction_timeout()

9.8.2. tx_commit

서버/클라이언트에서 사용하는 함수로 전역 트랜잭션을 commit한다.

transaction_control이 TX_UNCHAINED인 경우 tx_commit()이 반환할 때 호출자는 더 이상 트랜잭션 모드

에 있지 않다. transaction_control 특성이 TX_CHAINED인 경우, tx_commit()이 반환할 때 호출자는 새로

운 트랜잭션을 위하여 트랜잭션 모드로 남아있게 된다. transaction_control 특성에 대한 자세한 내용은

“9.8.5. tx_set_transaction_control”을 참고한다.

● 프로토타입

제9장 클라이언트 API 121

Page 140: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

# include <tx.h>

int tx_commit (void)

● 반환값

설명반환값

함수 호출에 성공한 경우TX_OK

함수 호출에 실패한 경우음수

● 오류

tx_commit()이 실패하는 경우 음수값을 반환한다.

설명에러 코드

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 성공적으로 commit된다. 그러나 새로운 트랜잭션은 시작될 수 없고 호

출자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_NO_BEGIN]

트랜잭션이 rollback된다. transaction_control 특성이 TX_CHAINED라면, 새

로운 트랜잭션이 시작된다.

[TX_ROLLBACK]

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 rollback된다. 이 에러가 발생하는 경우 새로운 트랜잭션은 시작될 수 없

고 호출자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_ROLL

BACK_NO_BEGIN]

에러 때문에 트랜잭션이 일부는 commit되거나 일부는 rollback된다. transac

tion_control 특성이 TX_CHAINED라면 새로운 트랜잭션이 시작된다.

[TX_HAZARD]

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 일부는 commit되거나 일부는 rollback된다. 새로운 트랜잭션은 시작될

수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_HAZARD_NO_BE

GIN]

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 트랜잭션 모드

에 있지 않는 경우이다. 트랜잭션과 관련된 호출자의 상태는 변함없다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자나 자원 관리자가 더 이상 애플리

케이션을 위하여 작업할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라

다르다. 트랜잭션과 관련된 호출자의 상태는 알 수 없다.

[TX_FAIL]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

void main(int argc, char *argv[])

{

122 Tmax Application Development Guide

Page 141: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char *buf;

int ret,cd;

long len, revent;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process.…

ret=tx_set_transaction_timeout( 5 );

if (ret<0) { error processing }

ret=tx_begin();

if (ret<0) { error processing }

cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY);

if (cd==-1) { error processing }

ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)};

if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback();

else tx_commit();

data process....

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_begin(), tx_set_commit_return(), tx_set_transaction_control(), tx_set_transaction_timeout()

9.8.3. tx_rollback

서버/클라이언트에서 사용하는 함수로 전역 트랜잭션을 rollback한다.

transaction_control 특성이 TX_UNCHAINED인 경우, tx_rollback()이 반환할 때 호출자는 더 이상 트랜잭

션 모드에 있지 않다. transaction_control 특성이 TX_CHAINED인 경우, tx_rollback()이 반환할 때 호출자

는 새로운 트랜잭션을 위하여 트랜잭션 모드로 남아있게 된다. transaction_control 특성에 대한 자세한 내

용은 “9.8.5. tx_set_transaction_control”을 참고한다.

● 프로토타입

#include <tx.h>

int tx_rollback (void)

● 반환값

제9장 클라이언트 API 123

Page 142: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

함수 호출에 성공한 경우TX_OK

함수 호출에 실패한 경우음수

● 오류

tx_rollback()이 실패하는 경우 음수값 중 하나를 반환한다.

설명에러 코드

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 rollback된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜

잭션 모드에 있지 않다.

[TX_NO_BEGIN]

트랜잭션이 일부는 commit되고 일부는 rollback된다. transaction_control 특

성이 TX_CHAINED라면 새로운 트랜잭션을 시작한다.

[TX_MIXED]

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 일부는 commit되고 일부는 rollback된다. 새로운 트랜잭션은 시작될 수

없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_MIXED_NO_BEGIN]

에러로 인하여 트랜잭션이 일부는 commit되거나 일부는 rollback된다. trans

action_control 특성이 TX_CHAINED라면 새로운 트랜잭션이 시작된다.

[TX_HAZARD]

transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭

션이 일부는 commit되거나 일부는 rollback된다. 새로운 트랜잭션은 시작될

수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_HAZARD_NO_BE

GIN]

트랜잭션이 독자적으로 commit된다. transaction_control 특성이 TX_CHAINED

인 경우, 새로운 트랜잭션이 시작된다.

[TX_COMMITTED]

transaction_control 특성이 TX_CHAINED일 때만 발생될 수 있는 에러로 트

랜잭션이 독자적으로 commit된다. 새로운 트랜잭션은 시작될 수 없고 호출

자는 더 이상 트랜잭션 모드에 있지 않다.

[TX_COMMIT

TED_NO_BEGIN]

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 트랜잭션 모드

에 있지 않다. 트랜잭션과 관련된 호출자의 상태는 변함없다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자나 자원 관리자는 더 이상 애플리

케이션을 위한 작업을 실행할 수 없다. 에러의 정확한 원인은 제품의 특성에

따라 다르다. 트랜잭션과 관련된 호출자의 상태는 알 수 없다.

[TX_FAIL]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

void main(int argc, char *argv[])

{

124 Tmax Application Development Guide

Page 143: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char *buf;

int ret,cd;

long len, revent;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process.…

ret=tx_set_transaction_timeout( 5 );

if (ret<0) { error processing }

ret=tx_begin();

if (ret<0) { error processing }

cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY);

if (cd==-1) { error processing }

ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)};

if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback();

else tx_commit();

data process....

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_begin(), tx_set_transaction_control(), tx_set_transaction_timeout()

9.8.4. tx_set_transaction_timeout

서버/클라이언트에서 transaction_timeout 설정 함수로 transaction_timeout 특성을 타임아웃 값으로 설정

한다. 설정된 값은 트랜잭션 타임아웃이 발생하기 전에 트랜잭션을 완료해야 하는 시간으로 tx_begin()과

tx_commit(), 또는 tx_begin()과 tx_rollback() 사이의 시간이다.

tx_set_transaction_timeout()는 함수 호출자가 트랜잭션 모드에 있는지와 상관없이 호출 가능하다.

tx_set_transaction_timeout()이 트랜잭션 모드에서 호출된다면, 새로운 타임아웃 값은 다음 트랜잭션부터

적용된다.

● 프로토타입

# include <tx.h>

int tx_set_transaction_timeout (TRANSACTION_TIMEOUT timeout)

제9장 클라이언트 API 125

Page 144: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 파라미터

설명파라미터

트랜잭션 타임아웃이 발생하기 전까지 허용된 시간을 초단위 숫자로 지정한

다. 설정값은 시스템별로 정의된 long 타입의 최대값까지 설정가능하다.

timeout

초기값은 0으로 설정되고 0으로 설정되면 타임아웃 제한이 없다.

● 반환값

설명반환값

함수 호출에 성공한 경우TX_OK

함수 호출에 실패한 경우음수

● 오류

tx_set_transaction_timeout()은 기존의 transaction_timeout값 변경없이 음수값 중 하나를 반환한다.

설명에러 코드

지정된 타임아웃 값이 유효하지 않다.[TX_EINVAL]

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 아직 tx_open()

을 호출하지 않았다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자가 더 이상 애플리케이션을 위한

작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.

[TX_FAIL]

● 예제

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

void main(int argc, char *argv[])

{

int ret;

long len;

char *buf;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) {error processing };

ret=tx_set_transaction_timeout( 5 );

if (ret<0) { error processing }

126 Tmax Application Development Guide

Page 145: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tx_begin();

if (ret<0) { error processing }

ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf, &len,

TPNOFLAGS);

if (ret == -1) {

tx_rollback();

error processing

}

data process ….

ret = tx_commit();

if (ret < 0) { error processing }

data process...

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_begin(), tx_commit(), tx_open(), tx_rollback(), tx_info()

9.8.5. tx_set_transaction_control

서버/클라이언트에서 transaction_control 특성을 control값으로 설정하는 함수이다. 특성은 tx_commit()

과 tx_rollback()이 호출자에게 반환하기 전에 새로운 트랜잭션을 시작할지 여부를 결정한다.

tx_set_transaction_control()는 애플리케이션이 트랜잭션 모드에 있는지 여부와 관계없이 호출 가능하다.

이 설정은 tx_set_transaction_control() 재호출에 의해 변경될 때까지 유효하게 적용된다.

● 프로토타입

# include <tx.h>

int tx_set_transaction_control (TRANSACTION_CONTROL control)

● 파라미터

control로 사용 가능한 값은 다음과 같다.

설명설정값

tx_commit()과 tx_rollback()이 함수 호출자에게 반환하기 전에 새로운 트랜잭

션을 시작하지 않도록 한다. 이 경우 호출자는 새로운 트랜잭션을 시작하려

면 tx_begin()을 실행해야 한다. transaction_control 특성의 초기 설정값이다.

TX_UNCHAINED

제9장 클라이언트 API 127

Page 146: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

tx_commit()과 tx_rollback()이 호출자에게 반환하기 전에 새로운 트랜잭션을

시작하도록 한다.

TX_CHAINED

● 반환값

설명반환값

함수 호출에 성공한 경우TX_OK

함수 호출에 실패한 경우음수

● 오류

tx_set_transaction_control()은 기존의 transaction_control 특성 변경없이, 음수값을 반환한다.

설명에러 코드

control 인수가 TX_UNCHAINED나TX_CHAINED로 설정되지 않았다.[TX_EINVAL]

함수가 부적절한 상황에서 호출되었다. 예를 들어, 함수 호출자가 아직

tx_open()을 호출하지 않았다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한

작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.

[TX_FAIL]

● 예제

...

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

int main(int argc, char *argv[])

{

int ret;

long len;

char *buf;

ret = tpstart((TPSTART_T *)NULL);

if (ret == -1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

ret = tx_set_transaction_timeout(5);

if (ret < 0){ error processing }

ret = tx_set_transaciont_control(TX_UNCHAINED);

if (ret < 0){ error processing }

ret = tx_begin();

if (ret < 0) { error processing }

128 Tmax Application Development Guide

Page 147: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

data process....

ret = tpcall(“SERVICE1”, (char *)buf, strlen(buf), (char **)&buf, &len,

TPNOFLAGS);

if (ret == -1)

{

tx_rollback();

error processing

}

data process...

ret = tpcall(“SERVICE2”, (char *)buf, strlen(buf), (char **)&buf, &len,

TPNOFLAGS);

if (ret == -1)

{

tx_rollback();

error processing

}

data process ….

ret = tx_commit();

if (ret < 0) { error processing }

data process...

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_begin(), tx_commit(), tx_open(), tx_rollback(), tx_info()

9.8.6. tx_set_commit_return

서버/클라이언트에서 commit_return 특성을 설정하는 함수로 when_return값으로 반환한다. commit_return

특성은 tx_commit()이 함수 호출자에게 제어권을 반환하는 방식을 결정한다. tx_set_commit_return()은

함수 호출자가 트랜잭션 모드에 있는 것과 관계 없이 호출가능하다. 설정은 tx_set_commit_return() 재호

출로 인해 변경될 때까지 유효하게 적용된다. commit_return 특성에 대한 초기 설정은 실행에 따라 다르

다.

● 프로토타입

#include <tx.h>

int tx_set_commit_return (COMMIT_RETURN when_return)

제9장 클라이언트 API 129

Page 148: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 파라미터

when_return으로 사용 가능한 값은 다음과 같다.

– TX_COMMIT_DECISION_LOGGED

tx_commit()이 2PC(Two-Phase Commit) 프로토콜 중 1번째 단계에서 로깅 된 후, 아직 2번째 단계는

완료되기 전에 반환하도록 한다. tx_commit()이 호출자에게 보다 빠르게 응답할 수 있지만, 트랜잭션

이 독자적(heuristic)인 결과를 갖게 될 위험이 있고, 그런 경우에 호출자는 tx_commit()으로부터 반환

된 코드로 발생된 상황을 제대로 알 수 없다.

정상적인 경우, 첫 번째 단계에서 트랜잭션을 commit하기로 한 트랜잭션 참여자는 2번째 단계에서

제대로 commit하게 된다. 그러나 네트워크나 노드 장애가 길게 지속되는 등의 비정상적인 경우에는

2단계 완료가 가능하지 않을 수 있으며, 독자적인 결과를 초래할 수도 있다. 트랜잭션 관리자는 옵션

으로 이 특성을 지원하지 않도록 선택할 수 있으며, 이 값을 지원하지 않음을 나타내는

[TX_NOT_SUPPORTED] 값으로 반환한다.

– TX_COMMIT_COMPLETED

2PC 프로토콜이 완전하게 종료된 후에 tx_commit()이 반환한다. 설정은 트랜잭션이 독자적인

(heuristic) 결과를 갖게 되었거나 또는 그럴 가능성을 알리는 반환 코드를 tx_commit()의 호출자에게

전달한다. 트랜잭션 관리자는 옵션으로 이 특징을 지원하지 않도록 선택할 수 있으며, 이 값을 지원하

지 않음을 나타내는 [TX_NOT_SUP-PORTED] 값으로 반환한다.

● 반환값

성공적인 완료된 경우 tx_set_commit_return()은 음 아닌 값의 [TX_OK]를 반환한다.

when_return이 TX_COMMIT_COMPLETED 또는 TX_COMMIT_DECISION_LOGGED으로 설정되지

않았다면, 함수는 음이 아닌 값으로 [TX_NOT_SUPPORTED]를 반환하고, commit_return 특성은 현재

적용되고 있는 값이 여전히 유효하다. 트랜잭션 관리자는 when_return을 최소한 TX_COMMIT_COM

PLETED나 TX_COMMIT_DECISION_LOGGED 중의 하나로는 설정해야 한다.

● 오류

tx_set_commit_return()는 commit_return 특성 설정 변경없이 음수값 중 하나를 반환한다.

설명에러 코드

when_return이 TX_COMMIT_COMPLETED나 TX_COMMIT_DECI

SION_LOGGED로 설정되어 있지 않다.

[TX_EINVAL]

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 아직 tx_open()

을 호출하지 않았다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한

작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.

[TX_FAIL]

130 Tmax Application Development Guide

Page 149: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 예제

...

#include <usrinc/tx.h>

int main(int argc, char *argv[])

{

int ret;

long len;

char *buf;

ret = tpstart((TPSTART_T *)NULL);

if (ret == -1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

ret = tx_set_transaction_timeout(5);

if (ret < 0){ error processing }

ret = tx_set_commit_return(TX_COMMIT_COMPLETED);

if (ret < 0){ error processing }

ret = tx_begin();

if (ret < 0){ error processing }

data process....

ret = tpcall(“SERVICE1”, (char *)buf, strlen(buf), (char **)&buf, &len,

TPNOFLAGS);

if (ret == -1)

{

tx_rollback();

error processing

}

data process...

ret = tpcall(“SERVICE2”, (char *)buf, strlen(buf), (char **)&buf, &len,

TPNOFLAGS);

if (ret == -1)

{

tx_rollback();

error processing

}

data process ….

ret = tx_commit();

if (ret < 0) { error processing }

data process...

tpfree((char *)buf);

제9장 클라이언트 API 131

Page 150: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

}

● 관련함수

tx_commit(), tx_open(), tx_info()

9.8.7. tx_info

서버/클라이언트에서 전역 트랜잭션 정보를 반환하는 함수이다. tx_info() 함수는 info가 가리키는 구조체

를 통하여 전역 트랜잭션 정보를 알려준다. 또한 호출자가 현재 트랜잭션 모드에 있는지 없는지를 알려주

는 값을 반환한다.

● 프로토타입

#include <tx.h>

int tx_info (TXINFO *info)

● 파라미터

info가 NULL이 아니라면 info가 가리키는 TXINFO 구조체는 전역 트랜잭션에 관한 정보가 된다.

TXINFO구조체는 아래와 같이 구성되어 있다.

XID xid;

COMMIT_RETURN when_return;

TRANSACTION_CONTROL transaction_control;

TRANSACTION_TIMEOUT transaction_timeout;

TRANSACTION_STATE transaction_state;

tx_info()가 트랜잭션 모드에서 호출된다면, xid는 현재 트랜잭션 branch id가 되고 transaction_state는

현재 트랜잭션의 상태가 된다. 호출자가 트랜잭션 모드에 있지 않다면, xid는 NULL XID가 된다(자세한

내용은 <tx.h>를 참조한다.)

호출자가 트랜잭션 모드에 있는 것과 관계없이 when_return, transaction_control, 그리고 transaction_time

out은 commit_return의 현재 설정과 transaction_control 특성, 그리고 초단위의 트랜잭션 타임아웃 값

을 포함한다.

반환된 트랜잭션 타임아웃 값은 다음 트랜잭션이 시작될 때부터 사용된다. 그것은 호출자의 현재 전역

트랜잭션에 대한 타임아웃 값이 아닐 수도 있다. 현재 트랜잭션이 시작된 후에 tx_set_transaction_timeout()

호출을 통해 트랜잭션 타임아웃 값을 변경했을 수도 있기 때문이다. info가 NULL이라면 TXINFO 구조

체는 반환되지 않는다.

같은 전역 트랜잭션 내에서, 계속적인 tx_info() 호출은 동일한 gtrid(글로벌 트랜잭션 구분자)의 XID 제

공을 보장한다. 하지만 반드시 동일한 bqual(로컬 트랜잭션 구분자)을 보장하지는 않는다. 따라서 xid는

동일하지 않을 수 있다.

132 Tmax Application Development Guide

Page 151: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 반환값

설명반환값

함수 호출에 성공한 경우1

(호출자가 트랜잭션 모드에 있는 경우 )

호출에 성공한 경우0

(호출자가 트랜잭션 모드에 있지 않은 경우 )

함수 호출에 실패한 경우음수

● 오류

tx_info()가 실패하는 경우 음수값을 반환한다.

설명에러 코드

함수가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 아직 tx_open()

을 호출하지 않았다.

[TX_PROTOCOL_ER

ROR]

치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한

작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.

[TX_FAIL]

● 예제

#include <stdio.h>

#include <string.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

void main(int argc, char *argv[])

{

int ret;

long len;

char *buf;

TXINFO info;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process....

ret=tx_begin();

if (ret<0) { error processing }

제9장 클라이언트 API 133

Page 152: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tpcall(“SERVICE”, buf, 20, (char **)&buf, &len, TPNOFLAGS);

if (ret==-1) { error processing }

if (tx_info(&info)==1) printf(“In transaction \n”);

else printf(“Not in transaction \n”);

if (strncmp(buf, “err”, 3)==0) tx_rollback();

else tx_commit();

data process....

tpfree((char *)buf);

tpend();

}

● 관련함수

tx_open(), tx_set_commit_return(), tx_set_transaction_control(), tx_set_transaction_timeout()

9.9. RQ 시스템RQ에서 사용하는 함수에 대해 설명한다.

Tmax 시스템은 신뢰성 있는 큐를 위하여 RQ를 제공하는데, RQ에 데이터를 Enqueue/Dequeue하는 큐

관리 프로세스로 ENQSVR이 동작한다. (Windows NT 또는 2000 환경에서는 사용할 수 없다.)

시스템의 장애나 오류로 인한 서비스가 불가능한 상태에서도 큐에 저장된 데이터는 정합성을 보장받을

수 있다. 주로 여러 대의 서버가 WAN 환경으로 구축되었거나 업무 폭주로 인한 작업량이 많은 경우 RQ

를 이용하면 데이터의 신뢰성을 보장받으면서 업무가 처리될 수 있다.

9.9.1. tpenq

서버/클라이언트에서 RQ에 데이터를 저장하는 함수이다. Tmax 시스템은 시스템의 장애나 에러로 인한

서비스가 불가능한 상태에서도 RQ에 저장된 데이터는 정합성을 보장할 수 있다. RQ에 데이터를 저장해

두었다가, 여러 가지 상황으로 시스템이 다운되고, 복구 이후 다시 실행 되면 이전에 처리하지 못한 데이

터를 계속해서 처리할 수 있다.

tpcall()이나 tpacall()로 서비스를 요청한 경우, 해당 서비스가 수행할 데이터가 누적되어 있다면 서비스

를 요청한 데이터도 대기(waiting)한다. 이 때 시스템의 장애나 에러로 인해 시스템이 다운되면 대기중인

데이터는 분실되게 된다.

이러한 문제점을 보안하고 데이터의 정합성을 보장할 수 있도록 tpenq()는 서비스를 요청하는 경우 데이

터를 RQ에 저장한다. 트랜잭션 모드에서 수행해도, 트랜잭션 모드에서 제외되기 때문에 트랜잭션 모드에

서 함수를 수행도중 에러가 발생해도 트랜잭션에는 영향을 미치지 않는다.

● 프로토타입

# include <tmaxapi.h>

int tpenq (char *qname, char *svc, char *data, long len, long flags)

134 Tmax Application Development Guide

Page 153: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 파라미터

설명파라미터

qname은 데이터를 저장할 RQ의 이름으로 config 파일에 등록된 이름이어야

한다.

qname

데이터를 RQ에 저장하고, svc명이 NULL이 아니면 즉시 서비스를 요청한다.svc

svc 명이 NULL이면 데이터는 RQ에 저장되고 서비스는 수행되지 않는다. 이

경우 나중에 tpdeq()를 이용하여 서비스를 요청해야 한다.

그러나 svc로 명명된 서비스가 없거나 또는 서비스를 수행하고 처리 결과를

받지 않은 상태에서 시스템 장애가 발생할 경우에 이 데이터는 내부적으로

fail 큐에 저장된다. 데이터는 tpdeq()로 서비스를 재요청하거나 에러 처리를

해야 한다.

NULL 값인 경우를 제외하고 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터

이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유

형들이어야 한다.

data

송신하는 데이터의 길이이다.len

- data가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 버퍼 유형(STRING,

STRUCT, X_COMMON, X_C_TYPE)인 경우 len은 무시되고 0이 사용된다.

- data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET,

CARRAY, MULTI STRUCTURE)인 경우 len은 0이 될 수 없다.

- data가 NULL인 경우 len은 무시되고 데이터 없이 서비스 요청이 송신된다.

flags로 사용 가능한 값은 다음과 같다.

설명설정값

- svc가 NULL이 아닌 경우 svc로 명명된 서비스를 요청하고, 처리 결과를 RQ

에 저장된다. 서비스 처리 결과는 tpdeq()를 이용해서 받는다.

TPRQS

- svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않

는다.

- svc가 NULL이 아닌 경우 svc로 명명된 서비스는 요청하지만, 처리 결과는

RQ에 저장하지 않겠다는 의미이다.

TPNOREPLY

- svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않

는다.

서비스별 RQ 데이터를 관리 할 때 사용한다.TPFUNC

제9장 클라이언트 API 135

Page 154: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

플래그가 설정 되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거(de

queued)된다. 데이터가 저장되기 전에 dequeue 해야 할 경우에는 tpenq() 호

출할 때 TPFUNC를 같이 설정한다.

서비스 처리 결과를 RQ에 저장하지 않고, 함수 호출자가 접속되어 있는 Tmax

시스템의 클라이언트 버퍼에 저장한다. 서비스는 RQ를 통해 요구하지만 결

0(zero)

과는 tpcall()처럼 함수 호출자가 접속한 클라이언트의 버퍼에서 가져올 때 사

용한다.

나중에 처리 결과를 받기 위해서는 tpdeq() 호출할 때 flags에 0(zero)을 설정

해야 한다.

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpenq()가 실패하는 경우 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

예를 들어, 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나, 또는

flags가 유효하지 않다.

존재하지 않는 qname이 사용되었다.[TPENOENT]

지속적인 서비스 결과로 지정된 큐의 크기를 넘는 경우에 발생한다.[TPEQFULL]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

tpenq()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

136 Tmax Application Development Guide

Page 155: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

void main(int argc, char *argv[])

{

int ret;

char *buf;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS);

if (ret==-1) { error processing }

data process....

ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS);

if (ret==-1) { error processing }

data process....

tpfree(buf);

tpend();

}

● 관련 함수

tpdeq(), tpqstat()

9.9.2. tpdeq

서버/클라이언트에서 RQ로부터 데이터를 로드하는 함수이다. tpenq()를 이용하여 서비스를 요청한 결과

를 받거나 서비스명을 NULL로 해서 저장한 데이터를 읽는다. tpenq() 호출할 때 flags에 TPNOREPLY를

설정하면 서비스는 결과를 받을 수 없다. 그러므로 트랜잭션 모드에서 tpdeq() 함수를 수행 도중 에러가

발생해도 트랜잭션에는 영향을 미치지 않는다.

● 프로토타입

# include <tmaxapi.h>

int tpdeq (char *qname, char *svc, char **data, long *len, long flags)

● 파라미터

설명파라미터

데이터를 저장할 RQ의 이름으로 환경파일에 등록된 이름이어야 한다.qname

tpenq()를 호출하는 경우 svc에 전달한 이름이어야 한다.svc

제9장 클라이언트 API 137

Page 156: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

서비스명으로 tpenq()를 호출한 경우, 서비스가 자동 요청되고, 결과가 RQ에

저장된다. 서비스 결과를 받기 위해서는 tpdeq()도 동일한 서비스명을 입력

해야 한다. 서비스명을 NULL로 tpenq()를 호출한 경우 tpdeq()도 동일한 서

비스명을 입력한다. 서비스명이 NULL인 경우 서비스명에 상관없이 큐에 쌓

여있는 모든 데이터를 하나씩 로드할 수 있다.

tpenq()를 수행할 때 에러나 시스템 장애로 인해 fail 큐에 저장된 데이터를

tpdeq() 하기 위해서는 svc에 _rq_sub_queue_name[TMAX_FAIL_QUEUE]

를 주고 deq해야 한다.

tpalloc()에 의해 할당된 버퍼에 대한 포인터이다. 함수가 성공적으로 반환되

면 *data는 수신된 데이터가 저장된다.

*data

tpdeq()가 성공적으로 수신한 데이터의 길이이다. tpdeq()는 필요하다면 응답

내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다. len은 *data

len

의 데이터의 길이로 *data는 수신 데이터가 커서 변경 될 수도 있고, 이 외에

다른 이유에 의해서도 변경될 수 있다. len이 호출 전 버퍼의 총 크기보다 크

다면 len이 그 버퍼의 새로운 크기가 된다.

len이 0으로 반환되었다면 어떤 데이터도 수신되지 않고 *data와 len이 지시

하는 버퍼 모두 아무런 변화가 없다. *data나 len이 NULL이 되는 것은 에러이

다.

flags로 사용 가능한 값은 다음과 같다.

설명설정값

RQ에서 데이터를 가져올 때 사용된다. reply 큐로부터 서비스의 결과를 가져

오기 위해서 설정된다.

TPRQS

서비스별 RQ 데이터를 관리할 때 사용한다. 플래그가 설정 되지 않았다면 처

음 tpenq()를 통해 저장된 데이터가 제거된다.

TPFUNC

데이터가 저장되기 전에 제거해야 할 경우에는 tpenq() 호출할 때 TPFUNC

를 같이 설정한다.

tpdeq() 호출할 때 블로킹 타임아웃 시간동안 메시지가 올 때까지 기다린다TPBLOCK

TPBLOCK과 함께 사용되면 블로킹 타임아웃 시간에 관계없이 응답이 올 때

까지 기다린다.

TPNOTIME

데이터를 자신이 접속한 클라이언트의 버퍼에서 가져오고자 할 때 사용한다.0(zero)

● 반환값

138 Tmax Application Development Guide

Page 157: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다)

● 오류

tpdeq()가 실패할 경우 상황에 따라 tperrno에 다음 에러 값들이 설정된다.

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

예를 들어, 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는

flags가 유효하지 않다.

TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.[TPGOTSIG]

서비스 이름이 잘못 되었거나 제거할 데이터가 없는 경우 해당 조건을 만족

하는 제거할 데이터를 찾지 못했다.

[TPEMATCH]

존재하지 않는 qname이 사용되었다.[TPENOENT]

tpdeq()이 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

void main(int argc, char *argv[])

{

int ret;

char *buf;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS);

if (ret==-1) { error processing }

data process....

ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS);

제9장 클라이언트 API 139

Page 158: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (ret==-1) { error processing }

data process....

tpfree(buf);

tpend();

}

● 관련 함수

tpenq(), tpqstat()

9.9.3. tpqstat

서버/클라이언트에서 사용되는 함수로 RQ에 저장된 데이터의 통계를 요청한다. RQ는 내부적으로 _fail

queue, _request queue, _reply queue의 3 부분으로 구성되어있다. 플래그 값을 이용하여 각 큐에 저장된

데이터 통계를 구할 수 있다.

● 프로토타입

# include <tmaxapi.h>

int tpqstat (char *qname, long flags )

● 파라미터

설명파라미터

Tmax 환경파일에 등록된 RQ 이름을 나타낸다.qname

다음은 flags로 사용 가능한 값들이다.

설명설정값

_fail queue, _request queue, _reply queue의 데이터 통계를 낼 때 사용한다.0

_fail queue의 데이터 통계를 낼 때 사용한다.1

_request queue의 데이터 통계를 낼 때 사용한다.2

_request queue의 데이터 통계를 낼 때 사용한다.3

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당되는 값이 설정된다.)

● 오류

140 Tmax Application Development Guide

Page 159: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpqstat()에 실패하는 경우 상황에 따라 tperrno에 아래값이 설정된다.

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

예를 들어, qname이 NULL이거나, qname에 해당하는 큐가 없거나 flags가

유효하지 않다.

tpqstat()가 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

void main(int argc, char *argv[])

{

int ret, i;

char *buf;

if (argc!=2) { error processing }

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) {error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

strcpy(buf, argv[1]);

data process…

ret=tpenq(“RQ”, NULL, (char *)buf, strlen(buf), TPRQS);

if (ret==-1) {error processing }

printf(“qstat :”);

for (i=0;i<4;i++) {

ret=tpqstat(“rq”, i);

if (ret==-1) {error processing }

printf(“ %d”,ret); /* qstat : 1 0 0 1 */

}

printf(“\n”);

data process…

ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS);

if (ret==-1) {error processing }

printf(”qstat :”);

for (i=0;i<4;i++) {

제9장 클라이언트 API 141

Page 160: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tpqstat(“rq”, i);

if (ret==-1) {error processing }

printf(” %d”,ret); /* qstat : 2 0 0 2 */

}

printf(“\n”);

tpfree((char *)buf);

tpend();

}

● 관련함수

tpenq(), tpdeq()

9.9.4. tpextsvcname

서버/클라이언트에서 tpdeq()로 RQ에서 데이터를 읽은 경우, 해당 데이터의 서비스명을 알고자 할 때 사

용한다. tpextsvcname() 함수는 _fail 큐에 저장되어 있는 데이터를 tpdeq()로 읽은 경우에 사용한다.

● 프로토타입

# include <tmaxapi.h>

int tpextsvcname (char *data, char *svc )

● 파라미터

설명파라미터

tpdeq() 함수를 이용하여 RQ로부터 읽은 데이터가 저장되어 있는 포인터이

다. tpalloc()으로 할당된다.

data

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpextsvcname()이 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

142 Tmax Application Development Guide

Page 161: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

예를 들면 data에 tpalloc()으로 할당되지 않은 버퍼가 전달되는 경우이다.

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

void main(int argc, char *argv[])

{

int ret;

char *buf, *svc_name;

long len;

ret=tpstart((TPSTART_T *)NULL);

if (ret==-1) { error processing }

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS);

if (ret==-1) { error processing }

data process....

ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS);

if (ret==-1) { error processing }

ret=tpextsvcname(buf, svc_name);

if (ret==-1) { error processing }

printf(“svc name : %s ,”,svc_name);

data process....

tpfree(buf);

tpend();

}

● 관련 함수

tpenq(), tpdeq()

제9장 클라이언트 API 143

Page 162: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.10. 이벤트를 활용하는 APITmax는 이벤트를 통해 다수의 클라이언트 뿐만 아니라 서비스 루틴에도 메시지를 보낼수 있다. 모든 클

라이언트와 서비스 루틴은 개발자 임의로 이벤트에 가입하거나 취소할 수 있고 이벤트를 발생시킬 수 있

다. 또한 하나의 이벤트에 중복 가입하거나 동시에 여러가지 이벤트에 가입할 수도 있다.

발생된 이벤트에 의한 이벤트 데이터 전송과 그에 따른 결과는 트랜잭션의 범주에 들지 않으므로 주의하

도록 한다.

9.10.1. tpsubscribe

서버/클라이언트에서 사용되는 함수로 특정 사건의 메시지에 대한 요청을 등록한다. 특정 사건의 발생시

점에 클라이언트나 서버로 부터 데이터를 전달받기 위한 요청을 등록하는 함수이다. eventname에 해당

하는 사건이 발생하면 알려 달라는 것을 Tmax 시스템에 등록하는 함수이다.

● 프로토타입

# include <tmaxapi.h>

long tpsubscribe(char *eventname, char *filter, TPEVCTL *ctl, long flags)

● 파라미터

설명파라미터

NULL로 끝나는 15자 이내의 문자열로 메시지를 받을 사건의 이름을 지정한

다. 와일드카드 문자나 partial-matching등은 지원이 되지 않으며 전체 문자열

이 일치하는 이름의 사건만을 등록할 수 있다.

eventname

앞으로 확장을 위하여 예약해 놓은 것으로 NULL을 지정한다.filter

사건이 발생하는 경우 메시지를 받아오는 방식을 지정하는 구조체로 tpsub

scribe()의 주체에 따라 다른 동작을 한다.

ctl

클라이언트에서 tpsubscribe()한 경우에 ctl은 항상 NULL이어야 하며 메시

지는 클라이언트에게 unsolicited 데이터 형태로 전달된다. 클라이언트는 tp

subscribe()이나 tpgetunsol() 등의 함수를 사용하여 전달된 데이터를 처리

한다.

현재 TPNOTIME만 의미가 있다.flags

서버에서 tpsubscribe()를 행하는 경우에는 ctl이 NULL이면 안되며 아래와 같은 내용을 가져야 한다.

struct tpevctl {

long ctl_flags;

long post_flags;

char svc[XATMI_SERVICE_NAME_LENGTH];

144 Tmax Application Development Guide

Page 163: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char qname[RQ_NAME_LENGTH];

};

typedef struct tpevctl TPEVCTL;

설명항목

앞으로 확장을 위하여 만들어진 것으로 현재는 0으로 채워야한다.ctl_flags

앞으로 확장을 위하여 만들어진 것으로 현재는 0으로 채워야한다.post_flags

qname을 사용할 경우 메시지는 tpenq(qname, NULL, data, len, TPNOFLAGS)

를 통해 RQ에 저장된다.

qname

svc를 사용할 경우 메시지는 tpacall(svc, data, len, TPNOREPLY)와 유사한

방식으로 서버에게 전달되며 서버의 반환값은 무시된다. qname과 svc는 둘

중 한가지만을 사용한다.

svc

● 반환값

설명반환값

함수 호출에 성공한 경우descriptor

(tpunsubscribe() 호출할 때에 사용될 descriptor를 반환한다.)

함수 호출에 실패한 경우-1

(상황에 따라 tperrno에 에러 값이 설정된다.)

● 오류

설명에러 코드

Tmax 시스템 에러가 발생하였다. 클라이언트의 경우 네트워크 에러가 가장

빈번히 발생한다.

[TPESYSTEM]

OS 레벨에서 발생하는 에러로 메모리 할당과 같은 문제를 포함한다.[TPEOS]

잘못된 인자를 사용하는 경우 발생하는 에러이다.[TPEINVAL]

TPEVCTL 구조체의 qname이나 svc에 해당하는 RQ나 서버가 존재하지 않

는 경우이다.

[TPENOENT]

클라이언트와 서버에서 tpsubscribe()를 수행하는 경우 ctl이 NULL이 아닌 경

우이다.

[TPEPROTO]

타임아웃이 발생한 경우이다.[TPETIME]

● 관련 함수

tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

제9장 클라이언트 API 145

Page 164: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.10.2. tpunsubscribe

서버/클라이언트에서 사용하는 함수로 특정 사건의 메시지에 대한 등록을 해제한다. tpunsubscribe()는

tpsubscribe()로 등록한 특정 사건에 대한 요청을 해제한다. 등록된 모든 요청이 해제되는 경우 Tmax 시

스템은 해당 사건의 테이블을 삭제한다.

● 프로토타입

# include <tmaxapi.h>

int tpunsubscribe(long sd, long flags)

● 파라미터

설명파라미터

tpsubscribe()로 등록할 때 받아온 반환값이다.sd

현재 TPNOTIME만 의미가 있다.flags

● 반환값

설명반환값

함수 호출에 성공한 경우양수

함수 호출에 실패한 경우음수

(상황에 따라 tperrno에 에러 값이 설정된다.)

● 오류

설명에러 코드

Tmax 시스템에서 에러가 발생하였다. 클라이언트의 경우 네트워크 에러가

가장 많이 발생한다.

[TPESYSTEM]

OS 레벨의 에러 발생한 경우로 메모리 할당과 같은 문제를 포함한다.[TPEOS]

잘못된 인자를 사용한 경우 발생한다.[TPEINVAL]

타임아웃이 발생한 경우이다.[TPETIME]

● 관련 함수

tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

146 Tmax Application Development Guide

Page 165: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.10.3. tppost

서버/클라이언트에서 특정 사건을 발생시키고 메시지를 전달하는 함수이다. tppost()는 이름이 eventname

인 사건에 tpsubscribe()로 등록된 모든 클라이언트/서버 프로세스에게 사건의 발생을 알리고 필요할 경

우 메시지를 전달하는 함수이다.

● 프로토타입

# include <tmaxapi.h>

int tppost(char *eventname, char *data, long len, long flags)

● 파라미터

설명파라미터

NULL로 끝나는 15자 이내의 문자열로 발생할 사건의 이름을 의미한다. 와일

드카드 문자나 partial-matching 등은 지원이 되지 않는다.

eventname

보낼 메시지에 대한 포인터로 tpalloc()에 의해 할당된 버퍼이어야 한다.data

송신하는 버퍼의 길이이다.len

- data의 길이 명시가 필요없는 버퍼를 가리키는 경우 len은 무시되고 보통 0

이 사용된다.

- data의 길이 명시가 반드시 필요한 버퍼를 가리키는 경우 len은 0이 될 수

없다.

- data가 NULL인 경우 len은 무시된다.

현재 TPNOTIME만 의미가 있다.flags

● 반환값

설명반환값

함수 호출에 성공한 경우양수

함수 호출에 실패한 경우음수

( 상황에 따라 tperrno에 에러 값이 설정된다.)

● 오류

설명에러 코드

Tmax 시스템 에러가 발생하였다. 클라이언트의 경우 네트워크 에러가 제일

빈번하다.

[TPESYSTEM]

OS 레벨의 에러 발생한다. 메모리 할당과 같은 문제를 포함한다.[TPEOS]

제9장 클라이언트 API 147

Page 166: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

잘못된 인자를 사용하는 경우이다.[TPEINVAL]

tpsubscribe()의 경우 TPEVCTL 구조체 내의 qname이나 svc에 해당하는 RQ

나 서버가 존재하지 않는 경우이다.

[TPENOENT]

클라이언트에서 tpsubscribe()를 수행하는 경우 ctl이 NULL이 아닌 경우나 서

버에서 수행하는 경우 ctl이 NULL인 경우 발생한다.

[TPEPROTO]

타임아웃이 발생한다.[TPETIME]

● 관련함수

tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()

9.11. 브로드 캐스트/멀티 캐스트Tmax는 다양한 방법으로 클라이언트에게 데이터를 전달할 수 있다. 관리나 기타 개발의 목적으로 다수의

클라이언트에게 데이터를 보내야 하는 경우 모든 클라이언트의 ID를 관리하여 각각 메시지를 보내는 것

도 한 방법이겠지만 시스템의 동시 사용자가 많은 경우 효율적인 방법이 되지 않는다.

다수의 클라이언트를 몇개의 그룹으로 구분할 수 있다면 하나의 API를 이용하여 해당되는 모든 클라이언

트에게 메시지를 보내는 것이 가능하다. Tmax는 클라이언트의 접속 정보를 활용하거나 이벤트를 이용하

는 방법으로 브로드 캐스트 및 멀티 캐스트를 구현하고 있다.

2개의 방식 모두 일반적인 의미의 브로드 캐스트 및 멀티 캐스트가 모두 가능하지만 구분의 편의상 전자

를 브로드 캐스트 API, 후자를 멀티 캐스트 API라고 부른다.

9.11.1. tpbroadcast

Tmax 시스템에 등록된 클라이언트들에게 요청하지 않은 메시지를 송신하는 함수이다. 메시지가 송신 가

능한 클라이언트들은 tpstart()로 이미 Tmax 시스템에 연결되어 있어야 하며, 이때 클라이언트의 이름과

플래그가 알맞게 정의되어야 한다. 비요청 메시지를 받기 위해서는 비요청 메시지를 받겠다는 정보를 주

어야 한다. tpstart()를 사용하는 경우 TPSTART_T 구조체의 플래그값을 TPUNSOL_POLL이나 TPUN

SOL_HND로 설정해야만 비요청 메시지를 받을 수 있다.

● 프로토타입

# include <atmi.h>

int tpbroadcast (char *nodename, char *usrname, char *cltname,

char *data, long len, long flags)

● 파라미터

148 Tmax Application Development Guide

Page 167: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

대상 클라이언트를 선택하는데 사용되는 논리적인 이름으로 15자 이내여야

한다.

nodename/

usrname/

이름 지정에는 물음표(?) 나 별표(*) 등의 와일드 카드(wildcards) 문자들이 사

용될 수 있다. NULL 값이 사용될 수 있는데, 이는 모든 클라이언트에 대응되cltname

는 와일드 카드로 동작한다. 길이가 0인 스트링 인수는 스트링 길이가 0인 클

라이언트 이름과만 대응된다.

cltname으로 사용되는 이름은, 클라이언트가 tpstart()를 이용하여 처음 Tmax

시스템에 연결할 때 등록하는 클라이언트 이름이다.

반드시 tpalloc()에 의해 이전에 할당된 버퍼를 사용하여야 한다.data

송신할 데이터 길이이다. data가 가리키는 버퍼가 특별한 길이 명시가 필요

없는 STRING, STRUCT, X_COMMON, X_C_TYPE 의 버퍼 유형이라면 len

은 무시되고 0이 사용된다. data가 NULL인 경우도 len은 무시된다.

len

다음은 flags로 설정 가능한 값에 대한 설명이다.

설명설정값

내부 버퍼가 송신 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을

만나면 요청이 송신되지 않는다.

TPNOBLOCK

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신 될 때까지 무한정

대기한다. 트랜잭션 타임아웃 내에서 tpbroadcast()를 한 경우에는 여전히

트랜잭션 타임아웃이 적용된다

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 내부에서 시그널 인

터럽트가 발생하여 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실

행된다.

TPSIGRSTRT

TPSIGRSTRT 플래그가 설정되지 않은 경우에 시그널 인터럽트가 발생하였

다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

제9장 클라이언트 API 149

Page 168: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpbroadcast()가 실패하는 경우 어떤 메시지도 클라이언트들에게 송신되지 않으며 tperrno에 아래 값 중

하나가 설정된다

설명에러 코드

인수가 유효하지 않다.[TPEINVAL]

예를 들어, 식별자 길이가 너무 길거나 플래그가 유효하지 않은 경우이다.

nodename를 잘못 사용한 경우, tpbroadcast()가 실패하고 TPEINVAL을 반

환하게 된다. 그러나 usrname이나 cltname이 잘못된 경우, 아무에게도 메시

지가 전달되지 않고 단순히 성공인 것으로 수행된다.

TPNOBLOCK이나 TPNOTIME이 설정되지 않은 상태에서, 블로킹 타임아웃

이 발생하였다.

[TPETIME]

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

tpbroadcast()가 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret;

char *buf;

TPSTART_T *tpinfo;

tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T));

if (tpinfo==NULL) { error processing }

strcpy(tpinfo->cltname, “cli1”);

strcpy(tpinfo->usrname, “navis”);

ret=tpstart(tpinfo);

if (ret==-1) { error processing }

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process…

tpbroadcast(“tmax”, NULL, NULL, buf, 0, TPNOFLAGS);

data process....

tpfree(buf);

150 Tmax Application Development Guide

Page 169: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

}

● 관련 함수

tpalloc(), tpend(), tpstart()

9.12. 환경 프로그램개발된 서비스가 일반 사용자를 위한 것일 경우 클라이언트 프로그램은 주로 개인 PC에 많이 사용되는

Windows 환경을 기반으로 하여 개발된다. Tmax는 이를 위해 다양한 개발툴을 위한 인터페이스를 제공한

다. 또한 개발자의 편의를 위해 다양한 종류의 라이브러리를 제공한다. 라이브러리에 따라 API가 추가되

었거나 대체되는 API가 있을 수 있다.

참고

Tmax가 지원하는 개발 툴은 PowerBuilder, Delphi, VC++, BC++, VB, VB .Net, C# .Net이며 각 개발

툴에 대한 자세한 사용법은 " Tmax Programming 4GL Guide" 를 참고한다.

다음은 지원 라이브러리에 대한 설명이다.

설명라이브러리

VC++, Delphi, C# 에 사용된다. (cdecl)tmax.lib (dll)

BC++, PowerBuilder, VB, VB.Net 에 사용된다. (stdcall)tmax4gl. lib (dll)

멀티 스레드 형태를 지원하기 위한 라이브러리이다. (cdecl)tmaxmt. lib (dll)

멀티 윈도우를 지원하기 위한 라이브러리이다. (cdecl)Wintmax. lib (dll)

윈도우 ce를 위한 라이브러리이다. (cdecl)tmaxce.lib (dll)

● tmaxmt.dll

윈도우 프로그래밍 환경에서 사용되는 Message-Driven 방식의 서비스 요청을 위해 2가지 API를 추가

하였다.

2개의 API는 거의 동일하며 지정한 Window로 메시지를 넘기느냐 지정한 콜백 함수로 넘기느냐 하는

차이가 있을 뿐이다. API를 수행할 때마다 스레드를 하나씩 생성하여 메시지를 처리한다. 헤더 파일은

tmaxpi.h 를 사용한다.

– WinTmaxAcall()

– WinTmaxAcall2()

● WinTmax.dll

제9장 클라이언트 API 151

Page 170: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

프로그래밍 환경에서 사용되는 Message-Driven 방식의 서비스 요청을 위한 API를 추가하였다. 독립적

인 스레드를 이용하여 메시지를 처리하므로 tpstart()나 tpend() 대신 WinTmaxStart(), WinTmaxEnd()를

사용한다.

– WinTmaxStart()

– WinTmaxEnd()

– WinTmaxSetContext ()

– WinTmaxSend ()

tmaxmt.dll과 유사한 방식으로 동작하지만 Tmax 시스템에 자동으로 접속/해제 작업을 하지 않으며 API

당 하나씩 스레드를 생성하는 대신 하나의 스레드로 모든 메시지를 처리한다. 에러 메시지와 비요청 메

시지를 처리하기 위해 따로 Window를 지정하지 않으면 메시지는 무시된다.

디버그 및 관리의 목적으로 MAX_DEBUG 환경 변수에 지정된 파일에 로그를 남길 수 있다. 헤더 파일

은 WinTmax.h를 사용한다.

9.12.1. WinTmaxAcall

Windows 시스템 환경에서 클라이언트사용하는 함수로 멀티 스레드 환경에서의 비동기 서비스의 송신 요

청한다. 멀티 스레드 환경에서 tpacall()과 같은 기능하는 함수로 새로운 스레드를 만들고, 스레드내에서

tpstart() → tpacall() → tpgetrply()를 수행한다. tpgetrply()를 호출한 후에는 SendMessage(wHandle,

msgType, (UINT) &msg, tperrno)를 호출하게 된다.

● 프로토타입

# include <tmaxapi.h>

int WinTmaxAcall(TPSTART_T *sinfo, HANDLE wHandle, unsigned int msgtype, char *svc,

char *sndbuf, int len, int flags)

● 파라미터

설명파라미터

Tmax 시스템에 클라이언트의 정보를 넘길 필요가 있을 경우 사용하는 구조

체로 tpstart()의 인수와 동일하다.

sinfo

메시지를 받을 윈도우의 핸들러를 지정한다.wHandle

도착 메시지를 지정한다. 일반적으로 WM_USER를 개발자 임의로 define하

여 사용한다. svc Tmax 환경파일에 등록된 서비스 이름을 지정한다.

msgtype

152 Tmax Application Development Guide

Page 171: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

서비스를 호출할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc()

으로 할당된 버퍼를 사용하여야 한다.

sndbuf

보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입

일 경우에는 반드시 설정해야 한다.

len

tpacall()의 플래그를 그대로 사용한다.flags

flags로 사용 가능한 값은 다음과 같다.

설명설정값

플래그없이 tpacall() 함수가 사용되었다면, svc에 호출된 서비스가 없거나 잘

못된 결과가 반환되었어도 정상적인 결과가 반환된다.

TPBLOCK

tpgetrply() 함수를 호출할 때 에러가 반환 된다. TPBLOCK 플래그를 이용해

tpacall() 함수 호출할 경우 서비스 상태의 정상 여부를 확인 할 수 있다.

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpacall()함

수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TPNOTRAN으로

설정해야 한다.

TPNOTRAN

tpacall() 함수 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc

서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된

다. 트랜잭션 모드 내에서의 tpacall()함수를 호출할 때, TPNOTRAN로 설정

되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다.

TPNOTRAN으로 호출된 서비스가 실패하였을 경우, 호출자의 트랜잭션에는

영향을 미치지 않는다.

tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과

는 나중에 tpacall() 함수에서 반환한 구별자를 이용하여 tpgetrply() 함수로 결

TPNOREPLY

과를 수신한다. flags가 TPNOREPLY로 설정하면 서비스에 대한 응답을 받

지 않는겠다고 설정된다. TPNOREPLY로 설정하면 tpacall() 함수는 서비스

가 정상적으로 호출되면 0을 반환한다.

함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN 플래그

와 함께 설정해야만 TPNOREPLY 플래그를 사용할 수 있다.

TPNOREPLY 플래그인 경우 서비스 상태의 정상 여부를 체크하기 위해서는

TPBLOCK 플래그를 함께 설정해야 한다. TPBLOCK 플래그를 설정하지 않

으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다.

내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황

을 만나면 서비스 요청은 실패하도록 설정하는 플래그이다.

TPNOBLOCK

제9장 클라이언트 API 153

Page 172: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

TPNOBLOCK 플래그 설정없이 tpacall() 함수가 호출된 경우 블로킹 상황이

발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아

웃 또는 블로킹 타임아웃)이 발생할 때까지 대기한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기하도록 설정하는 플래그이다. 트랜잭션 타임아웃 내에서 tpacall()을 한 경

우에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용하는 플래그이다.TPSIGRSTRT

시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT

가 설정되지 않은 상태에서 신호 인터럽트가 발생하였다면, 함수는 실패하고

tperrno에 TPGOTSIG가 설정된다

● 반환값

설명반환값

함수 호출이 성공한 경우1

(구별자(descriptor)를 반환하고 구별자는 송신된 서비스 요청에 대한 응답을

수신하는데 사용된다. )

함수 호출이 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

WinTmaxAcall()이 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다. 예를 들어, svc가 NULL이거나 데이터가 tpalloc()으로

할당되지 않은 버퍼를 가리키거나, 또는 플래그가 유효하지 않다.

[TPEINVAL]

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인경우 사

용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.

[TPEITYPE]

처리되지 않은 비동기성 서비스 요청수가 최대 한계에 도달했기 때문에, 호

출자의 서비스 요청이 송신되지 않았다.

[TPELIMIT]

트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가

실패하였다.

[TPETRAN]

타임아웃이 발생하였다.[TPETIME]

154 Tmax Application Development Guide

Page 173: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생한 것이며

트랜잭션은 rollback될 것이다. 그렇지 않다면 TPNOTIME이나 TPNOBLOCK

이 모두 설정되지 않은 상황에서 블로킹 타임아웃이 발생한 것이다. 트랜잭

션 타임아웃이 발생하는 경우 트랜잭션이 rollback될 때까지 새로운 서비스

요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두

[TPETIME] 에러로 실패한다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

트랜잭션 모드에서의 TPNOREPLY 서비스를 호출하는 경우 TPNOTRAN 플

래그를 설정하지 않는 경우 등 부적절한 상황에서 발생한다.

[TPEPROTO]

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

...

#include <usrinc/tmaxapi.h>

#define WM_WINTMAX_RECV WM_USER + 1

...

BEGIN_MESSAGE_MAP(CWinTmaxAcall2TestDlg, CDialog)

...

ON_MESSAGE(WM_WINTMAX_RECV, OnWinTmaxAcall)

...

END_MESSAGE_MAP()

BOOL CWinTmaxAcall2TestDlg::OnInitDialog()

{

CDialog::OnInitDialog();

...

ret = tmaxreadenv(“tmax.env”, “TMAX”);

if (ret == -1){

AfxMessageBox(“tmaxreadenv fail...”);

return FALSE;

}

return TRUE; // return TRUE unless you set the focus to a control

}

void CWinTmaxAcall2TestDlg::OnOK()

{

...

제9장 클라이언트 API 155

Page 174: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

GetDlgItemText(IDC_EDIT1, m_Input);

lstrcpy((LPTSTR)buf, (LPCTSTR)m_Input.operator const char *());

...

buf = tpalloc(“STRING”, NULL, 0);

if (buf == NULL){

AfxMessageBox(“buf alloc fail...”);

return FALSE;

}

ret = WinTmaxAcall((TPSTART_T *)NULL, m_hWnd, WM_WINTMAX_RECV,

“TOUPPER”, buf, 0, TPNOFLAGS);

if (ret == -1){

error processing

}

}

LRESULT CWinTmaxAcall2TestDlg::OnWinTmaxAcall(WPARAM wp, LPARAM lp)

{

char msg[100];

memset(msg, 0x00, 100);

TPSVCINFO *get = (TPSVCINFO *)wp;

if (lp < 0){

error processing

}

...

SetDlgItemText(IDC_EDIT2, get->data);

return 0;

}

● 관련 함수

tpacall(), WinTmaxAcall2()

9.12.2. WinTmaxAcall2

Windows 시스템 환경에서 클라이언트사용하는 함수로 멀티 스레드 환경에서의 비동기 서비스의 송신 요

청한다. 멀티 스레드 환경에서 tpacall()과 같은 기능하는 함수로 새로운 스레드를 만들고, 스레드내에서

tpstart() → tpacall() → tpgetrply()를 수행한다. tpgetrply()를 호출한 후에는 지정된 콜백 함수에게 수신

된 데이터를 전달한다.

● 프로토타입

# include <tmaxapi.h>

int WinTmaxAcall2(TPSTART_T *sinfo, WinTmaxCallback fn, char *svc,

char *sndbuf, int len, int flags)

156 Tmax Application Development Guide

Page 175: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 파라미터

설명파라미터

Tmax 시스템에 클라이언트의 정보를 넘길 필요가 있을 경우 사용하는 구조

체로 tpstart() 의 인수와 동일하다.

sinfo

서비스 요청에 대한 응답을 받을 콜백 함수를 지정한다.fn

Tmax 환경파일에 등록된 서비스 이름을 지정한다.svc

서비스를 호출 할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc()

으로 할당된 버퍼를 사용하여야 한다.

sndbuf

보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입

일 경우에는 반드시 설정해야 한다.

len

tpacall()의 플래그를 그대로 사용한다. 자세한 내용은 다음과 같다.flags

flags로 사용 가능한 값은 다음과 같다.

설명설정값

플래그없이 tpacall() 함수가 사용되었다면, svc에 호출된 서비스가 없거나 잘

못된 결과가 반환되었어도 정상적인 결과가 반환된다.

TPBLOCK

tpgetrply() 함수를 호출할 때 에러가 반환 된다. TPBLOCK 플래그를 이용해

tpacall() 함수 호출할 경우 서비스 상태의 정상 여부를 확인 할 수 있다.

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpacall()함

수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TPNOTRAN으로

설정해야 한다.

TPNOTRAN

tpacall() 함수 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc

서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된

다. 트랜잭션 모드 내에서의 tpacall()함수를 호출할 때, TPNOTRAN로 설정

되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다.

TPNOTRAN으로 호출된 서비스가 실패하였을 경우, 호출자의 트랜잭션에는

영향을 미치지 않는다.

tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과

는 나중에 tpacall() 함수에서 반환한 구별자를 이용하여 tpgetrply() 함수로 결

TPNOREPLY

과를 수신한다. flags가 TPNOREPLY로 설정하면 서비스에 대한 응답을 받

지 않는겠다고 설정된다. TPNOREPLY로 설정하면 tpacall() 함수는 서비스

가 정상적으로 호출되면 0을 반환한다.

함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN 플래그

와 함께 설정해야만 TPNOREPLY 플래그를 사용할 수 있다.

제9장 클라이언트 API 157

Page 176: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

TPNOREPLY 플래그인 경우 서비스 상태의 정상 여부를 체크하기 위해서는

TPBLOCK 플래그를 함께 설정해야 한다. TPBLOCK 플래그를 설정하지 않

으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다.

내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황

을 만나면 서비스 요청은 실패하도록 설정하는 플래그이다.

TPNOBLOCK

TPNOBLOCK 플래그 설정없이 tpacall() 함수가 호출된 경우 블로킹 상황이

발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아

웃 또는 블로킹 타임아웃)이 발생할 때까지 대기한다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대

기하도록 설정하는 플래그이다. 트랜잭션 타임아웃 내에서 tpacall()을 한 경

우에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용하는 플래그이다.TPSIGRSTRT

시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT

가 설정되지 않은 상태에서 신호 인터럽트가 발생하였다면, 함수는 실패하고

tperrno에 TPGOTSIG가 설정된다

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

WinTmaxAcall2()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다. 예를 들어, svc가 NULL이거나 data가 tpalloc()으로 할

당되지 않은 버퍼를 가리키거나, 또는 플래그가 유효하지 않다.

[TPEINVAL]

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우

사용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.

[TPEITYPE]

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우

사용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.

[TPEITYPE]

158 Tmax Application Development Guide

Page 177: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에, 호

출자의 서비스 요청이 송신되지 않았다.

[TPELIMIT]

svc는 트랜잭션을 지원하지 않는 서비스이고, 이때 TPNOTRAN이 설정되지

않았다.

[TPETRAN]

타임아웃이 발생하였다.[TPETIME]

함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생한 것이며

트랜잭션은 rollback될 것이다. 그렇지 않다면 TPNOTIME이나 TPNOBLOCK

이 모두 설정되지 않은 상황에서 블로킹 타임아웃이 발생한 것이다. 트랜잭

션 타임아웃이 발생한 경우 트랜잭션이 rollback될 때까지 새로운 서비스 요

청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두 [TPETIME]

에러로 실패한다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

트랜잭션 모드에서의 TPNOREPLY 서비스 호출할 때 TPNOTRAN 플래그를

설정하지 않는 경우 등 부적절한 상황에서 발생한다.

[TPEPROTO]

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

...

#include <usrinc/tmaxapi.h>

#define WM_WINTMAX_RECV WM_USER + 1

int mycallfn(unsigned int, long);

...

BEGIN_MESSAGE_MAP(CWinTmaxAcall2TestDlg, CDialog)

...

...

END_MESSAGE_MAP()

BOOL CWinTmaxAcall2TestDlg::OnInitDialog()

{

CDialog::OnInitDialog();

...

ret = tmaxreadenv(“tmax.env”, “TMAX”);

if (ret == -1){

AfxMessageBox(“tmaxreadenv fail...”);

return FALSE;

}

제9장 클라이언트 API 159

Page 178: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

return TRUE; // return TRUE unless you set the focus to a control

}

void CWinTmaxAcall2TestDlg::OnOK()

{

...

GetDlgItemText(IDC_EDIT1, m_Input);

lstrcpy((LPTSTR)buf, (LPCTSTR)m_Input.operator const char *());

...

buf = tpalloc(“STRING”, NULL, 0);

if (buf == NULL){

AfxMessageBox(“buf alloc fail...”);

return FALSE;

}

ret = WinTmaxAcall2((TPSTART_T *)NULL, (WinTmaxCallback)mycallfn,

“TOUPPER”, (char *)buf, 0, TPNOFLAGS);

if (ret == -1){

error processing

}

}

int mycallfn(unsigned int msg, long retval)

{

TPSVCINFO *svcinfo;

char infomsg[30];

memset(infomsg, 0x00, sizeof(infomsg));

svcinfo = (TPSVCINFO *)msg;

strncpy(infomsg, svcinfo->data, svcinfo->len);

if (retval != 0){

strcpy(infomsg,tpstrerror(retval));

AfxMessageBox(infomsg);

return -1;

} else {

strncpy(infomsg, svcinfo->data, sizeof(infomsg) - 1);

AfxMessageBox(infomsg);

return 1;

}

}

● 관련 함수

tpacall(),WinTmaxAcall()

160 Tmax Application Development Guide

Page 179: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.12.3. WinTmaxStart

Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 멀티 Window 환경에서 Tmax 시스템과 연결

하는데 사용된다. 기능상으로는 tpstart()와 동일하다. 다중 스레드를 사용하는 경우에는 각각의 스레드별

로 WinTmaxStart()를 이용하여 별도의 연결을 맺고 서비스를 호출해야 한다.

● 프로토타입

# include <WinTmax.h>

int WinTmaxStart(TPSTART_T *tpinfo)

● 파라미터

TPSTART_T에 대해서는 “9.1.1. tpstart”를 참고한다.

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

● 오류

WinTmaxStart()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

인수가 유효하지 않다. 예를 들어 tpinfo가 NULL이나 TPSTART_T 구조체에

대한 포인터가 아니다.

[TPEINVAL]

tpinfo가 TPSTART_T 구조체에 대한 포인터가 아니다.[TPEITYPE]

WinTmaxStart()가 부적절한 곳에서 호출되었다. 예를 들어, 서버 프로그램에

서 사용되었거나 이미 연결된 상황에서 재호출된 경우에 발생한다.

[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생했다. 또는 환경변수 설정이 잘못 된 경우이다. 예

를 들어 TMAX_HOST_ADDR나 TMAX_HOST_PORT가 잘못 설정되어 연결

이 실패한 경우에 발생한다.

[TPEOS]

● 관련 함수

tpstart(), WinTmaxEnd(), WinTmaxSend(), WinTmaxSetContext()

제9장 클라이언트 API 161

Page 180: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

9.12.4. WinTmaxEnd

메시지를 처리하는 스레드를 종료하고 사용 메모리를 해제하는 외에 기능상 tpend()와 같으므로 “9.1.2.

tpend”의 내용을 참고한다.

● 프로토타입

# include <WinTmax.h>

int WinTmaxEnd(void)

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

WinTmaxEnd()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

임계 영역으로 들어갈 수 없는 경우에 발생, 시스템 내부 오류로써 시스템 상

태 확인

[TPETIME]

tpend()가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 서버이다. 혹

은 연결이 해제된 후에 다시 호출된 경우에 발생한다.

[TPEPROTO]

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

if (WinTmaxStart((TPSTART_T *)NULL) == -1) {

error process routine..

return FALSE;

}

.....

WinTmaxEnd();

9.12.5. WinTmaxSetContext

Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 Window 핸들과 메시지 타입을 설정한다.

162 Tmax Application Development Guide

Page 181: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

멀티 Window 환경에서 사용되며 지정된 Window 핸들과 메시지 타입을 라이브러리의 빈 slot에 저장하여

관리하도록 한다. 이렇게 관리되는 정보는 작업 스레드가 응답을 수신한 후 지정되어 있는 Window에게

지정된 메시지 타입으로 데이터를 전송하게 된다.

데이터 전송은 다음과 같은 형태로 전송한다.

SendMessage(winhandle, msgType, (UINT) &msg, callRet)

응답을 받게되면 작업 스레드는 SendMessage(winhandle, msgType, (UINT) &msg, callRet)로 데이터를

전송한다. 이 경우 지정된 Window에서는 WPARAM에는 msg가 대응되며 LPARAM에는 callRet가 대응된

다. msg는 TPSVCINFO 구조체이며 callRet는 서비스 처리 결과값으로서 적절한 메시지가 수신된 경우에

는 0이며 잘못된 메시지가 수신된 경우에는 –1이다.

예를 들어 정상적으로 tpreturn(TPSUCCESS, …)으로 서비스가 처리되거나 혹은 실패한 경우로서 tpre

turn(TPFAIL, …)으로 처리되거나 혹은 비요청 메시지가 수신된 경우에는 적절한 메시지로 간주하고 callRet

값은 0이 된다. 하지만 동기형 결과값이나 대화형 메시지가 전달되는 경우, 이는 멀티 Window 환경에서

사용할 수 없는 형태이기 때문에 callRet 값은 –1이 된다.

● 프로토타입

# include <WinTmax.h>

int WinTmaxSetContext(void *winhandle, unsigned int msgType, int slot)

● 파라미터

설명파라미터

수신 데이터를 처리할 Window 핸들이다.winhandle

메시지 타입이다.msgType

지정된 Window 핸들과 메시지 타입을 할당할 slot을 의미한다. 할당 가능한

slot의 최대 개수는 256이며 시스템 내부적으로 0과 1은 각각 기본 출력과 에

slot

러를 위한 것으로 설정된다. 데이터 수신과정에서 에러가 발생한다든가 출력

용 Window가 지정되어 있지 않은 경우에는 기본 Window가 사용된다. slot은

사용자에 의해서 재정의되어 사용될 수 있다.

– –1을 지정하는 경우

시스템 내부적으로 비어있는 slot을 자동으로 검색하여 지정된 Window 핸

들과 메시지 타입을 할당한다.

– 0 이상의 값을 설정하는 경우

주어진 index의 slot에 지정된 Window와 메시지 타입을 할당한다.

● 반환값

제9장 클라이언트 API 163

Page 182: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

함수 호출에 성공한 경우index

(slot에 대한 index를 반환하고 index는 WinTmaxSend()에서 첫 번째 인자로

사용된다.)

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

WinTmaxSetContext()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

...

int CTMaxGwView::Connect()

{

CString szTemp, Fname;

WinTmaxEnd();

int Ret = tmaxreadenv(TMAXINI, “TMAX117”);

if(Ret<0)

{

szTemp.Format(“tmaxreadenv error”);

LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength());

return FALSE;

}

if (WinTmaxStart((TPSTART_T *)NULL) == -1) {

szTemp.Format(“WinTmaxStart 에러 = [%s]”, tpstrerror(tperrno));

LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength());

return FALSE;

}

WinTmaxSetContext(m_hWnd, WM_TMAX_RECV_RDP, 0);

WinTmaxSetContext(m_hWnd, WM_TMAX_RECV_ERR, 1);

WinTmaxSetContext(m_hWnd, WM_TMAX_RECV, 2);

return TRUE;

}

● 관련 함수

164 Tmax Application Development Guide

Page 183: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

WinTmaxStart(),WinTmaxEnd(), WinTmaxSend()

9.12.6. WinTmaxSend

Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 데이터를 송신한다. 멀티 Windows 환경에서

사용되며 서비스를 요청하는 함수이다.

● 프로토타입

# include <WinTmax.h>

int WinTmaxSend(int recvContext, char *svc, char *data, long len, long flags)

● 파라미터

설명파라미터

Tmax 시스템으로부터 응답을 수신하는 경우에 어느 Windows에 응답을 보

낼 것인가를 지정한다. WinTmaxSetContext()의 반환값이다.

recvContext

– 예를 들어

rc = WinTmaxSetContext(hwd, 0x300, -1);

slot 하나를 찾아서 (hwd, 0x300)을 저장하고 index를 반환한다. 이 경우,

WinTmaxSend(rc, svc, data, len, 0)는 응답이 오면 hwd windows에 0x300

번 메시지를 보내게 된다.

서비스 이름이다.svc

tpalloc()으로 할당된 버퍼로서 서비스 요청할 때에 전달할 데이터가 저장된

다.

data

데이터의 길이값으로써 CARRAY 버퍼 혹은 다중 구조체 버퍼를 사용하는

경우에는 정확한 길이 값을 명시해야 한다.

len

플래그 값으로서 WinTmaxSend()에서 사용할 수 있는 플래그 값은 다음과

같다.

flags

WinTmaxSend()에서 사용할 수 있는 값은 다음과 같다.

설명설정값

TPBLOCK 플래그없이 WinTmaxSend() 함수가 사용되었다면, svc가 등록되

어 있지 않거나 서비스 수행에 실패해도 정상적인 결과가 반환된다. 에러는

TPBLOCK

응답을 받는 시점에 확인할 수 있다. 플래그를 이용하면 서비스 호출시점에

정상 여부를v 확인할 수 있다.

WinTmaxSend()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한

다. 결과는 작업 스레드에 의해서 수신되어 등록된 Windows에 전달된다. 그

TPNOREPLY

제9장 클라이언트 API 165

Page 184: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

러나 TPNOREPLY 플래그는 서비스에 대한 응답을 받지 않겠다고 설정하는

것이다.

WinTmaxSend() 함수 호출자가 트랜잭션 모드 상태에서 플래그를 설정하여

svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행

된다.

TPNOTRAN

트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, WinT

maxSend() 함수가 트랜잭션 모드에서 호출되는 경우 플래그는 반드시 TP

NOTRAN으로 설정해야 한다. 트랜잭션 모드 내에서의 WinTmaxSend() 함

수를 호출하는 경우 TPNOTRAN로 설정되었어도 여전히 트랜잭션 타임아웃

(timeout)에 영향을 받는다. TPNOTRAN으로 호출된 서비스가 실패하였을

경우, 호출자의 트랜잭션에는 영향을 미치지 않는다.

TPNOBLOCK 플래그가 설정한 상태에서, 내부 버퍼가 송신할 메시지들로

가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패한

TPNOBLOCK

다. TPNOBLOCK 플래그 설정없이 WinTmaxSend()를 호출하는 경우 블로킹

상황이 발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션

타임아웃 또는 블로킹 타임아웃)이 발생할 때까지 기다리게 된다.

함수 호출자가 블로킹 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기

다리겠다는 것을 의미한다. 그러나 트랜잭션 타임아웃 내에서 WinTmaxSend()

을 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.

TPNOTIME

시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 시스템 함수 호출이

방해될 때 시스템 함수 호출이 재실행된다. 플래그가 설정되지 않은 상태에

TPSIGRSTRT

서 신호 인터럽트가 발생하였다면, 함수는 실패하고 tperrno에 TPGOTSIG가

설정된다.

● 반환값

설명반환값

함수 호출에 성공한 경우구별자(descriptor)

(구별자(descriptor)를 반환한다. 현재 이 구분자는 사용되지 않는다. )

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

WinTmaxSend()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

166 Tmax Application Development Guide

Page 185: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.[TPENOENT]

data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인경우 사

용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.

[TPEITYPE]

처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에, 호

출자의 서비스 요청이 송신되지 않았다.

[TPELIMIT]

타임아웃이 발생하였다. 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션

타임아웃이 발생한 것이며 트랜잭션은 rollback된다. 그렇지 않다면 TPNO

[TPETIME]

TIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블로킹 타임아웃이

발생한다. 트랜잭션 타임아웃이 발생하는 경우는 트랜잭션이 rollback될 때

까지 새로운 서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리

는 일은 모두 [TPETIME] 에러로 실패한다.

TPNOBLOCK이 설정된 상태에서, 블로킹 상황이 발생하였다.[TPEBLOCK]

TPSIGRSTRT가 설정되지 않은 상태에서, 시그널이 수신되었다.[TPGOTSIG]

트랜잭션 모드에서의 TPNOREPLY 서비스 호출 시TPNOTRAN 플래그를 설

정하지 않는 경우 등 부적절한 상황에서 발생한다.

[TPEPROTO]

Tmax 시스템에 에러가 발생하였다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

...

int CTMaxGwView::SendData2(char *data, long nLen)

{

CString szTemp;

m_send_length.Format(“%d”,nLen);

UpdateData(FALSE);

char *tpbuf = tpalloc(“STRING”, NULL, nLen);

if (tpbuf == NULL) {

szTemp.Format(“tpalloc Error [%s]”, tpstrerror(tperrno));

LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength());

return -1;

}

memcpy(tpbuf, data, nLen);

CString strService;

strService.Format(“TOUPPER_STRING”);

int nSendResult=WinTmaxSend(2,(LPSTR)(LPCSTR)strService, (char*)tpbuf, nLen, 0);

tpfree(tpbuf);

제9장 클라이언트 API 167

Page 186: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

9.13. Multithread/Multicontext

9.13.1. tpgetctxt

현재 context를 반환하는 함수이다.

● 프로토타입

#include <usrinc/atmi.h>

int tpgetctxt(int *ctxtid, long flags)

● 파라미터

설명파라미터

함수를 호출한 시점의 현재 context를 얻어온다.ctxtid

- multicontext인 경우 : 1보다 큰 값을 가져온다.

- singlecontext인 경우 : 0값을 가져온다.

0으로 설정해야 한다.flags

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno변수 값이 설정된다. )

● 오류

tpgetctxt()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

잘못된 인자가 설정되었다.[TPEINVAL]

예를 들어 1번째 인자가 포인터 값이 아니던가 2번째 인자가 0이 아닌 값으

로 설정된 경우 등이다.

Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

168 Tmax Application Development Guide

Page 187: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

int newContext()

{

int i;

int id;

i = tpstart(tpinfo);

if (i < 0)

{

printf(“\t[newContext]tpstart fail[%d][%s]\n",

tperrno,tpstrerror(tperrno));

tpfree((char *)tpinfo);

return -1;

}

i = tpgetctxt(&id,TPNOFLAGS);

if (i < 0)

{

printf(“\t[newContext]tpgetctxt fail[%d][%s]\n",

tperrno,tpstrerror(tperrno));

return -1;

}

return id;

}

● 관련 함수

tpsetctxt()

9.13.2. tpsetctxt

현재 context를 설정하는 함수이다.

● 프로토타입

#include <usrinc/atmi.h>

int tpsetctxt(int ctxtid, long flags)

● 파라미터

제9장 클라이언트 API 169

Page 188: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명파라미터

함수를 호출한 시점의 현재 context를 설정한다. 설정 가능한 context란 tpstart()

를 하여 새로운 context가 생성된 ID이다.

ctxtid

TPNULLCONTEXT를 비롯한 다른 사용 가능한 context로 설정할 수 있으나

TPINVALIDCONTEXT로는 설정할 수 없다.

현재 0을 설정해야 한다.flags

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(tperrno변수 값이 설정된다.)

● 오류

tpsetctxt()가 실패하는 경우 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

잘못된 인자가 설정된 경우로 ctxtid에 0 또는 TPINVALIDCONTEXT가 설정

된 경우나 flags값에 0이외의 값이 설정된 경우이다.

[TPEINVAL]

ctxtid에 설정된 값이 설정 가능한 context가 아닌 경우 발생한다.[TPENOENT]

- tpstart()하기 전에 이 함수를 호출한 경우 발생한다.[TPEINVAL]

- tpstart()를 TPMULTICONTEXTS로 설정하지 않은 상태에서 이 함수를 호

출한 경우 발생한다.

- multicontext인 경우 0으로 설정된 경우에 발생한다.

Tmax 시스템에 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

int altContext(int id)

{

int i;

int ret;

ret = tpsetctxt(id, TPNOFLAGS);

if (ret < 0)

{

170 Tmax Application Development Guide

Page 189: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

printf(“\t[altContext]tpsetctxt fail[%d][%s]\n"tperrno,tpstrerror(tperrno));

tpfree((char *)tpinfo);

return -1;

}

return 1;

}

● 관련함수

tpgetctxt()

제9장 클라이언트 API 171

Page 190: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 191: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제10장 서버 API

Tmax 서버에서 사용하는 함수에 대해 설명한다. ATMI에서 서버 프로그램을 작성할 때 필요한 함수에 대

해 알아본다. 서버 또한 클라이언트 역할도 할 수 있기 때문에 클라이언트에서 사용하는 함수도 사용이 가

능하다.

10.1. TCSTCS 방식의 서버 프로그램에서 사용하는 함수에 대해 설명한다.

다음은 TCS 방식 서버 프로그램 함수 목록이다.

● 서비스 완료 관련 함수

tpreturn()은 클라이언트에게 응답을 보내는 것이며, tpforward()는 필요에 의하여 또 다른 서버로 서비

스 요청을 보내고 서비스를 끝낸다.

기능함수

서비스 요청에 대한 응답을 클라이언트에게 보내고 서비스 루틴을 종료한다.tpreturn

또 다른 서비스를 처리하기 위해 다른 서버로 서비스를 의뢰한다. 애플리케

이션을 해제한다.

tpforward

● 서버 초기화와 종료 관련 함수

애플리케이션과 연결할 데이터베이스의 open과 close를 담당하고, 명령어 라인 옵션 처리 등의 기능을

제공한다. 이 서브 루틴을 개발자가 작성하지 않으면 Tmax에서 기본적으로 제공된다.

기능함수

서버를 초기화한다.tpsvrinit

서버의 초기화를 해제한다.tpsvrdone

● 비요청 관련 함수

Tmax에서 서버는 클라이언트가 요청하지 않은 메시지를 클라이언트에게 일방적으로 보낼 수 있다. 이

것은 Tmax에 접속되어 있는 클라이언트에게 알리고 싶은 메시지를 전달하고자 할 때 사용한다. 비요청

메시지를 받을 수 있는 클라이언트는 Tmax에 접속되어 있어야 하고, Tmax에 접속해서 비요청 메시지

를 받으려고 하는 경우 플래그 값을 설정해야 한다.

제10장 서버 API 173

Page 192: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

기능함수

클라이언트의 요청이 없더라도 서버에 접속된 모든 클라이언트에게 자동으

로 메시지를 송신한다.

tpbroadcast

클라이언트의 요청이 없더라도 서버에서 클라이언트가 사전 등록한 요구 메

시지를 자동으로 송신한다.

tpsendtocli

Tmax 시스템에 접속한 클라이언트의 ID를 반환한다. ID는 tpsendtocil()에 사

용된다.

tpgetclid

해당 서버 프로세스가 위치한 노드에 클라이언트 ID에 해당하는 클라이언트

가 접속해 있는지 검사한다.

tpchkclid

참고

함수와 관련 함수에 대한 자세한 사항은 Tmax 안내서 중 "Tmax Reference Guide""를 참고한다.

서비스 루틴 인자

서버 프로그램은 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

174 Tmax Application Development Guide

Page 193: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명멤버

클라이언트가 요청 데이터를 받기 위해서 사용되는 버퍼로서, 서버 main() 안에서

tpalloc()으로 미리 할당된다.

data

요청한 데이터의 길이를 나타낸다.len

트랜잭션 상태에 있는지 또는 호출자가 반드시 응답을 요구하는지 등을 서비스에게

알려준다.

flags

예를 들어 flags가 TPTRAN이라면 서비스가 트랜잭션 모드 안에 있다는 것을, TPNO

TRAN 이라면 현재의 트랜잭션에 참여할 수 있다는 것을 알게 한다.

연결 구별자이다. 이것은 어떤 클라이언트에게 응답을 보내야 할지를 알게 한다.cd

서버는 클라이언트가 요청한 서비스를 처리하기 위해 미리 버퍼를 main()에서 할당하

기 때문에 tpreturn() , tpforward()로 통신할 때 TPSVCINFO의 데이터를 쓸 것을 권장

한다. TPSVCINFO의 데이터에 대해 접근할 때, 서버 프로그램과 클라이언트 프로그

램의 버퍼 유형이 같아야 한다.

클라이언트 프로그램

다음은 클라이언트 프로그램 프로그램에 대한 예이다.

#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

}

. . .

}

서버 프로그램

다음은 서버 프로그램에 대한 예로 개발자가 작성한 서비스 루틴이다. main()은 Tmax에서 제공한 것이다.

제10장 서버 API 175

Page 194: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#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);

};

10.1.1. tpreturn

서버의 서비스 종료하는 함수이다. tpreturn() 함수는 서비스 루틴 완료를 의미한다. C 언어에서의 반환 문

장과 같은 역할을 한다. tpreturn()이 호출되면 서비스 루틴은 Tmax 시스템에게 반환된다. Tmax 시스템으

로 정상적으고 반환되기 위해서는, tpreturn()은 Tmax 시스템이 제어하는 서비스 루틴 내에서 호출되는 것

이 바람직하다.

tpreturn() 함수는 서비스의 응답 메시지를 송신한다. 응답을 수신할 프로그램이 tpcall(), tpgetrply(),

tprecv()로 응답을 기다리고 있다면, 그 응답은 tpreturn() 호출이 성공한 후 수신자의 버퍼를 통해 전달된

다.

tpreturn()은 대화형 서비스들이 대화형 연결을 종료할 수 있게 한다. 서비스 루틴은 직접 tpdiscon()을 호

출할 수 없다. 올바른 결과를 보장하려면, 대화형 서비스에 연결된 프로그램은 tpdiscon()을 호출하지 않

는 것이 좋다. 그보다 대화형 서비스에서의 완료 통보 즉, tpreturn()으로써 송신되는 TPEV_SVCSUCC나

TPEV_SVCFAIL과 같은 이벤트들을 기다려야 한다.

서비스 루틴이 트랜잭션 모드에 있는데, 해당 서비스를 호출한 클라이언트나 서비스가 명시적으로 트랜

잭션을 시작하지 않으면(즉, tx_begin을 사용하지 않으면) tpreturn은 트랜잭션의 한 부분으로서 TPSUC

CESS인 경우 commit 아니면 rollback된다. 서비스는 동일한 트랜잭션(global transaction)의 한 부분으로

써 여러 번 호출될 수도 있다. 그래서 tx_begin을 사용한 트랜잭션 시작자가 tx_commit 또는 tx_rollback중

하나를 호출하여 트랜잭션을 완료하기 전까지는 완전히 commit 또는 rollback되지 않는다.

tpreturn() 함수는 서비스 루틴에서 요청된 서비스들로부터 모든 응답을 수신한 후에 호출되어야 한다. 그

렇지 않으면, 서비스 특성에 따라 [TPESVCERR] 에러나 TPEV_SVCERR 이벤트가 서비스 루틴과 통신

하는 프로그램에게 반환된다. 수신되지 않은 응답들은 Tmax시스템에 의해 자동으로 무시된다. 또한 이런

응답들에 사용되는 구별자(descriptor)들은 무효화 된다.

tpreturn() 함수는 대화형 통신에 사용되는 서비스에서 시작된 모든 연결을 종료한 후에 호출되어야 한다.

그렇지 않으면, 서비스 특성에 따라 [TPESVCERR] 에러나 TPEV_SVCERR 이벤트 중의 하나가 서비스

176 Tmax Application Development Guide

Page 195: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

루틴과 통신하는 프로그램에게 반환된다. 또한, 강제적인 연결 해제 이벤트 즉, TPEV_DISCONIMM가 서

비스와 연결된 모든 연결 종속자들에게 전달된다.

대화형 통신에서 서비스 루틴이 tpreturn()을 호출할 때 통신 제어권을 가지고 있지 않았다면 2가지 결과

가 일어날 수 있다.

1. 서비스 루틴이 TPFAIL의 rval과 NULL의 data로 tpreturn()를 호출하였다면, 이때 대화 시작자에게

TPEV_SVCFAIL이벤트가 전달된다.

2. 와 다른 형태의 tpreturn()이 호출된다면, 대화 시작자에게 TPEV_SVCERR 이벤트가 전달된다. 대화형

서비스는 서비스에서 시작하지 않은 대화형 연결을 하나만 가지고 있기 때문에, Tmax 시스템에서 데

이터나 이벤트가 송신되어야 할 구별자를 알고 있다. 이런 이유로, 구별자(descriptor)는 tpreturn()에 인

수로 전달되지 않는다.

● 프로토타입

# include <atmi.h>

void tpreturn ( int rval, long rcode, char *data, long len, long flags )

● 파라미터

– rval

rval 인수로는 다음 값들이 사용될 수 있다. 아래에 존재하지 않는 rval 값은 모두 TPFAIL로 간주된다.

설명rval값

서비스가 성공적으로 종료되었다.TPSUCCESS

데이터가 존재하고 tpreturn()수행 중에 에러가 발생하지 않는다면, 데이터는

송신된다. 호출자가 트랜잭션 모드에 있다면, 이 트랜잭션의 한 부분을 commit

이 가능한 상태로 결정한다. 트랜잭션이 최종적으로 완료될 때, 그 트랜잭션

에 속한 나머지 서비스들이 모두 성공적으로 완료되어 commit 가능 상태라

면 commit을 하고 하나라도 실패하면 rollback된다.

tpreturn()에 대한 호출이 반드시 전체 트랜잭션을 완료하는 것이 아님에 유의

해야 한다. 또한, 호출자가 TPSUCCESS로 반환하더라도 대기중인 응답이나

대화형 연결이 존재하거나, 혹은 서비스 내에서 행해진 어떤 작업이 트랜잭

션을 rollback 되게 했다면, 그 때는 서비스 실패로 메시지가 송신된다. 응답

의 수신자가 [TPESVCERR] 표시 또는 TPEV_SVCERR 이벤트를 수신한다.

서비스 루틴 내에서 트랜잭션이 rollback 되게 되면, rval은 TPFAIL로 설정됨

에 유의해야 한다.

대화형 서비스에서 TPSUCCESS로 반환되면, TPEV_SVCSUCC 이벤트가

발생된다.

제10장 서버 API 177

Page 196: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명rval값

서비스가 애플리케이션의 실패로 종료되었다. 응답을 수신하는 프로그램에

에러가 반환된다. 응답을 수신하는 호출이 실패하고 수신자는 [TPSVCFAIL]

TPFAIL

값이나 TPEV_SVCFAIL 이벤트를 수신한다. 이 인수는 데이터를 송신할 수

없다.

TPFAIL 호출자가 트랜잭션 모드에 있고 autotransaction인 경우 tpreturn()은

트랜잭션을 rollback한다. 트랜잭션이 이미 rollback상태로 결정되어 있을 수

도 있다.

서비스 호출 후 반환할 경우 서버 프로세스를 강제 종료하고자 할 때 사용된

다. tpexit()로 종료된 프로세스는 TMM에 의해 다시 시동된다.

TPEXIT

TPEXIT와 비슷하나 TPDOWN으로 종료된 프로세스는 TMM에 의해 다시 기

동 되지 않는다.

TPDOWN

TPSUCCESS와 동일하다.TMSUCCESS

TPFAIL과 동일하다.TMFAIL

– rcode

애플리케이션에서 사용자에 의해 정의되는 반환값 rcode는 서비스 응답을 수신하는 프로그램에게

송신된다. 이 코드는 rval의 값과 상관없이 응답이 클라이언트로 무사히 송신될 수 있는 한, 즉 수신하

는 호출이 성공하거나 [TPSVCFAIL] 로 반환하거나 또는 TPEV_SVCSUCC 또는 TPEV_SVCFAIL 이

벤트들 중 하나를 수신한다면 송신되어진다. rcode값은 수신자에게 전역변수 tpurcode로 전달된다.

– data

송신되는 응답 데이터를 가리킨다. data가 NULL이 아니라면, 반드시 이전에 tpalloc()에 의하여 할당

된 버퍼를 가리켜야 한다. 이것이 서비스 루틴에 전달된 것과 동일한 버퍼라면, Tmax 시스템에서 처

리를 담당한다. 따라서, 서비스 루틴 작성자는 이 버퍼에 대한 제거여부를 신경 쓸 필요가 없다. 실제

로 사용자가 이 버퍼를 제거하려 한다면 이는 실패한다. 그러나 tpreturn()으로 전달되는 버퍼가 서비

스 발생시와 동일한 버퍼가 아니라면, tpreturn()은 이 버퍼를 해제한다.

– len

송신된 데이터 길이이다. data가 길이 명시가 필요 없는 버퍼를 가리킨다면, len은 무시되고 보통 0이

사용된다. data가 길이 명시가 필요한 버퍼를 가리킨다면, len은 0이 될 수 없다. data가 NULL이면,

len은 무시된다. 이 경우, 서비스를 호출한 프로그램이 응답을 기대하고 있다면, 아무 데이터도 없는

응답이 송신된다. 응답이 기대되지 않는다면 tpreturn()은 필요에 따라 data를 제거하고, 송신하는 응

답 없이 반환한다.

– flags

사용되지 않으며 반드시 0으로 설정하도록 한다.

178 Tmax Application Development Guide

Page 197: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

서비스가 대화형이라면, 데이터가 전달되지 않는 경우는 다음의 2가지이다.

• tpreturn() 호출할 경우에 대화형 연결이 이미 종료된 경우로 호출자가 TPEV_DISCONIMM 이벤트

를 수신하였다. 이 경우 tpreturn()은 단순히 서비스 루틴을 종료하고, 트랜잭션 모드에 있다면 현재

트랜잭션을 rollback한다. 이 경우, 호출자의 데이터는 전달될 수 없다.

• 호출자가 통신 제어권을 갖고 있지 않다면, 위에서 언급한 것처럼 TPEV_SVCFAIL 또는

TPEV_SVCERR 중 하나가 대화 시작자에게 송신된다. 대화 시작자가 수신하는 이벤트에 관계없

이, 어떤 데이터도 전달되지 않는다. 그러나, 대화 시작자가 TPEV_SVCFAIL 이벤트를 수신하였다

면, 반환 코드는 시작자의 tpurcode 변수로 이용 가능하다.

● 반환값

서비스 루틴은 호출자인 Tmax 시스템에게 어떤 값도 반환하지 않는다. 서비스 루틴은 tpreturn()을 사용

하여 종료되는 것이 원칙이다. 서비스 루틴이 tpreturn()을 사용하지 않고 예를 들어, C 언어의 반환문장

등을 사용하여 반환한다면 서버는 서비스 요청자에게 서비스 에러를 반환한다. 또한 대화형 통신을 위

해 유지되어 있는 연결이 강제적으로 종료되고 비동기적으로 기다리고 있는 응답들이 모두 무시된다.

서버가 트랜잭션 모드에 있었다면 그 트랜잭션은 rollback된다. 또한 tpreturn()이 서비스 루틴 외부에서

사용되었을 경우 예를 들어 서비스가 아닌 루틴에서 사용된 경우 이는 아무런 일도 하지 않고 단순히 반

환하게 된다.

● 오류

tpreturn()이 서비스 루틴을 종료시키기 때문에 인수를 처리하는 중에 에러가 발생하면 호출자인 서비스

루틴에게 전달되지 않는다. 에러들은 다음과 같이 전달된다.

– 동기와 비동기 통신: tpcall() 또는 tpgetrply()으로 서비스 결과를 수신하는 프로그램에 대해서는 tperrno

에 [TPESVCERR]이 전달된다.

– 대화형 통신 : tpsend()나 tprecv()를 사용하는 프로그램에 대해서는 TPEV_SVCERR 이벤트를 발생

시킨다.

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

SERVICE1(TPSVCINFO *msg)

{

char *buf;

long len;

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processsing }

buf=msg->data;

제10장 서버 API 179

Page 198: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

data process....

ret=tpcall(“SERVICE2”, buf, sizeof(buf), &buf, &len, TPNOFLAGS);

if (ret==-1) { error processing }

data process....

if (buf !=”SUCCESS”) {

printf(“svc fail..\n”);

tpreturn (TPFAIL, -1, NULL,0,0);

}

else

tpreturn(TPSUCCESS, 0, msg->data, msg->len, 0);

}

● 관련 함수

tpalloc(), tpcall(), tpconnect(), tpdiscon(), tpgetrply(), tprecv(), tpsend()

10.1.2. tpforward

서버에서 서비스 요청을 또 다른 서비스 루틴으로 전달하는 함수이다. tpforward()는 자신의 서비스 처리

를 종료하고 클라이언트의 요청을 svc 서비스 루틴으로 전달한다.

tpforward()는 서비스 루틴에서 마지막으로 호출되는 것으로 tpreturn()처럼 작동한다. tpreturn()과 마찬가

지로 tpforward()가 Tmax 시스템으로 올바로 반환되기 위해서는 tpforward()는 Tmax 시스템이 제어하는

서비스 루틴 내에서 호출되어야 한다.

data가 가리키는 데이터를 사용하여 svc로 명명된 서비스에게 요청을 전달한다. 요청을 전달하는 서비스

루틴은 어떤 응답도 수신하지 않는다. 요청이 전달된 후 서비스 루틴은 Tmax 시스템에게로 반환한다. 그

리고 서버는 자유롭게 다른 작업을 수행할 수 있다. tpforward()는 요청자로부터 아무 응답도 기대하지 않

기 때문에, 특별한 에러없이 어떤 서비스에게든지 전달될 수 있다.

서비스 루틴이 트랜잭션 모드에 있다면, 그 트랜잭션은 트랜잭션 시작자(originator)가 tx_commit() 또는

tx_rollback() 중의 하나를 실행하여 트랜잭션을 완료할 때 비로소 완료될 수 있다. tpforward()는 tpreturn()

과 마찬가지로 트랜잭션을 완료하지 않는다.

트랜잭션이 서비스 루틴 내에서 tx_begin()을 사용하여 시작된 것이라면, 그 트랜잭션은 tpforward()호출

전에 tx_commit() 또는 tx_rollback() 둘 중의 하나로 먼저 완료되어야 한다. 즉, tpforward()로 연결된 모든

서비스들은 모두가 트랜잭션 모드이거나, 아니면 모두가 트랜잭션 모드가 아니어야 한다.

최종적으로 전달된 서버 프로세스가 tpreturn()을 이용하여 처음 서비스를 요청한 클라이언트에게 응답을

보낸다. tpforward()는 응답을 기다리고 있는 요청자에게 응답을 송신하는 책임을 다른 서버 프로세스에게

전가하는 것으로 멀티 노드 간에도 서비스가 이루어진다.

tpforward()는 서비스 루틴이 요청한 모든 서비스들에 대한 응답을 받은 후 호출되어야 한다. 수신되지 않

은 응답에 대한 구별자들은 무효화되고 전달 요청은 전송되지 않는다.

180 Tmax Application Development Guide

Page 199: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

다음은 tpforward 함수 흐름에 대한 그림이다.

[그림 10.1] tpforward

● 프로토타입

# include <atmi.h>

void tpforward (char *svc, char *data, long len, long flags)

● 파라미터

설명파라미터

버퍼를 받을 서비스 이름이다.svc

NULL이 아니라면 tpalloc()에 의해 이전에 할당된 버퍼를 가리켜야 한다.data

버퍼가 서비스 루틴에 송신된 것과 동일한 버퍼라면 Tmax 시스템이 이 버퍼

에 대한 처리 책임을 갖는다. 서비스 루틴 작성자가 이 버퍼를 해제하려 한다

면 이는 실패하게 된다. 그러나 tpforward()로 송신되는 버퍼가 서비스를 호출

할 경우에 전달된 것과 동일한 버퍼가 아니라면 tpforward()가 그 버퍼를 해제

한다.

송신될 데이터의 길이이다.len

data가 특별한 길이 명시가 필요 없는 버퍼를 가리킨다면(예를 들어, STRUCT

타입 버퍼), len은 무시되고 0이 된다. data가 NULL이라면, len은 무시되고

데이터 길이가 0인 요청이 송신된다.

서비스 루틴 작성자는 tpforward() 호출 후 다시 제어권을 획득할 수 없기 때

문에 TPSIGRSTRT가 암시적으로 정의된 형태의 블로킹 송신이 사용된다.

tpforward() 수행 중에 시그널이 발생하여 수행이 중지되더라도 나중에 재수

행되며, 블로킹 상황을 만나더라도 타임아웃 발생 전까지는 기다려서 송신한

다.

사용되지 않으며 지정된 값은 무시된다.flags

제10장 서버 API 181

Page 200: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 반환값

서비스 루틴은 호출자인 Tmax 시스템에서 어떤 값도 반환하지 않는다. 서비스 루틴은 void로 선언된다.

● 오류

tpforward()가 실패하는 경우 상황에 따라 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

다음의 경우에 발생한다.[TPESVCERR]

- 유효하지 않은 버퍼를 사용하는 경우

- 유효한 tpacall(), tpconnect()의 반환값으로 cd를 반환하는 경우

- 대화형 통신에서 tpreturn()대신 tpforward()를 사용한 경우

- TPEV_DISCONIMM 이벤트가 발생한 경우

- 트랜잭션 모드에서 xa operation이 실패한 경우(tx_begin(), tx_rollback(),

tx_commit())

서비스 루틴 작업 중이나 또는 요청을 전송하는 중에 트랜잭션 타임아웃이

발생한 경우에 TPETIME 에러가 반환된다.

[TPETIME]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

SWITCH(TPSVCINFO *msg)

{

int switch;

char *buf;

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

strcpy(buf, msg->data);

data process…

if (switch>5) tpforward(“SERVICE1”, buf, 0, 0);

else tpforward(“SERVICE2”, buf, 0, 0);

}

● 관련 함수

tpalloc(), tpconnect(), tpreturn()

182 Tmax Application Development Guide

Page 201: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

10.1.3. tpsvrinit

개발자가 서비스를 수행하기 전에 Tmax 서버를 초기화 과정을 수행하는 작업을 처리하는 함수이다. Tmax

응용 서버 프로그램의 분리된 main의 초기화 과정에 tpsvrinit()을 호출한다. 이 루틴은 프로세스가 수행되

고 난 후, 아직 어떤 서비스 요청도 처리하기 전에 호출된다. 그러므로 tpsvrinit() 루틴 내에 Tmax 통신이

수행되거나 트랜잭션이 정의될 수도 있다.

애플리케이션에서 tpsvrinit()루틴을 제공하지 않는다면 Tmax가 제공하는 기본(default) 루틴이 대신 호출

된다. 기본 tpsvrinit()은 트랜잭션을 처리하는 서버 그룹에 포함된 서버이면 tx_open()과 userlog()를 호출

하여 서버가 성공적으로 시작되었음을 알린다.

애플리케이션별 명령어 라인 옵션(CLOPT)은 서버에게 전달되어 tpsvrinit()에서 처리될 수 있다. 명령어

라인 옵션(CLOPT)에 대한 자세한 설명은 source 환경파일의 SERVER 절 중 CLOPT 항목을 참조한다.

옵션은 argc와 argv를 통해 전달된다.

getopt()가 Tmax 서버 main()에서 사용되기 때문에 optarg, optind, opterr가 tpsvrinit() 내에서 옵션 parsing

및 에러 검출을 제어하는데 사용된다.

● 프로토타입

# include <tmaxapi.h>

int tpsvrinit ( int argc, char **argv )

● 파라미터

설명파라미터

명령라인 인수의 개수argc

명령라인 인수argv

● 반환값

설명반환값

함수 호출에 실패한 경우-1

(함수 호출이 실패한 경우 어떤 서비스 요청도 받지 않고 서버 프로세스는 종

료되고 에러는 발생하지 않는다.)

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

EXEC SQL INCLUDE sqlca.h;

tpsvrinit(int argc, char **argv)

제10장 서버 API 183

Page 202: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

{

EXEC SQL begin declare section;

char user_name[30];

char user_passwd[30];

EXEC SQL end declare section;

EXEC SQL CONNECT scott IDENTIFIED BY tiger;

return(0);

}

SERVICE(TPSVCINFO *msg)

{

int ret, cd;

char *buf;

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process....

cd=tpgetclid();

if (cd==-1) { error processing }

ret=tpsendtocli(cd, buf, 0, TPNOFLAGS);

if (ret==-1) { error processing }

data process....

printf(“ Sevice end\n”);

EXEC SQL COMMIT WORK RELEASE;

tpreturn(TPSUCCESS, buf, strlen(buf), 0);

}

● 관련 함수

tx_open(), tpsvrdone()

10.1.4. tpsvrdone

UCS 방식 서버 프로세스를 종료하는 함수이다. Tmax 응용 서버 프로그램의 분리된 main은 서비스 요청

처리를 모두 마치고 프로세스를 종료하기 전에 tpsvrdone()을 호출한다. 이 루틴이 실행될 때 서버 프로세

스는 여전히 시스템의 일부이기는 하지만 서비스는 지원하지 않는다. tpsvrdone() 루틴 내에서 Tmax 통신

이 수행되거나 트랜잭션이 정의될 수도 있다.

tpsvrdone()이 대화형 연결을 유지하고 있는 경우는 Tmax는 대화형 연결을 종료한다. 비동기성 응답을 대

기하고 있는 경우는 대기하고 있던 비동기성 응답들을 무시한다. 트랜잭션 모드에 있는 동안은 트랜잭션

을 중지하고 서버는 바로 종료한다.

184 Tmax Application Development Guide

Page 203: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

애플리케이션에서 tpsvrdone() 루틴을 제공하지 않는다면 Tmax가 제공하는 기본(default) 루틴이 대신 호

출된다. 기본 tpsvrdone()은 트랜잭션을 처리하는 서버 그룹에 포함된 서버이면 tx_close()와 userlog()를

호출하여 서버가 곧 종료할 것임을 알린다. tpreturn()이나 tpforward() 중 하나가 tpsvrdone() 내에서 호출

된다면 이러한 루틴들은 아무런 작동없이 단순히 반환한다.

● 프로토타입

# include <tmaxapi.h>

int tpsvrdone (void)

● 반환값

tpsvrdone()은 개발자가 서버 프로세스의 종료를 수행하기 전에 필요한 작업을 수행하도록 작성하는 함

수로 반환값은 없다. tpsvrdone()은 에러가 발생하지 않는다.

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

EXEC SQL INCLUDE sqlca.h;

SERVICE(TPSVCINFO *msg)

{

int ret, cd;

char *buf;

EXEC SQL begin declare section;

….

EXEC SQL end declare section;

EXEC SQL CONNECT : scott IDENTIFIED BY : tiger;

buf=tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

data process….

cd=tpgetclid();

if (cd==-1) { error processing }

ret=tpsendtocli(cd, buf, 0, TPNOFLAGS);

if (ret==-1) { error processing }

data process....

tpsvrdone();

}

void tpsvrdone()

{

printf(“ Sevice end\n”);

제10장 서버 API 185

Page 204: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

EXEC SQL COMMIT WORK RELEASE;

}

● 관련 함수

tx_close(), tpsvrinit()

10.1.5. tpsendtocli

사용되는 함수로 지정된 클라이언트에게 비요청 메시지를 송신한다. tpbroadcast()는 Tmax 시스템에 접

속되어 있는 임의의 클라이언트에 비요청 메시지를 전송한다. tpsendtocli()는 서버 프로세스에서 해당 서

버 프로세스가 제공하는 서비스를 요청한 클라이언트에게만 비요청 메시지를 보내기 위해 사용한다.

● 프로토타입

# include <tmaxapi.h>

int tpsendtocli ( int clid, char *data, long len, long flags )

● 파라미터

설명파라미터

tpgetclid()로 얻은 클라이언트의 유일한 번호이다.clid

tpalloc()에 의해 할당된 버퍼이어야 한다.data

송신하는 버퍼의 길이이다. data가 길이 명시가 필요없는 버퍼로 설정된 경

우 len은 무시되고 보통 0이 사용된다. data가 길이 명시가 반드시 필요한 버

퍼를 설정된 경우 len은 0이 될 수 없다. data가 NULL인 경우 len은 무시된다.

len

메시지 송신할 때 사용되는 옵션이다.flags

flags로 사용 가능한 값은 다음과 같다

설명설정값

메시지는 클라이언트에게 수신되어야 한다. 하지만, 클라이언트가 수신된 메

시지를 빠르게 처리하지 못한다면 요청한 결과를 수신할 떄 오랜 시간이 걸

릴 수 있다.

0(Zero)

TPUDP 플래그는 클라이언트와 데이터를 통신하는 방식이 UDP라는 의미가

아니다. 호출자가 데이터를 송신할 때, 송신할 내부 버퍼에 전달될 메시지가

TPUDP

가득 차서 보내지 못할 경우가 있다. 이럴 경우 데이터는 버려도 된다는 의미

이다. 통신 상의 UDP처럼 데이터가 도중에 분실될 수 있다는 의미이다.

클라이언트의 상태를 점검하고 다른 메시지를 요청할 수 있는지 확인한다.TPFLOWCONTROL

186 Tmax Application Development Guide

Page 205: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

해당 클라이언트로의 send message가 너무 많이 쌓여 있다면 tpsendtocli()

는 –1을 반환하고 tperrno를 TPEQFULL로 설정한다. 이 플래그는 Tmax 시

스템의 부하를 줄여준다.

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpsendcli()에 실패하는 경우 상황에 따라 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

clid가 유효하지 않다.[TPEBADDESC]

tpsendtocli()가 부적절한 상황에서 호출되었다.[TPEPROTO]

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

송신할 메시지가 있으므로 같은 메시지일 경우에는 재전송할 필요가 없다.[TPEQFULL]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

SERVICE(TPSVCINFO *msg)

{

int ret, clid;

char *buf;

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

strcpy(buf, msg->data);

data process….

clid = tpgetclid();

if (clid==-1) { error processing }

제10장 서버 API 187

Page 206: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ret=tpsendtocli(clid, (char *)buf, 0, 0);

if (ret==-1) { error processing }

tpreturn(TPSUCCESS, 0, 0, 0);

}

● 관련 함수

tpbroadcast()

10.1.6. tpgetclid

시스템에 접속된 클라이언트의 번호를 알 수 있는 함수이다. 클라이언트 번호는 도메인 시스템 내에서 유

일한 번호이다. 여러 멀티 노드로 도메인 시스템이 구축되어 있어도 유일한 번호를 클라이언트에게 부여

한다. 이 함수는 서버에서만 사용할 수 있는 함수로, 서비스를 요청한 해당 클라이언트 ID를 구해서

tpsendtocli()에서 클라이언트로 메시지를 보내기 위해서 보통 사용한다.

● 프로토타입

#include <tmaxapi.h>

int tpgetclid(void)

● 반환값

설명반환값

함수 호출에 성공한 경우0 이상의 정수값

(클라이언트의 번호에 해당하는 0 이상의 정수값을 반환한다. )

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당하는 값이 설정된다.)

● 오류

tpgetclid()가 실패하는 경우 상황에 따라 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

tpgetclid()가 부적절한 상황에서 호출되었다.[TPESYSTEM]

예를 들어, 클라이언트 프로그램내에 사용되었다.

운영 시스템에 에러가 발생하였다.[TPEOS]

188 Tmax Application Development Guide

Page 207: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tmaxapi.h>

SERVICE(TPSVCINFO *msg)

{

int ret, clid;

char *buf;

buf = (char *)tpalloc(“STRING”, NULL, 0);

if (buf==NULL) { error processing }

strcpy(buf, msg->data);

data process…

clid = tpgetclid();

if (clid==-1) { error process }

ret=tpsendtocli(clid, buf, strlen(buf), 0);

if (ret==-1) { error processing }

data process….

tpreturn(TPSUCCESS,0,buf, strlen(buf), 0);

}

● 관련 함수

tpsendtocli()

10.1.7. tpchkclid

ID에 해당하는 클라이언트가 해당 서버 프로세스가 위치한 노드에 접속한 상태인지를 확인하는 함수이다.

주로 RDP 방식의 서버 프로그램을 개발할 때 서비스 루틴에서 접속한 클라이언트 ID를 저장하고 usermain()

루틴에서 tpsendtocli()로 메시지를 보내는 경우에 사용하면 불필요한 에러를 사전에 막을 수 있다. (RPD

방식에서는 서버 프로세스가 위치한 노드에 직접 연결된 상태가 아니면 tpsendtocli()를 사용할 수 없다.)

● 프로토타입

#include <tmaxapi.h>

int tpchkclid(int clid)

● 파라미터

설명파라미터

접속 상태를 알고자 하는 클라이언트 ID를 지정한다.clid

제10장 서버 API 189

Page 208: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 반환값

설명반환값

해당 클라이언트가 로컬 노드에 접속된 클라이언트가 아닌 경우-2

해당 클라이언트가 접속되어 있지 않은 경우-1

해당 클라이언트가 정상적으로 접속된 경우1

● 예제

ret = tpchkclid(clid);

if (ret<0)

{

error processing routine

}

10.2. UCSUCS 방식의 서버 프로그램에서 사용하는 함수에 대해 설명한다.

● 스케줄링 관련 API

UCS 방식은 사용자가 개발한 usermain() 루틴이 main() 루틴처럼 사용되므로 스케줄링 API를 통하여

TMM과 CLH로부터 오는 여러가지 메시지를 처리해야 한다.

기 능함수

지정 시간(초)동안 CLH 혹은 사용자 설정 FD에 메시지가 도착했는지 확인한

다.

tpschedule

지정 시간(마이크로초)동안 CLH 혹은 사용자 설정 FD에 메시지가 도착했는

지 확인한다.

tpuschedule

● 소켓 FD 관련 매크로

소켓 관련 매크로는 앞서 설명한 tpschedule()등의 UCS 스케줄러에 사용자의 소켓 FD를 같이 사용하

기 위한 것으로 일반 네트워크 프로그램에서 사용하는 FD_SET, FD_CLR, FD_ISSET과 유사하다.

기 능함수

UCS 스케줄러에 FD를 등록한다. tpschedule() / tpuschedule()은 해당 FD에

도착한 메시지도 확인한다.

tpgetfd

해당 FD에 메시지가 도착했는지 확인한다.tpissetfd

해당 FD를 UCS 스케줄러에서 해제한다.tpclrfd

● 서비스 포워딩

190 Tmax Application Development Guide

Page 209: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

시스템이 아닌 일반 호스트 시스템과 연동을 하여 운영하는 경우 일반적으로 서버 프로그램에서 소켓

을 열고 데이터를 주고 받는 과정을 클라이언트를 대신하여 수행한다. 그러나 외부 호스트 시스템과의

연결이 불안정하거나 서비스 시간이 길 경우 해당 서버 프로그램은 블록 상태에 놓이게 되고 추가적인

서비스를 수행하지 못한다.

이러한 경우를 해결하기 위해 서비스 루틴은 클라이언트의 요청을 받아 클라이언트의 정보를 저장하고

외부 호스트로 요청을 보내는 부분까지만 담당한다. 응답은 usermain() 루틴을 이용하여 저장된 클라이

언트의 정보와 함께 다른 서비스 루틴으로 넘겨진다. 그 서비스 루틴이 클라이언트에게 결과값을 보내

도록 하면 서버 프로그램은 블록되지 않고도 모든 과정을 수행할 수 있게 된다.

[그림 10.2] UCS 방식 서비스 포워딩

기 능함수

서버 라이브러리 내의 CTX_T 구조체의 값을 사용자 변수에 저장한다.tpgetctx

서버 라이브러리 내의 CTX_T 구조체의 내용을 지운다.tpcancelctx

서버 라이브러리 내에 클라이언트의 정보를 저장한다.tpsavectx

tpgetctx() 혹은 tpsavectx()로 얻은 클라이언트 정보/트랜잭션 정보와 함께 다

른 서비스 루틴으로 클라이언트의 관리를 넘긴다.(TCS 방식 서버 프로그램

에서 사용되는 tpforward()와 유사하다.)

tprelay

● usermain() 루틴 내에서의 비동기형 통신

usermain() 루틴 내에서 서비스 시간이 긴 비동기형 통신을 사용하는 경우 tpgetreply()에서 블록이 일어

나 스케줄링이 늦어지는 경우가 있다. 서비스 결과를 tpgetreply()로 받지 않고 콜백 함수을 지정하면 스

제10장 서버 API 191

Page 210: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

케줄링에 지장없이 결과값을 처리할 수 있다. 그러나 loop 시간이 짧은 usermain() 내에서 매번 비동기

형 통신이 일어나는 경우 최대 비동기형 서비스 수를 초과하게 되어 에러가 발생하게 되므로 주의한다.

기 능함수

비동기형 서비스 요청을 처리하는 콜백 함수를 설정한다.tpregcb

설정된 콜백 함수을 해제한다.tpunregcb

참고

함수와 관련 함수에 대한 자세한 사항은 Tmax 안내서 중 "Tmax Reference Guide" 를 참고한다.

10.2.1. tpschedule

UCS 서버 프로세스에서 데이터의 도착을 기다리는 함수이다. tpschedule()은 UCS 형태의 서버 프로세스

에서만 사용 가능한 함수로, 최대 타임아웃 시간동안 sleep하다가 그 안에 데이터가 도착하면 즉시 반환

한다.

tpschedule() 함수는 데이터가 도착했을 때 해당되는 서비스가 자동적으로 수행되고 난 후에 반환된다. 그

러므로 데이터가 도착한 후에 사용자가 임의로 서비스를 수행하지 않도록 한다. 서비스는 무조건 시스템

에 의해서 항상 수행되므로 UCS 형태의 서비스 프로그램이라도 이점을 주의해야 한다.

● 프로토타입

#include <ucs.h>

int tpschedule(int timeout)

● 파라미터

설명파라미터

타임아웃은 기다리고자 하는 시간을 초 단위로 입력해야 한다.timeout

타임아웃에 -1을 설정하면 데이터가 도착했는지 체크만 한 후 즉시 반환하고,

0을 설정하면 데이터가 도착할 때까지 한없이 대기한다.

● 반환값

설명반환값

함수가 수행에 성공해서 데이터가 도착한 경우양수

타임아웃 시간까지 데이터가 도착하지 않은 경우 또는 함수가 수행에 실패해

서 에러가 발생한 경우

-1

192 Tmax Application Development Guide

Page 211: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

(타임아웃 시간까지 데이터가 도착하지 않으면 -1을 반환하고, tperrno에 13

번(TPETIME)이 설정된다. 그 외의 경우 상황에 따라 tperrno에 변수값이 설

정된다.)

● 오류

tpschedule()에 실패하는 경우 상황에 따라 tperrno에 다음 에러 값들이 설정된다.

설명에러 코드

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

TIMEOUT으로 지정된 시간까지 데이터가 도착하지 않아서 타임아웃이 발생

하였다.

[TPETIME]

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/ucs.h>

int usermain(int argc, char *argv[])

{

...

while(1)

{

...

tpschedule(3);

ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf,

(long *)&rlen, TPNOFLAGS);

if (ret == -1) {

error processing

}

...

}

}

● 관련 함수

tpsleep(), tp_sleep(), tp_usleep()

제10장 서버 API 193

Page 212: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

10.2.2. tpuschedule

UCS 서버 프로세스에서 데이터의 도착을 micro second 단위로 입력한 시간동안 기다리는 함수이다.

tpuschedule()은 UCS 형태의 서버 프로세스에서만 사용 가능한 함수로, 최대 타임아웃 시간동안 대기하

다가 정해진 시간 안에 데이터가 도착하면 즉시 반환한다.

● 프로토타입

#include <ucs.h>

int tpuschedule (int timeout)

● 파라미터

설명파라미터

대기할 시간을 시간을 micro second 단위로 입력해야 한다.timeout

–1을 설정하면 데이터가 도착했는지 체크만 하고 즉시 종료하고, 0을 설정하

면 데이터가 도착할 때까지 대기한다.

● 반환값

설명반환값

타임아웃 시간까지 데이터가 도착하지 않는 경우0

타임아웃 시간까지 데이터가 도착한 경우양수

함수 호출에 에러가 발생하는 경우-1

(tperrno 변수 값이 설정된다.)

● 오류

tpuschedule() 실패하는 경우 상황에 따라 tperrno에 다음 에러 값이 설정된다.

설명에러 코드

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

...

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/ucs.h>

194 Tmax Application Development Guide

Page 213: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

int usermain(int argc, char *argv[])

{

...

while(1)

{

...

tpuschedule(3000000);

ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf,

(long *)&rlen, TPNOFLAGS);

if (ret == -1) { error processing }

...

}

}

● 관련 함수

tpschedule()

10.2.3. tpsetfd

서버/클라이언트에서 사용되는 함수로 소켓 fd를 UCS 프로세스의 스케줄러에 등록한다. tpsetfd()는 UCS

방식 프로세스를 사용한 소켓 fd를 켤 때 사용된다. UCS 방식 프로세스의 외부 소켓 스케줄링에 사용된다.

UCS 스케줄러는 TMM, CLH 뿐만 아니라 해당 소켓 fd에 도착한 메시지도 같이 검사하게 된다.

사용자가 지정한 소켓에 메시지가 도착했을 경우 tpschedule()은 별다른 처리없이 정상 결과(UCS_US

ER_MSG)를 반환하며 어떤 소켓에 메시지가 도착했는지를 알기 위해서는 아래에 설명된 tpisetfd()를 사

용해야 한다.

● 프로토타입

#include <ucs.h>

int tpsetfd (int fd)

● 파라미터

설명파라미터

등록할 소켓 fd를 설정한다.fd

● 반환값

설명반환값

함수 호출에 성공한 경우1

제10장 서버 API 195

Page 214: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

함수 호출에 실패한 경우-1

(tperrno에 에러상황에 해당하는 값이 설정된다. )

● 오류

tpsetfd()가 실패하는 경우 상황에 따라 tperrno에 아래값 중 하나가 설정된다.

설명에러 코드

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <errno.h>

#include <usrinc/ucs.h>

...

#define SERV_ADDR “168.126.185.129”

#define SERV_PORT 1500

int fd_read(int, char *, int);

extern int errno;

int usermain(int argc, char *argv[])

{

...

int listen_fd, n, newfd;

struct sockaddr_in my_addr, child_addr;

socklen_t child_len;

buf = tpalloc(“STRING”, NULL, 0);

if (buf == NULL){

error processing

}

memset((void *)&my_addr, NULL, sizeof(my_addr));

memset((void *)&child_addr, NULL, sizeof(child_addr));

listen_fd = socket(AF_INET, SOCK_STREAM, 0);

if (listen_fd == -1){

error processing

}

196 Tmax Application Development Guide

Page 215: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

my_addr.sin_family = AF_INET;

inaddr = inet_addr(SERV_ADDR);

my_addr.sin_port = htons((unsigned short)SERV_PORT);

if (inaddr != -1){

memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));

}

ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));

if (ret == -1){

error processing

}

ret = listen(listen_fd, 5);

if (ret == -1){

error processing

}

ret = tpsetfd(listen_fd);

if (ret == -1){

error processing

}

...

while(1) {

n = tpschedule(10);

...

if (n == UCS_USER_MSG){

if (tpissetfd(listen_fd)) {

child_len = sizeof(child_addr);

newfd = accept(listen_fd, &child_addr, &child_len);

if (newfd == -1){

error processing

}

ret = tpsetfd(newfd);

if (ret == -1){

error processing

}

}

if (tpissetfd(newfd)){

/* 소켓으로 부터 버퍼를 읽는다 */

fd_read(newfd, buf, 1024);

ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,

(long *)&rlen, TPNOFLAGS);

if (ret == -1){

error processing

제10장 서버 API 197

Page 216: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

...

tpclrfd(newfd);

close(newfd);

}

...

}

return 1;

}

● 관련 함수

tpclrfd(), tpissetfd()

10.2.4. tpissetfd

서버에서 UCS 프로세스에서 소켓 fd로 데이터가 도착했는지를 검사하는 함수이다. UCS 방식 서버 프로

세스의 외부 소켓을 스케줄링하는데 사용한다.

● 프로토타입

#include <ucs.h>

int tpissetfd (int fd)

● 파라미터

설명파라미터

테스트 할 fdset 내부의 fd를 설정한다.fd

● 반환값

설명반환값

메시지가 도착했을 경우양수

메시지가 도착하지 않은 경우0

함수 호출에 실패한 경우-1

(tperrno에 상황에 해당하는 값이 설정된다.)

● 오류

tpissetfd() 호출을 실패할 경우 상황에 따라 tperrno에 다음 에러값이 설정된다.

198 Tmax Application Development Guide

Page 217: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명에러 코드

Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <errno.h>

#include <usrinc/ucs.h>

...

#define SERV_ADDR “168.126.185.129”

#define SERV_PORT 1500

int fd_read(int, char *, int);

extern int errno;

int usermain(int argc, char *argv[])

{

...

int listen_fd, n, newfd;

struct sockaddr_in my_addr, child_addr;

socklen_t child_len;

buf = tpalloc(“STRING”, NULL, 0);

if (buf == NULL){ error processing }

memset((void *)&my_addr, NULL, sizeof(my_addr));

memset((void *)&child_addr, NULL, sizeof(child_addr));

listen_fd = socket(AF_INET, SOCK_STREAM, 0);

if (listen_fd == -1){ error processing }

my_addr.sin_family = AF_INET;

inaddr = inet_addr(SERV_ADDR);

my_addr.sin_port = htons((unsigned short)SERV_PORT);

if (inaddr != -1)

memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));

ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));

if (ret == -1){ error processing }

ret = listen(listen_fd, 5);

if (ret == -1){ error processing }

tpsetfd(listen_fd);

...

while(1) {

n = tpschedule(10);

제10장 서버 API 199

Page 218: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

...

if (n == UCS_USER_MSG){

if (tpissetfd(listen_fd)) {

child_len = sizeof(child_addr);

newfd = accept(listen_fd, &child_addr, &child_len);

if (newfd == -1){ error processing }

tpsetfd(newfd);

}

if (tpissetfd(newfd)){

/* 소켓으로 부터 버퍼를 읽는다 */

fd_read(newfd, buf, 1024);

ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,

(long *)&rlen, TPNOFLAGS);

if (ret == -1){ error processing }

...

tpclrfd(newfd);

close(newfd);

}

...

}

}

return 1;

}

● 관련함수

tpissetfd(), tpsetfd()

10.2.5. tpclrfd

UCS 방식 프로세스 내부의 fdset의 소켓 fd를 off 시키는데 사용되는 함수로 UCS 방식 서버 프로세스의

외부 소켓을 스케줄링하는 경우에 사용한다.

● 프로토타입

#include <ucs.h>

int tpclrfd (int fd)

● 파라미터

설명파라미터

off할 내부 fdset의 소켓이다.fd

200 Tmax Application Development Guide

Page 219: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 에러 상황에 해당되는 값이 설정된다.)

● 오류

tpclrfd() 호출을 실패할 경우 상황에 따라 tperrno에 아래 값 중 하나가 설정된다.

설명에러 코드

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <errno.h>

#include <usrinc/ucs.h>

….

#define SERV_ADDR “168.126.185.129”

#define SERV_PORT 1500

int fd_read(int, char *, int);

extern int errno;

int usermain(int argc, char *argv[])

{

...

int listen_fd, n, newfd;

struct sockaddr_in my_addr, child_addr;

socklen_t child_len;

buf = tpalloc(“STRING”, NULL, 0);

if (buf == NULL){ error processing }

memset((void *)&my_addr, NULL, sizeof(my_addr));

memset((void *)&child_addr, NULL, sizeof(child_addr));

listen_fd = socket(AF_INET, SOCK_STREAM, 0);

if (listen_fd == -1){ error processing }

제10장 서버 API 201

Page 220: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

my_addr.sin_family = AF_INET;

inaddr = inet_addr(SERV_ADDR);

my_addr.sin_port = htons((unsigned short)SERV_PORT);

if (inaddr != -1){

memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));

}

ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));

if (ret == -1){ error processing }

ret = listen(listen_fd, 5);

if (ret == -1){ error processing }

tpsetfd(listen_fd);

...

while(1) {

n = tpschedule(10);

...

if (n == UCS_USER_MSG){

if (tpissetfd(listen_fd)) {

child_len = sizeof(child_addr);

newfd = accept(listen_fd, &child_addr, &child_len);

if (newfd == -1){ error processing }

tpsetfd(newfd);

}

if (tpissetfd(newfd)){

/* 소켓으로 부터 버퍼를 읽는다 */

fd_read(newfd, buf, 1024);

ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf,

(long *)&rlen, TPNOFLAGS);

if (ret == -1){ error processing }

...

ret = tpclrfd(newfd);

if (ret == -1){ error processing }

close(newfd);

}

...

}

202 Tmax Application Development Guide

Page 221: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

return 1;

}

● 관련 함수

tpissetfd()

10.2.6. tpsavectx

UCS 프로세스에서 사용되며 클라이언트의 정보를 내부적으로 관리하도록 한다. tpsavectx()는 tprelay()

함수와 함께 사용된다. tprelay()는 처리 결과를 다른 서비스로 전달하는 역할을 수행한다. 일반적인 서비

스 프로그램에서 tpforward 형식으로 다른 서비스를 호출한 것과 동일하게 동작하게 된다. 결과적으로 호

출된 서비스에서는 처리된 결과값을 해당 클라이언트에게 전달하게 된다.

tpsavectx() 함수는 대외기관 업무와 같이 다른 프로토콜이 이용되며 시간이 많이 소요되어 채널이 묶일

수 있는 가능성이 많은 경우에 사용되게 된다.

일반적으로 사용되는 형태는 다음과 같다.

클라이언트 → svc1 → svc2(service, tpsavectx) → 대외기관

클라이언트 ← svc3 ← svc2(usermain, tprelay) ← 대외기관

1. svc1에서는 tpforward(...TPNOREPLY)를 이용해서 호출한다.

2. svc2는 UCS 프로세스에 존재하는 서비스이며 서비스 루틴 내에서 tpsavectx()를 사용하여 클라이언트

의 정보를 저장하며 대외 기관과 통신을 하게 된다.

3. 결과는 usermain에서 수신하게 되며 이를 tprelay()를 통해서 svc3에게 전달하게 된다. 이 경우 svc3는

svc2에서 tpforward로 자신을 호출한 것으로 간주하여 최종 결과를 주어진 클라이언트에게 전달하게

된다.

svc1에서 서비스를 TPNOREPLY로 전달하고 있기 때문에 채널이 묶이는 것을 방지할 수 있어 작은 수의

업무 프로세스로도 많은 클라이언트를 감당할 수 있다. 또한 하나의 UCS 프로세스로서 송, 수신 프로세

스 역할을 수행하여 비교적 단순한 시스템을 구성할 수 있다. 이는 시스템 관리 측면에서도 효율적이다.

● 프로토타입

#include <ucs.h>

CTX_T * tpsavectx()

● 반환값

설명반환값

함수 호출에 성공한 경우CTX_T

제10장 서버 API 203

Page 222: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

함수 호출에 실패한 경우NULL

● 오류

설명에러 코드

tpsavectx() 함수는 반드시 서비스 루틴 내에서 사용해야 한다. 서비스 루틴

이 아닌 곳에 사용되는 경우에는 TPEPROTO 에러가 발생한다. tpsvrinit()

혹은 tpsvrdone()에서는 사용될 수 없다.

[TPEPROTO]

메모리 할당 오류가 발생하였다.[TPESYSTEM]

● 예제

...

#include <stdio.h>

#include <usrinc/ucs.h>

CTX_T *ctx = NULL;

usermain(int argc, char *argv[])

{

int ret, i;

char *rcvbuf, *sndbuf;

long sndlen;

rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);

if (rcvbuf == NULL){ error processing }

i = 0;

while(1) {

tpschedule(1);

if (ctx != NULL)

{

i++;

if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)

{ error processing }

else

{

...

ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);

if (ret==-1) { error processing }

data process...

ctx = NULL;

tpfree(sndbuf);

}

}

}

204 Tmax Application Development Guide

Page 223: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

int RELAY(TPSVCINFO *rqst)

{

...

ctx = tpsavectx();

tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);

}

● 관련 함수

tpreturn(), tpforward(), tprelay()

10.2.7. tpgetctx

현재 클라이언트의 정보를 사용자가 선언, 할당한 CTX_T 구조체에 복사해오는 함수이다. tpgetctx()를 사

용했을 경우 tprelay()로 이 정보를 사용하지 않을 경우 해당 서비스 루틴이 완료되더라도 클라이언트는

계속 응답을 기다리게 된다. tpgetctx()로 얻어진 정보는 tpcancelctx()로 취소할 수 없으므로 반드시 tprelay()

를 사용해야 한다.

tpgetctx()는 서비스 루틴 내에서만 사용할 수 있다.

● 프로토타입

#include <tmaxapi.h>

int tpgetctx (CTX_T *ctxp)

● 파라미터

설명파라미터

tpsavectx()로 저장된 클라이언트의 정보를 CTX_T 구조체로 받아온다.ctxp

● 예제

RELAY_SVC(TPSVCINFO *msg) {

CTX_T *ctxp;

ctxp=(CTX_T *)malloc(sizeof(CTX_T);

....

ret = tpgetctx(ctxp);

if (ret<0) {

error process routine

}

.....

}

제10장 서버 API 205

Page 224: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

10.2.8. tpcancelctx

tpsavectx()로 저장된 클라이언트 정보들 중 해당 구조체의 내용을 취소하는 함수이다. tprelay()를 수행하

지 않아도 서비스 루틴이 종료되면 정상적으로 결과가 반환된다.

tpgetctx()는 서비스 루틴 내에서만 사용할 수 있다.

● 프로토타입

#include <tmaxapi.h>

int tpgetclid(void)

● 파라미터

설명파라미터

라이브러리 내부에 저장된 CTX_T 구조체의 내용을 지운다.ctxp

● 예제

RELAY_SVC(TPSVCINFO *msg) {

.....

ctxp = (CTX_T *)tpsavectx();

.....

ret=tpcancelctx(ctxp);

if (ret<0) {

error process routine

}

.....

tpreturn(TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

10.2.9. tprelay

UCS 서버 프로세스에서 서비스를 요청한 클라이언트의 정보를 담아서 또 다른 서비스를 요청하는 함수

이다. tprelay()는 UCS 형태의 서버 프로세스에서만 사용 가능한 함수로 서비스를 요청한 클라이언트에

대한 정보를 담아서 또 다른 서비스를 요청하는 방식으로 멀티 노드 간에도 서비스가 이루어진다. 이런 형

식을 취하면 tprelay()를 통해서 호출된 서비스는 마치 클라이언트가 자기를 직접 호출한 것으로 인식하고

서비스의 수행결과는 최초 서비스를 요청한 클라이언트에게 전달된다.

서비스 수행 결과를 호출한 클라이언트에게 전달할 수 있으므로 UCS 프로세스에서 간단한 구성을 통해

빠른 응답을 유도할 수 있다. 대체적으로 2번~3번의 서비스를 호출해야만 결과를 얻어 낼수 있는 프로그

램 루틴인 대외기간 업무와 연동하여 서비스를 처리하는 경우에 사용하는 것이 좋다.

● 프로토타입

206 Tmax Application Development Guide

Page 225: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <ucs.h>

int tprelay(char *svc, char *data, long len, long flags, CTX_T *ctxp);

● 파라미터

설명파라미터

Tmax 환경파일에 등록된 서비스 이름을 지정한다.svc

서비스를 호출 할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc()

으로 할당된 버퍼를 사용하여야 한다.

data

보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입

일 경우에는 반드시 설정해야 한다.

len

현재 사용되지 않으며 TPNOFLAGS를 설정한다.flags

tpgetctx() 혹은 tpsavectx()로 받아온 정보 구조체이다.ctxp

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(상세 에러는 tperrno에 세팅된다.)

● 오류

tprelay()에 실패하는 경우 상황에 따라 tperrno에 다음 에러값이 설정된다.

설명에러 코드

함수에 사용된 인자값이 잘못된 경우이다.[TPEINVAL]

예를 들어 ctxp가 NULL이거나 잘못된 버퍼를 사용한 경우에 발생한다

Tmax 시스템적인 에러가 발생하였다.[TPESYSTEM]

● 예제

...

#include <stdio.h>

#include <usrinc/ucs.h>

CTX_T *ctx = NULL;

DUMMY(TPSVCINFO *msg)

{

data process ….

제10장 서버 API 207

Page 226: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

usermain(int argc, char *argv[])

{

int ret, i;

char *rcvbuf, *sndbuf;

long sndlen;

rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);

if (rcvbuf == NULL){ error processing }

i = 0;

while(1) {

tpschedule(1);

if (ctx != NULL)

{

i++;

if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)

{ error processing }

else

{

...

ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);

if (ret==-1) { error processing }

data process...

ctx = NULL;

tpfree(sndbuf);

}

}

}

}

int RELAY(TPSVCINFO *rqst)

{

...

ctx = tpsavectx();

tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);

}

● 관련 함수

tpreturn(), tpforward()

208 Tmax Application Development Guide

Page 227: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

10.2.10. tpregcb

서버에서 UCS에서 비동기형 요청에 대한 응답을 받는 루틴을 설정하는 함수로 UCS 방식 프로세스가 서

버 프로그램으로부터 응답을 받았을 때 이를 처리할 루틴을 설정하는 함수이다. UCS 방식 서버 프로세스

에 tpgetreply() 대신 사용된다.

● 프로토타입

# include <ucs.h>

int tpregcb (UcsCallback)

● 파라미터

내용파라미터

비동기형 서비스 호출인 tpacall()에 대한 응답을 받는 콜백 함수를 설정한다.UcsCallback

usermain() 루틴에서 사용된 tpacall() 에 대한 응답을 콜백 함수로 처리하고 싶을 때 사용한다. 처리시점

은 tpschedule() 혹은 tpuschedule()이 수행되었을 때이다. 콜백 함수의 인수로 사용되는 UCSMSGINFO

구조체의 내용은 아래와 같다.

UCSMSGINFO {

ong urcode,

int errcode,

int msgtype,

int cd,

long len,

char *data

}

설명멤버

사용자가 지정한 urcode 값이다.urcode

에러 상황일 경우 에러코드가 저장된다.errcode

Tmax 시스템이 내부적으로 사용하는 메시지 타입이다. tpacall()에 대한 정상

적인 응답은 1004로 나타난다.

msgtype

tpacall()로 얻어지는 구별자이다.cd

요청 데이터 길이로서 CARRAY, X_OCTET, 구조체 배열인 경우 값이 설정

된다.

len

해당 서비스에서 온 결과값으로 main() 루틴 내에서 tpalloc()으로 할당된 버

퍼이다. 클라이언트에서 사용된 버퍼 형식으로 형변환하여 사용한다. 사용자

임의로 메모리 해제할 수 없다.

*data

● 예제

제10장 서버 API 209

Page 228: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

usermain() {

tpregcb(reply_receive)

while(1){

tpacall(“SVC”, msg->data, msg->len, TPNOFLAGS);

.....

}

}

int reply_receive(UCSMSGINFO *reply) {

printf("errcode : %d\n", reply->errcode);

printf("msgtype : %d\n", reply->msgtype);

printf("cd : %d\n", reply->cd);

printf("data....%s\n", reply->data);

return 0;

}

10.2.11. tpunregcb

서버에서 UCS에서 비동기형 요청에 대한 응답을 받는 루틴을 재설정하는 함수이다. tpunregcb()는 서버

프로그램에서 응답을 받으면 수행되는 루틴을 재설정(reset)하는 함수로, UCS 방식 서버 프로세스에 사

용된다.

● 프로토타입

#include <ucs.h>

int tpunregcb (void )

● 반환값

설명반환값

함수 호출에 성공한 경우1

함수 호출에 실패한 경우-1

(tperrno에 해당하는 에러상황을 설정한다.)

● 오류

설명에러 코드

Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그파일에 기록된다.[TPESYSTEM]

운영 시스템에 에러가 발생하였다.[TPEOS]

● 예제

210 Tmax Application Development Guide

Page 229: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

...

#include <usrinc/atmi.h>

#include <usrinc/ucs.h>

void reply_receive(UCSMSGINFO *reply);

int usermain(int argc, char *argv[])

{

...

ret = tpregcb(reply_receive);

if (ret == -1){

error processing

}

ret = tpunregcb();

if (ret == -1){

error processing

}

while(1)

{

...

tpschedule(3);

cd = tpacall(“SERVICE”, buf, strlen(buf), TPNOFLAGS);

if (cd < 0) {

error processing

}

...

}

}

void reply_receive(UCSMSGINFO *reply) {

printf(“first reply receive\n”);

printf(“data....%s\n”, reply->data);

}

● 관련 함수

tpregcb()

제10장 서버 API 211

Page 230: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115
Page 231: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제11장 예제

11.1. 통신 유형 예제본 절에서는 Tmax에서 사용하는 3가지 통신형인 동기형, 비동기형, 대화형 애플리케이션의 간단한 예제

를 통해 전체적인 흐름에 대한 이해를 돕고자 한다.

11.1.1. 동기형 통신

클라이언트는 string형 버퍼에 문자열을 복사해서 서비스를 호출하고 서버측의 서비스 루틴은 이 문자열

을 받아서 대문자열로 바꾸어 반환하는 프로그램이다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.sync_cli.c

대문자로 바꾸는 서비스 프로그램이다.syncsvc.c

Tmax에서 제공되는 Makefile로 수정해야 한다.Makefile

Tmax 환경설정 파일이다.sample.m

● 프로그램 특징

설명구분

- Tmax 연결 : 기본 연결(클라이언트 정보 없음)클라이언트 부분

- 버퍼 유형 : STRING

- 통신 유형 : tpcall()을 이용한 동기형 통신

- 서비스 : TOUPPERSTR서버 부분

- 데이터베이스 연결: 없음

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<sync_cli.c>

제11장 예제 213

Page 232: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <stdio.h>

#include <string.h>

#include <usrinc/atmi.h>

main(int argc,char *argv[])

{

char *sendbuf, *recvbuf;

long rlen;

if (argc != 2)

{

fprintf(stderr,“Usage: $ %s string \n”,argv[0]);

exit(1);

}

if (tpstart((TPSTART_T*)NULL) == -1)

{

fprintf(stderr,“Tpstart failed\n”);

exit(1);

}

if ((sendbuf = tpalloc(“STRING”,NULL,0)) == NULL) {

fprintf(stderr,“Error allocation send buffer\n”);

tpend();

exit(1);

}

if ((recvbuf = tpalloc(“STRING”,NULL,0)) == NULL) {

fprintf(stderr,“Error allocation recv buffer\n”);

tpend();

exit(1);

}

strcpy(sendbuf ,argv[ 1 ] ) ;

if ( tpcall(“TOUPPERSTR”,sendbuf,0,&sendbuf,&rlen, TPNOFLAGS) == -1)

{

fprintf(stderr,“Can’t send request to service TOUPPER->%s!\n”,

tpstrerror(tperrno)) ;

tpfree(sendbuf) ;

tpfree(recvbuf) ;

tpend();

exit(1);

}

printf(“Sent value:%s\n ”,sendbuf );

printf(“Returned value:%s\n ”,recvbuf );

tpfree(sendbuf);

214 Tmax Application Development Guide

Page 233: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpfree(recvbuf);

tpend( );

서버 프로그램

다음은 서버 프로그램 예제이다.

<syncsvc.c>

#include <stdio.h>

#include <usrinc/atmi.h>

TOUPPERSTR(TPSVCINFO *msg)

{

int i;

for (i = 0; i < msg->len ; i++)

msg->data[i] = toupper(msg->data[i]);

msg->data[i] = ‘\0’;

tpreturn(TPSUCCESS, 0, msg->data, 0, TPNOFLAGS);

}

Tmax 환경파일

다음은 Tmax 환경파일 설정 예제이다.

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR = “/home/tmax”,

APPDIR = “/home/tmax/appbin”,

PATHDIR = “/home/tmax/path”,

TLOGDIR = “/home/tmax/log/tlog”,

ULOGDIR = “/home/tmax/log/slog”,

SLOGDIR = “/home/tmax/log/ulog”

*SVRGROUP

svg1 NODENAME = tmax

*SERVER

syncsvc SVGNAME = svg1,

제11장 예제 215

Page 234: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

MIN = 1, MAX = 5,

CLOPT = “ –e $(SVR).err –o $(SVR).out “

*SERVICE

TOUPPERSTR SVRNAME = syncsvc

11.1.2. 비동기형 통신

클라이언트는 구조체형 버퍼의 멤버에 문자열을 복사해서 서비스를 호출하고 서버 측의 서비스 루틴은

이 문자열을 받아서 소문자열 혹은 대문자열로 바꾸어 반환하는 프로그램이다.

클라이언트는 비동기형 통신으로 TOUPPER 서비스를 요청하고 다시 동기형으로 TOLOWER 서비스를

호출하여 결과를 받은 다음 앞서 요청한 TOUPPER 서비스의 수행결과를 받는다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.async_cli.c

대문자/소문자로 바꾸는 서비스 프로그램이다.asyncsvc.c

Tmax에서 제공되는 Makefile로 수정해야 한다.Makefile

Tmax 환경설정 파일이다.sample.m

● 프로그램 특징

설명구분

- Tmax 연결 : 기본 연결클라이언트 부분

- 버퍼유형 : 구조체 버퍼(STRUCT)

- 통신 유형 : 동기형 및 비동기형

- 서비스 : TOUPPER, TOLOWER서버 부분

- 데이터베이스 연결: 없음

구조체 버퍼다음은 비동기형 통신에서 사용하는 구조체 버퍼이다.

<demo.s>

struct strdata {

int flag;

216 Tmax Application Development Guide

Page 235: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char sdata[20];

};

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<async_cli.c>

#include <stdio.h>

#include <string.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

main(int argc,char *argv[ ])

{

struct strdata *sendbuf, *sendbuf1;

long dlen,clen;

int cd;

if (argc != 3) {

fprintf(stderr, “Usage: $ %s string STRING\n”, argv[0], argv[1]);

exit(1) ;

}

if (tpstart((TPSTART_T *)NULL) == -1) {

fprintf(stderr, “TPSTART_T failed\n”);

exit(1) ;

}

sendbuf = (struct strdata *)tpalloc(“STRUCT”, “strdata”, 0);

if ( sendbuf == NULL) {

fprintf(stderr, “Error allocation send buffer\n”);

tpend () ;

exit(1) ;

}

sendbuf1 = (struct strdata *)tpalloc(“STRUCT”, “strdata”, 0);

if (sendbuf1 == NULL) {

fprintf(stderr, “Error allocation send1 buffer\n”);

tpend();

exit(1) ;

}

strcpy(sendbuf->sdata, argv[1]);

strcpy(sendbuf1->sdata, argv[2]);

제11장 예제 217

Page 236: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if ((cd = tpacall(“TOUPPER”, (char *)sendbuf, 0, TPNOFLAGS)) == -1) {

fprintf(stderr, “Toupper error -> %s”, tpstrerror(tperrno));

tpfree((char *)sendbuf);

tpend();

exit(1) ;

}

if (tpcall(“TOLOWER”,(char *)sendbuf1,0,(char **)&sendbuf1, &dlen,

TPSIGRSTRT) == -1) {

fprintf(stderr, “Tolower error -> %s”, tpstrerror(tperrno));

tpfree((char *)sendbuf);

tpend();

exit(1) ;

}

if (tpgetrply(&cd, (char **)&sendbuf, &clen, TPSIGRSTRT) == -1) {

fprintf(stderr, “Toupper getrply error -> %s”, tpstrerror(tperrno));

tpfree((char *)sendbuf);

tpend();

exit(1) ;

}

printf(“Return value %s\n %s\n”, sendbuf -> sdata, sendbuf1 -> sdata);

tpfree((char *)sendbuf);

tpfree((char *)sendbuf1);

tpend() ;

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<asyncsvc.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

TOUPPER(TPSVCINFO *msg)

{

int i = 0;

struct strdata *stdata;

stdata = (struct strdata *)msg -> data;

218 Tmax Application Development Guide

Page 237: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

while (stdata->sdata[ i ] != ‘\0’) {

stdata->sdata[ i ] = toupper(stdata->sdata[ i ]);

i++ ;

}

tpreturn(TPSUCCESS, 0, (char *)stdata, 0, TPNOFLAGS);

}

TOLOWER(TPSVCINFO *msg)

{

int i = 0;

struct strdata *stdata;

stdata = (struct strdata *)msg -> data;

while ( stdata->sdata[ i ] != ‘\0’) {

stdata->sdata[ i ] = tolower(stdata->sdata[ i ]);

i++;

}

tpreturn(TPSUCCESS, 0, (char *)stdata, 0, TPNOFLAGS);

}

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR =“/home/tmax”,

APPDIR =“/home/tmax/appbin”,

PATHDIR =“/home/tmax/path”

*SVRGROUP

svg1 NODENAME = tmax

*SERVER

asyncsvc SVGNAME = svg1, MIN = 1, MAX = 5

*SERVICE

제11장 예제 219

Page 238: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TOUPPER SVRNAME = asyncsvc

TOLOWER SVRNAME = asyncsvc

11.1.3. 대화형 통신

클라이언트는 사용자의 입력을 받아 STRING 버퍼를 통해 고유번호를 보내며 서버 측의 서비스 루틴은

데이터베이스에 저장된 테이블에서 그 고유번호보다 큰 번호를 가지는 고객정보를 구조체를 통해 반환해

준다. 클라이언트는 대화형 모드를 설정하면서 고유번호를 보내며 대화 주도권은 서버에 넘긴다. 서버는

조건을 만족하는 데이터베이스의 모든 데이터를 커서를 통해 읽어서 클라이언트로 보낸다.

클라이언트는 TPEVSVCSUCC를 통해 이상없이 모든 데이터를 읽어왔다는 것을 확인할 수 있다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.conv_cli.c

구조체를 정의한 파일이다.demo.s

서버 프로그램이다.convsvc.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

Tmax 환경설정 파일이다.sample.m

● 프로그램 특징

설명구분

- Tmax 연결 : 기본 연결클라이언트 부분

- 버퍼 유형: 보낼 때 STRING, 받을 때는 STRUCT 타입 사용

- 통신 유형 : 대화형 통신

- 서비스 : MULTI서버 부분

- 데이터베이스 연결 : Oracle 사용

구조체 버퍼

다음은 대화형 통신에서 사용하는 구조체 버퍼이다.

<demo.s>

struct sel_o {

char seqno[10];

char corpno[10];

220 Tmax Application Development Guide

Page 239: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char compdate[8];

int totmon;

float guarat;

float guamon;

} ;

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<conv_cli.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

main(int argc, char *argv[])

{

struct sel_o *rcvbuf;

char *sndbuf;

long sndlen, rcvlen, revent;

int cd;

if (argc != 2) {

printf("Usage: client string\n");

exit(1);

}

/* tpstart()와 함께 Tmax에 연결함. */

if (tpstart((TPSTART_T *) NULL) == -1) {

printf("tpstart failed\n");

exit(1);

}

if ((sndbuf = tpalloc("STRING", NULL, 12)) == NULL) {

printf("tpalloc failed:sndbuf\n");

tpend();

exit(1);

}

if ((rcvbuf = (struct sel_o *)tpalloc("STRUCT", "sel_o", 0)) == NULL) {

printf("tpalloc failed:rcvbuf\n");

tpfree(sndbuf);

tpend();

exit(1);

}

제11장 예제 221

Page 240: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

strcpy(sndbuf, argv[1]);

if ((cd = tpconnect ("MULTI", sndbuf, 0, TPRECVONLY)) == -1){

printf("tpconnect failed:CONVER service, tperrno=%d\n", tperrno);

tpfree(sndbuf);

tpfree((char *)rcvbuf);

tpend();

exit(1);

}

/* 대화형 통신 연결, 대화 주도권은 서버측에 넘김 */

printf("tpconnect SUCESS \"MULTI\" service\n");

while ( 1 ) { /* 다중 데이터 수신. */

printf("tprecv strat\n");

if( tprecv(cd, (char **)&rcvbuf, &rcvlen, TPNOTIME, &revent) < 0 ) {

/* 서버에서 tpreturn()으로 끝냈다면 */

if (revent == TPEV_SVCSUCC){

printf("all is completed\n");

break;

}

printf("tprecv failed, tperrno=%s, revent=%x\n",

tpstrerror(tperrno), revent );

tpfree(sndbuf);

tpfree((char *)rcvbuf);

tpend();

exit(1);

}

printf("seqno = %s\t\t corpno =%s\n", rcvbuf->seqno, rcvbuf->corpno);

printf("compdate = %s\t\t totmon =%d\n", rcvbuf->compdate, rcvbuf->totmon);

printf("guarat = %f\t\t guamon =%f\n\n\n", rcvbuf->guarat, rcvbuf->guamon) ;

}

tpfree(sndbuf);

tpfree((char *)rcvbuf);

tpend();

printf("FINISH\n");

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<convsvc.pc>

#include <stdio.h>

#include <string.h>

222 Tmax Application Development Guide

Page 241: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

EXEC SQL begin declare section; /* Oracle 전역 변수 선언 */

char seq[10];

struct sel_o *sndbuf;

EXEC SQL end declare section;

EXEC SQL include sqlca;

MULTI(TPSVCINFO *msg)

{

int i, cd;

long sndlen, revent;

memset(seq, 0, 10);

strcpy(seq, msg->data);

if ((sndbuf = (struct sel_o *) tpalloc (“STRUCT”, “sel_o”, 0)) == NULL) {

printf(“tpalloc failed:\n”);

tpreturn (TPFAIL, -1, NULL, 0, TPNOFLAGS);

}

/* 다량 데이터 위해 커서 선언 */

EXEC SQL declare democursor cursor for

select *

from corp

where seqno > :seq;

EXEC SQL open democursor;

EXEC SQL whenever not found goto end_of_fetch;

if (sqlca.sqlcode != 0){

printf(“oracle sqlerror=%s”, sqlca.sqlerrm.sqlerrmc);

tpreturn (TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

/* Oracle 에러가 없는 동안 데이터 전송 */

while ( sqlca.sqlcode == 0 ){

EXEC SQL fetch democursor into :sndbuf;

if (tpsend (msg->cd, (char *)sndbuf, 0, TPNOTIME, &revent) == -1){

printf(“tpsend failed, tperrno=%d, revent=%x\n”, tperrno,

revent ) ;

tpfree ((char *)sndbuf);

tpreturn (TPFAIL, -1, NULL, 0, TPNOFLAGS);

제11장 예제 223

Page 242: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

}

tpreturn (TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

end_of_fetch:

exec sql close democursor;

printf(“tpreturn before”);

tpreturn (TPSUCCESS, 0, NULL, 0, TPNOFLAGS);

}

테이블 생성 스크립트

다음은 Oracle 테이블 생성 스크립트 예제이다.

<mktable.sql>

sqlplus scott/tiger << EOF

create table multi_sel

(

seqno VARCHAR(10),

corpno VARCHAR(10),

compdate VARCHAR(8),

totmon NUMERIC(38),

guarat FLOAT,

guamon FLOAT

);

create unique index idx_tdb on multi_sel(seqno);

EOF

테이블 및 데이터 출력 스크립트

다음은 Oracle 테이블 및 데이터 출력 스크립트 예제이다.

<sel.sql >

sqlplus scott/tiger << EOF

Desc multi_sel;

select * from multi_sel;

EOF

Tmax 환경파일

다음은 Tmax 환경파일 설정 예제이다.

224 Tmax Application Development Guide

Page 243: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

<sample.m>

* DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR = “/home/tmax”,

APPDIR = “/home/tmax/appbin”,

PATHDIR =“/home/tmax/path”

* SVRGROUP

svg1 NODENAME = tmax,

DBNAME = ORACLE,

OPENINFO = “ORACLE_XA+Acc=P/scott/tiger+SesTm=60”,

TMSNAME = svg1_tms

*SERVER

convsvc SVGNAME = svg1, CONV = Y

*SERVICE

MULTI SVRNAME = convsvc

다음은 환경 설정에 추가된 항목에 대한 설명이다.

설명항목

사용하는 데이터베이스명을 정의한다.DBNAME

Oracle 데이터베이스와 연동하기 위한 연결 정보를 설정한다.OPENINFO

전역 트랜잭션 처리를 주재하는 프로세스 이름을 설정한다.TMSNAME

대화형 모드 서버를 지정한다.CONV = Y

11.2. 전역 트랜잭션 프로그램 예제전역 트랜잭션(Global Transaction Processing)이란 하나 이상의 자원 관리자(데이터베이스)와 하나 이상

의 물리적인 사이트가 하나의 논리적인 단위로 참여하는 트랜잭션이다. Tmax 시스템에서는 모든 트랜잭

션을 일단 전역 트랜잭션으로 간주하며, 데이터의 무결성을 위해 2PC(Two-Phase Commit)를 사용한다.

클라이언트는 사용자의 입력을 받아 구조체 버퍼를 통해 고유번호와 데이터를 보내며 서버 측은 해당 고

유번호의 데이터를 업데이트하고 이 데이터로 다른 데이터베이스를 사용하는 서비스를 호출하여 테이블

에 추가한다. 클라이언트는 이 모든 과정을 하나의 트랜잭션으로 지정하여 에러가 발생하였을 경우 2개의

데이터베이스를 동시에 rollback할 수 있도록한다.

제11장 예제 225

Page 244: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

[그림 11.1] 2개의 데이터베이스 접속

다음은 전역 트랜잭션 처리 프로그램의 특징이다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

데이터베이스에 UPDATE하는 서버 프로그램이다.update.pc

데이터베이스에 INSERT하는 서버 프로그램이다.insert.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

Tmax 환경설정 파일이다.sample.m

데이터베이스에 테이블로 생성하는 SQL 스크립트이다.mktable.sql

● 프로그램 특징

설명구분

- Tmax 접속 : 기본 접속클라이언트 부분

- 사용 버퍼 : 구조체 버퍼(STRUCT) 사용

- 통신 유형 : tpcall()에 의한 동기 통신

- 트랜잭션 처리: 클라이언트에서 트랜잭션 범위 지정

- 서버 프로그램 : 서로 다른 데이터베이스를 사용하는 2개의 서버 프로그램서버 부분

- 서비스 : UPDATE , INSERT

- 데이터베이스 연결 : 2종류의 Oracle 데이터베이스

226 Tmax Application Development Guide

Page 245: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

구조체 버퍼

다음은 전역 트랜잭션에서 사용하는 구조체 버퍼이다.

<demo.s>

struct input {

int account_id;

int branch_id;

char phone[15];

char address[61];

};

클라이언트 프로그램다음은 클라이언트 프로그램 예제이다.

<client.c >

#include <stdio.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

#define TEMP_PHONE "6283-2114"

#define TEMP_ADDRESS "Korea"

int main(int argc, char *argv[])

{

struct input *sndbuf;

char *rcvbuf;

int acnt_id, n, timeout;

long len;

if (argc != 2) {

fprintf(stderr, "Usage:%s account_id \n", argv[0]);

exit(1);

}

acnt_id = atoi(argv[1]);

timeout = 5;

n = tmaxreadenv("tmax.env", "tmax");

if (n < 0) {

제11장 예제 227

Page 246: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

fprintf(stderr, "tmaxreadenv fail! tperrno = %d\n", tperrno);

exit(1);

}

n = tpstart((TPSTART_T *)NULL);

if (n < 0) {

fprintf(stderr, "tpstart fail! tperrno = %s\n", tperrno);

exit(1);

}

sndbuf = (struct input *)tpalloc("STRUCT", "input", sizeof(struct input));

if (sndbuf == NULL) {

fprintf(stderr, "tpalloc fail: sndbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

rcvbuf = (char *)tpalloc("STRING", NULL, 0);

if (rcvbuf == NULL) {

fprintf(stderr, "tpalloc fail: rcvbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

sndbuf->account_id = acnt_id;

sndbuf->branch_id = acnt_id;

strcpy(sndbuf ->phone, TEMP_PHONE);

strcpy(sndbuf ->address, TEMP_ADDRESS);

tx_set_transaction_timeout(timeout);

n = tx_begin();

if (n < 0)

fprintf(stderr, "tx begin fail! tperrno = %d\n", tperrno);

n = tpcall("UPDATE", (char *)sndbuf, sizeof(struct input), (char **)&rcvbuf,

(long *)&len, TPNOFLAGS);

if (n < 0) {

fprintf(stderr, "tpcall fail! tperrno = %d\n", tperrno);

tpend();

exit(1);

}

n = tx_commit();

if (n < 0) {

fprintf(stderr, "tx commit fail! tx error = %d \n", n);

tx_rollback();

228 Tmax Application Development Guide

Page 247: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

exit(1);

}

printf("rtn msg = %s\n", rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

서버 프로그램다음은 데이터베이스에 UPDATE하는 서버 프로그램 예제이다.

<update.pc>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/sdl.h>

#include "../sdl/demo.s"

#define OKMSG "YOU COMPLETE THE TRANSACTION"

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

char ssn[15];

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

UPDATE(TPSVCINFO *msg)

{

struct input *rcvbuf;

int ret;

long acnt_id, rcvlen;

char *send;

rcvbuf = (struct input *)(msg->data);

send = (char *)tpalloc("STRING", NULL, 0);

제11장 예제 229

Page 248: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (send == NULL) {

fprintf(stderr, "tpalloc fail errno = %s\n", strerror(tperrno));

tpreturn(TPFAIL, 0, (char *)NULL, 0, 0);

}

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

strcpy(phone, rcvbuf->phone);

strcpy(address, rcvbuf->address);

strcpy(ssn, "1234567");

EXEC SQL UPDATE ACCOUNT

SET BRANCH_ID = :branch_id,

PHONE = :phone,

ADDRESS = :address,

SSN = :ssn

WHERE ACCOUNT_ID = :account_id;

if (sqlca.sqlcode != 0 && sqlca.sqlcode != 1403 ) {

fprintf(stderr, "update failed sqlcode = %d\n", sqlca.sqlcode);

tpreturn(TPFAIL, -1, (char *)NULL, 0, 0);

}

rcvbuf->account_id++;

ret = tpcall("INSERT", (char *)rcvbuf, 0, (char **)&send, (long *)&rcvlen,

TPNOFLAGS);

if (ret < 0) {

fprintf(stderr, "tpcall fail tperrno = %d\n", tperrno);

tpreturn(TPFAIL, -1, (char *)NULL, 0, 0);

}

strcpy(send, OKMSG);

tpreturn(TPSUCCESS, 1, (char *)send, strlen(send), TPNOFLAGS);

}

다음은 데이터베이스에 INSERT하는 서버 프로그램 예제이다.

<insert.pc>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/sdl.h>

#include "../sdl/demo.s"

#define OKMSG "YOU COMPLETE THE TRANSACTION"

230 Tmax Application Development Guide

Page 249: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

char ssn[15];

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

INSERT(msg)

TPSVCINFO *msg;

{

struct input *rcvbuf;

int ret;

long acnt_id;

char *send;

rcvbuf = (struct input *)(msg->data);

send = (char *)tpalloc("STRING", NULL, 0);

if (send == NULL) {

fprintf(stderr, "tpalloc fail errno = %s\n", tpstrerror(tperrno));

tpreturn(TPFAIL, 0, (char *)NULL, 0, TPNOFLAGS);

}

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

strcpy(phone, rcvbuf->phone);

strcpy(address, rcvbuf->address);

strcpy(ssn, "1234567");

/* Declare && Open Cursor for Fetch */

EXEC SQL INSERT INTO ACCOUNT (

ACCOUNT_ID,

BRANCH_ID,

SSN,

PHONE,

ADDRESS )

VALUES (

:account_id, :branch_id, :ssn, :phone, :address);

if (sqlca.sqlcode != 0 && sqlca.sqlcode != 1403 )

{

printf("insert failed sqlcode = %d\n", sqlca.sqlcode);

tpreturn(TPFAIL, -1, (char *)NULL, 0, TPNOFLAGS);

}

제11장 예제 231

Page 250: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

strcpy(send, OKMSG);

tpreturn(TPSUCCESS, 1, (char *)send, strlen(send), TPNOFLAGS);

}

테이블 생성 스크립트

다음은 Oracle 테이블 생성 스크립트 예제이다.

<mktable.sql>

sqlplus scott/tiger << EOF

drop table ACCOUNT;

create table ACCOUNT (

ACCOUNT_ID integer,

BRANCH_ID integer not null,

SSN char(13) not null,

BALANCE number,

ACCT_TYPE char(1),

LAST_NAME char(21),

FIRST_NAME char(21),

MID_INIT char(1),

PHONE char(15),

ADDRESS char(61),

CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)

);

quit

EOF

Tmax 환경파일

다음은 Tmax 환경파일 사용예제이다.

<sample.m>

*DOMAIN

res SHMKEY=88000, MINCLH=1, MAXCLH=5, TPORTNO=8880, BLOCKTIME=60

*NODE

tmax1 TMAXDIR = "/user/ tmax ",

232 Tmax Application Development Guide

Page 251: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

APPDIR = "/user/ tmax /appbin",

PATHDIR = "/user/ tmax /path",

TLOGDIR = "/user/ tmax /log/tlog",

ULOGDIR="/user/ tmax /log/ulog",

SLOGDIR="/user/ tmax /log/slog"

tmax2 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 = tmax1, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",

TMSNAME = svg1_tms

svg2 NODENAME = tmax2, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",

TMSNAME = svg2_tms

*SERVER

update SVGNAME=svg1

insert SVGNAME=svg2

*SERVICE

UPDATE SVRNAME=update

INSERT SVRNAME=insert

11.3. 데이터베이스 적용 프로그램대표적인 데이터베이스인 Oracle과 Informix를 사용하는 몇 가지 예제를 제시한다.

11.3.1. Oracle Insert 프로그램

클라이언트는 사용자의 입력을 받아 구조체 버퍼에 넣어 서비스를 호출하며 서버는 이를 받아 해당 테이

블에 추가한다. 클라이언트는 트랜잭션을 지정하여 에러가 발생하였을 경우 rollback할 수 있도록 한다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.oins_cli.c

제11장 예제 233

Page 252: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구성

서비스 프로그램 Oracle 소스이다.oinssvc.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

Tmax 환경설정 파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

데이터베이스 테이블 내용을 출력하는 SQL 스크립트이다.sel.sql

● 프로그램 특징

설명구분

- Tmax 접속 : 기본 접속클라이언트 부분

- 사용 버퍼 : 구조체 버퍼(STRUCT) 사용

- 통신 유형 : tpcall()에 의한 동기 통신

- 트랜잭션 처리: 클라이언트에서 트랜잭션 범위 지정

- 서비스 : ORAINS서버 부분

- 데이터베이스 연결 : Oracle 데이터베이스

구조체 버퍼

다음은 구조체 버퍼 예제이다.

<demo.s>

struct ktran {

int no;

char name[20];

};

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<oins_cli.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

main(int argc, char *argv[])

234 Tmax Application Development Guide

Page 253: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

{

struct ktran *sndbuf, *rcvbuf;

long sndlen, rcvlen;

int cd;

if (argc != 3) {

printf(“Usage: client no name\n”);

exit(1);

}

printf(“tpstart-start \n”);

if(tpstart ((TPSTART_T *) NULL) == -1) {

printf(“Tpstart failed\n”);

exit(1);

}

printf(“tpstart-ok \n”);

if((sndbuf=(struct ktran *) tpalloc("STRUCT","ktran",0))==NULL) {

printf(“tpalloc failed:sndbuf, tperrno=%d\n”, tperrno);

tpend();

exit(1) ;

}

if((rcvbuf = (struct ktran *) tpalloc("STRUCT", "ktran", 0))== NULL) {

printf(“tpalloc failed:rcvbuf, tperrno=%d\n”, tperrno);

tpfree((char *)sndbuf);

tpend();

exit(1);

}

sndbuf->no = atoi(argv[1]);

strcpy(sndbuf->name, argv[2]);

printf(“tpcall-start \n”);

tx_begin();

if(tpcall("ORAINS",(char *)sndbuf,0,(char **)&rcvbuf,&rcvlen,TPNOFLAGS)==-1){

printf(“tpcall failed:ORA service, tperrno=%d”, tperrno);

printf(“sql code=%d\n”, tpurcode);

tx_rollback();

tpfree ((char *)sndbuf);

tpfree ((char *)rcvbuf);

tpend();

exit(1);

}

제11장 예제 235

Page 254: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

printf(“tpcall-success \n”);

tx_commit();

tpfree ((char *)sndbuf);

tpfree ((char *)rcvbuf);

tpend();

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<oinssvc.pc>

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

EXEC SQL begin declare section;

char name[20];

int no;

EXEC SQL end declare section;

EXEC SQL include sqlca;

ORAINS(TPSVCINFO *msg)

{

struct ktran *stdata;

stdata = (struct ktran *)msg->data;

strcpy(name, stdata->name);

no = stdata->no;

printf(“Ora service started\n”);

/* 데이터베이스에 삽입 */

EXEC SQL insert into testdb1(no, name) values(:no, :name);

if (sqlca.sqlcode != 0){

printf(“oracle sqlerror=%s”,sqlca.sqlerrm.sqlerrmc);

tpreturn (TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

236 Tmax Application Development Guide

Page 255: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpreturn (TPSUCCESS, sqlca.sqlcode, stdata, 0, TPNOFLAGS);

}

테이블 생성 스크립트

다음은 Oracle 테이블 생성 스크립트 예제이다.

<mktable.sql>

sqlplus scott/tiger << EOF

create table testdb1 (

no number(7),

name char(30)

) ;

EOF

테이블 및 데이터 출력 스크립트

다음은 Oracle 테이블 및 데이터 출력 스크립트 예제이다.

<sel.sql>

sqlpus scott/tiger << EOF

desc testdb1;

select * from testdb1;

select count (*) from testdb1;

EOF

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR = /home/tmax,

APPDIR = /home/tmax/appbin,

PATHDIR = /home/tmax/path

*SVRGROUP

svg1 NODENAME = tmax,

DBNAME = ORACLE,

제11장 예제 237

Page 256: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

OPENINFO = “Oracle_XA+Acc=P/scott/tiger+SesTm=60”,

TMSNAME = svg1_tms

*SERVER

oinssvc SVGNAME = svg1, MIN = 1, MAX = 5

*SERVICE

ORAINS SVRNAME = oinssvc

다음은 환경 설정에 추가된 항목에 대한 설명이다.

설명항목

사용하는 데이터베이스를 정의한다.DBNAME

Oracle 데이터베이스 연결 정보를 설정한다.OPENINFO

- tpsvrinfo()에서 호출한다.

- Oracle 데이터베이스인 경우 CLOSEINFO는 지정하지 않아도 된다.

- 트랜잭션 처리를 주재하는 프로세스 이름을 지정한다.TMSNAME

- OPENINFO 지정으로 인한 자동 트랜잭션을 처리한다.

- svg1에 속한 해당 서비스를 자동 트랜잭션 상태에서 처리한다.

11.3.2. Oracle Select 프로그램

클라이언트는 사용자의 입력을 받아 구조체 버퍼에 넣어 서비스를 호출하며 서버는 이에 해당하는 모든

데이터를 받아 구조체 배열을 사용하여 결과를 반환한다. 클라이언트는 트랜잭션을 지정하여 에러가 발

생하였을 경우 rollback할 수 있도록 한다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.oins_cli.c

클라이언트 사용 함수 모듈이다.cdata.c

서비스 프로그램 Oracle 소스이다.oselsvc.pc

Tmax에서 제공되는 Makefile 로 수정해야 한다.Makefile

Tmax 시스템 환경 파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

데이터베이스 테이블 내용을 출력하는 SQL 스크립트이다.sel.sql

● 프로그램 특징

238 Tmax Application Development Guide

Page 257: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구분

- Tmax 접속 : 기본 접속클라이언트 부분

- 사용 버퍼 : 구조체 버퍼(STRUCT) 사용

- 통신 유형 : tpcall()에 의한 동기 통신

- 트랜잭션 처리: 클라이언트에서 트랜잭션 범위 지정

- 서비스 : ORASEL서버 부분

- 데이터베이스 연결: Oracle 데이터베이스

- 필요에 의해 버퍼 크기를 재조정

구조체 버퍼

다음은 사용 구조체 버퍼 예제이다.

<demo.s>

struct stru_his{

long ACCOUNT_ID ;

long TELLER_ID ;

long BRANCH_ID ;

long AMOUNT ;

} ;

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<oins_cli.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

#include “../sdl/demo.s”

#define NARRAY 10

#define NOTFOUND 1403

main(int argc,char *argv[])

{

struct stru_his *transf;

int i, j;

제11장 예제 239

Page 258: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

long urcode, nrecv, narray = NARRAY;

long account_id, teller_id, branch_id, amount;

if (argc != 2) {

fprintf(stderr,“Usage:$%s ACOUNT_ID !\n”, argv[0]);

exit(0);

}

if (tpstart((TPSTART_T *) NULL) == -1) { /* Tmax에 접속 */

fprintf(stderr,“TPSTART_T(tpinfo) failed -> %s!\n”,

tpstrerror(tperrno)) ;

exit(1) ;

}

/* c structure 구조로 Buffer 생성 */

transf = (struct stru_his *) tpalloc(“STRUCT”, “stru_his”,0);

if (transf == (struct stru_his *)NULL) {

fprintf(stderr,“Tpalloc failed->%s!\n”,

tpstrerror(tperrno)) ;

tpend();

exit(1);

}

memset(transf, 0x00, sizeof(struct stru_his));

account_id = atoi(argv[1]);

transf->ACCOUNT_ID = account_id;

/* 트랜잭션 타임아웃 설정 */

tx_set_transaction_timeout(30);

/* global 트랜잭션 시작 */

if (tx_begin() < 0) {

fprintf(stderr, “tx_begin() failed ->%s!\n”,

tpstrerror(tperrno));

tpfree((char*)transf);

tpend();

exit(0) ;

}

if (tpcall(“ORASEL”,(char *)transf, 0, (char **)&transf, &nrecv,

TPNOFLAGS)== -1){

/* 동기 통신으로 “ORASEL” 서비스 요청 */

fprintf(stderr,“Tpcall(SELECT...)error->%s ! ”,

tpstrerror(tperrno)) ;

tpfree((char *)transf);

/* 실패시 트랜잭션 취소 */

tx_rollback();

240 Tmax Application Development Guide

Page 259: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

exit(0) ;

}

/* 성공시 트랜잭션 커밋 */

if (tx_commit() == -1) {

fprintf(stderr, “tx_commit() failed ->%s!\n”,

tpstrerror(tperrno)) ;

tpfree((char *)transf);

tpend();

exit(0) ;

}

/* 받아온 데이터는 구조체의 배열이다. */

for (j =0 ; j < tpurcode ; j++) {

/* Oracle에서 셀렉트한 데이터 결과를 프린트 */

if (j == 0)

printf(“%-12s%-10s%-10s%-10s\n”,

“ACCOUNT_ID”,“TELLER_ID”, “BRANCH_ID”, “AMOUNT”);

account_id=transf[j].ACCOUNT_ID;

teller_id=transf[j].TELLER_ID;

branch_id=(*(transf+j)).BRANCH_ID;

amount=transf[j].AMOUNT;

printf(“%-12d %-10d %-10d %-10d\n”, account_id, teller_id,branch_id, amount);

}

/* 셀렉트한 data가 없거나 끝이라면 */

if (urcode == NOTFOUND) {

printf(“No records selected!\n”);

tpfree((char *)transf);

tpend();

return 0;

}

tpfree((char *)transf);

tpend();

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<oselsvc.pc>

#include <stdio.h>

#include <usrinc/atmi.h>

#include “../sdl/demo.s”

#define NARRAY 10

제11장 예제 241

Page 260: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#define TOOMANY 2112

#define NOTFOUND 1403

EXEC SQL include sqlca.h;

EXEC SQL begin declare section;

long key, rowno= NARRAY;

long account_id[NARRAY],teller_id[NARRAY], branch_id[NARRAY],

amount[NARRAY] ;

EXEC SQL end declare section;

ORASEL(TPSVCINFO *msg)

{

struct stru_his *transf;

int i , lastno;

transf=(struct stru_his *) msg->data;

/* msg Buffer의 내용을 프로그램 변수에 전달. */

key = transf->ACCOUNT_ID;

/* transf Buffer의 크기를 재조정 */

if((transf=(struct stru_his *) tprealloc((char*)transf,

sizeof(struct stru_his) * NARRAY ))==(struct stru_his*)NULL){

fprintf(stderr, “tprealloc error ->%s\n”,

tpstrerror(tperrno));

tpreturn(TPFAIL, tperrno, NULL, 0, TPNOFLAGS);

}

EXEC SQL select account_id, teller_id, branch_id, amount

into :account_id, :teller_id, :branch_id, :amount from sel_his

where account_id > :key

/* account_id가 client에서 보낸 key값 보다 큰 것을 */

order by account_id; /* global 변수에 넣어줌 */

/* sql error 체크 (셀렉트된 것이 없거나 너무 많은 것 제외.) */

if (sqlca.sqlcode!=0 && sqlca.sqlcode!=NOTFOUND && sqlca.sqlcode!=TOOMANY) {

fprintf(stderr,“SQL ERROR ->NO(%d):%s\n”, sqlca.sqlcode,

sqlca.sqlerrm.sqlerrmc) ;

tpreturn(TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

/* access한 개수를 lastno에 넣어줌 */

lastno = sqlca.sqlerrd[2];

/* 셀렉트된 data가 너무 많음 */

if (sqlca.sqlcode == TOOMANY)

lastno =rowno;

/* No records */

242 Tmax Application Development Guide

Page 261: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (lastno == 0)

transf->ACCOUNT_ID = 0;

/* Oracle에서 셀렉트한 데이터를 전송할 Buffer에 넣어줌 */

for ( i = 0 ; i < lastno; i++) {

transf[i].ACCOUNT_ID = account_id[i];

transf[i].TELLER_ID = teller_id[i];

transf[i].BRANCH_ID = branch_id[i];

transf[i].AMOUNT = amount[i];

}

tpreturn(TPSUCCESS, lastno, transf, i * sizeof(struct stru_his),

TPNOFLAGS );

}

테이블 생성 스크립트

다음은 Oracle 테이블 작성 스크립트 예제이다.

<mktable.sql>

sqlplus scott/tiger << EOF

create table sel_his(

account_id number(6),

teller_id number(6),

branch_id number(6),

amount number(6)

);

create unique index idx_tdb1 on sel_his(account_id);

EOF

테이블 및 데이터 출력 스크립트

다음은 Oracle 테이블 및 데이터 출력 스크립트 예제이다.

<sel.sql>

sqlplus scott/tiger << EOF

desc sel_his;

select * from sel_his;

EOF

Tmax 환경파일

다음은 Tmax 환경파일에 대한 예제이다.

제11장 예제 243

Page 262: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR =“/home/tmax”,

APPDIR =“/home/tmax/appbin”,

PATHDIR =“/home/tmax/path”

*SVRGROUP

svg1 NODENAME = tmax,

DBNAME = ORACLE,

OPENINFO = “Oracle_XA+Acc=P/scott/tiger+SesTm=600”,

TMSNAME = svg1_tms

*SERVER

oselsvc SVGNAME = svg1, MIN = 1, MAX = 5

*SERVICE

ORASEL SVRNAME = oselsvc

다음은 환경 설정에 추가된 항목에 대한 설명이다.

요구 사항항목

사용 데이터베이스명을 설정한다.DBNAME

- Oracle 데이터베이스 연결 정보를 설정한다.OPENINFO

- Oracle에서는 CLOSEINFO는 설정하지 않아도 된다.

트랜잭션 처리를 관리하는 프로세스 이름을 지정한다.TMSNAME

해당 서비스를 처리할 때 자동으로 트랜잭션 상태로 처리한다.AUTOTRAN

OPENINFO 절을 사용할 때 옵션으로 DbgFl과 LogDir을 사용할 수 있다.

LogDir을 사용하지 않으면 $ORACLE_HOME/rdbms/log 또는 현재 디렉터리에 <xa_NULL날짜.trc> 파일

이 생성되고 LogDir을 지정하면 지정된 곳에 XA에 관련된 로그를 남길수 있다. DbgFl은 몇번째 단계의 디

버그 플래그를 설정할지를 결정해준다. 기본적인 단계인 0x01 또는 OCI 단계인 0x04 등을 사용하면 된다.

OPENINFO=“Oracle_XA+Acc=P/계정/암호 +SesTm=60+LogDir=/tmp+DbgFl=0x01”

주의

개발할 때에는 Debug 모드를 해제하고 사용해야만 나중에 디스크가 FULL되는 상황을 피할 수 있다.

244 Tmax Application Development Guide

Page 263: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

11.3.3. Informix Insert 프로그램

클라이언트는 사용자의 입력을 받아 구조체 버퍼에 넣어 서비스를 호출하며 서버는 이를 받아 해당 테이

블에 추가해준다. 클라이언트는 트랜잭션을 지정하여 에러가 발생하였을 경우 rollback할 수 있도록 한다.

Informix 응용 프로그램 컴파일 전 다음 사항을 먼저 확인한다.

1. UNIX 환경 확인( .profile .login .cshrc )

다음 값을 설정한다.

INFORMIXDIR=/home/informix

INFORMIXSERVER=tmax

ONCONFIG=onconfig

PATH=$INFORMIXDIR/bin: …

LD_LIBRARY_PATH=/home/informix/lib:/home/informix/lib/esql:

2. Makefile 확인

다음 오퍼레이션과 설정을 확인한다.

# Server esql makefile

TARGET = <target filename>

APOBJS = $(TARGET).o

SDLFILE = info.s

LIBS = -lsvr -linfs

# solaris의 경우 –lnsl –lsocket 추가

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

SDLOBJ = ${SDLFILE:.s=_sdl.o}

SDLC = ${SDLFILE:.s=_sdl.c}

SVCTOBJ = $(TARGET)_svctab.o

CFLAGS =-O -I$(INFORMIXDIR)/incl/esql -I$(TMAXDIR)

# Solaris 32bit, Compaq, Linux: CFLAGS = -O -I$(INFORMIXDIR)/incl/esql

–I$(TMAXDIR)

# Solaris 64bit: CFLAGS = -xarch=v9 -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

# HP 32bit: CFLAGS = -Ae -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

# HP 64bit: CFLAGS = -Ae +DA2.0W +DD64 +DS2.0 -O -I$(INFORMIXDIR)/incl/esql

–I$(TMAXDIR)

# IBM 32bit: CFLAGS = -q32 –brtl -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

# IBM 64bit: CFLAGS = -q64 –brtl -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

INFLIBD = $(INFORMIXDIR)/lib/esql

INFLIBDD = $(INFORMIXDIR)/lib

제11장 예제 245

Page 264: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

INFLIBS = -lifsql -lifasf -lifgen -lifos -lifgls -lm -ldl -lcrypt

$(INFORMIXDIR)/lib/esql/

checkapi.o -lifglx -lifxa

APPDIR = $(TMAXDIR)/appbin

SVCTDIR = $(TMAXDIR)/svct

TMAXLIBDIR = $(TMAXDIR)/lib

#

.SUFFIXES : .ec .s .c .o

.ec.c :

esql -e $*.ec

#

# server compile

#

all: $(TARGET)

$(TARGET):$(OBJS)

$(CC) $(CFLAGS) -L$(TMAXLIBDIR) -L$(INFLIBD) -L$(INFLIBDD) -o $(TARGET)

$(OBJS) $(LIBS) $(INFLIBS)

mv $(TARGET) $(APPDIR)/.

rm -f $(OBJS)

$(APOBJS): $(TARGET).ec

esql -e -I$(TMAXDIR)/usrinc $(TARGET).ec

$(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) $(TARGET).lis

<TMS Makefile>

#

TARGET = info_tms

246 Tmax Application Development Guide

Page 265: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

INFOLIBDIR = ${INFORMIXDIR}/lib

INFOELIBDIR = ${INFORMIXDIR}/esql

INFOLIBD = ${INFORMIXDIR}/lib/esql

INFOLIBS = -lifsql -lifasf -lifgen -lifos -lifgls -lm -ldl -lcrypt

/opt/informix/lib/esql/checkapi.o

-lifglx -lifxa

# solaris는 라이브러리에 –lnsl –lsocket –laio –lelf 추가

CFLAGS =-O -I$(INFORMIXDIR)/incl/esql -I$(TMAXDIR)

# Solaris 32bit, Compaq, Linux: CFLAGS = -O -I$(INFORMIXDIR)/incl/esql

–I$(TMAXDIR)

# Solaris 64bit: CFLAGS = -xarch=v9 -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

# HP 32bit: CFLAGS = -Ae -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR)

# HP 64bit: CFLAGS = -Ae +DA2.0W +DD64 +DS2.0 -O -I$(INFORMIXDIR)/incl/esql

–I$(TMAXDIR)

# IBM 32bit: CFLAGS = -q32 –brtl -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR

# IBM 64bit: CFLAGS = -q64 –brtl -O -I$(INFORMIXDIR)/incl/esql –I$(TMAXDIR

TMAXLIBDIR = $(TMAXDIR)/lib

TMAXLIBS = -ltms -linfs

# CC = /opt/SUNWspro/bin/cc : solaris only

$(TARGET): $(APOBJ)

$(CC) $(CFLAGS) -o $(TARGET) -L$(TMAXLIBDIR) -L$(INFOLIBD)

-L$(INFOLIBDIR) -L

$(INFOELIBDIR) $(INFOLIBS) $(TMAXLIBS)

mv $(TARGET) $(TMAXDIR)/appbin

#

clean:

-rm -f *.o core $(TARGET)

Informix Insert 프로그램의 내용은 다음과 같다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

서버 프로그램이다.tdbsvr.ec

Tmax에서 제공되는 Makefile을 수정한다.Makefile

Tmax 시스템 환경파일이다.sample.m

데이터베이스 생성 SQL 스크립트이다. XA 모드는 데이터베이스가 로깅 모

드에서 생성될 때 지원한다.

mkdb.sql

제11장 예제 247

Page 266: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구성

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

데이터베이스 테이블에 내용을 출력하는 SQL 스크립트이다.sel.sql

SDLFILE이다.info.s

● 프로그램 특징

설명구분

- Tmax 접속 : 기본 접속클라이언트 부분

- 사용 버퍼 : 구조체 버퍼(STRUCT) 사용

- 통신 유형 : tpcall()에 의한 동기 통신

- 트랜잭션 처리: 클라이언트에서 트랜잭션 범위 지정

- 서비스 : INSERT서버 부분

- 데이터베이스 연결: Informix 데이터베이스

구조체 버퍼

다음은 사용 구조체 버퍼 예제이다.

<demo.s>

struct info {

char seq[8];

char data01[128];

char data02[128];

char data03[128];

};

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<client.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

#include “info.s”

248 Tmax Application Development Guide

Page 267: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

main(int argc, char **argv)

{

struct info *transf;

char data[256];

long nrecv;

/* Tmax에 연결. */

if ((tpstart((TPSTART_T *)NULL) == -1) {

fprintf(stderr, “tpstart(TPINFO...) failed ->%s!\n”,

tpstrerror(tperrno)) ;

exit(1) ;

}

/* 응용프로그램에서 사용할 Buffer 메모리 할당. */

if ((transf=(struct info *)tpalloc ("STRUCT","info",0))==(struct info *)NULL){

fprintf(stderr, “tpalloc(struct info, ...) failed ->%s!\n”,

tpstrerror(tperrno)) ;

tpend();

exit(1) ;

}

/* 전송할 데이터 필드를 채움. */

strcpy(transf->seq, “000001”);

strcpy(transf->data01, “Hello”);

strcpy(transf->data02, “World”);

strcpy(transf->data03, “1234”);

/* 트랜잭션 timeout 설정 * /

tx_set_transaction_timeout (30);

/* 트랜잭션 시작을 알림. */

if (tx_begin() < 0) {

fprintf(stderr, “tx_begin() failed ->%s!\n”,

tpstrerror(tperrno)) ;

tpfree ((char *)transf);

tpend( ); exit(0);

}

/* 서비스 호출 */

if (tpcall ("INSERT",(char*) transf,0,(char **)&transf,&nrecv,TPNOFLAGS)==-1)

{

fprintf(stderr,"tpcall(struct info, ...)

failed ->%s!\n",tpstrerror(tperrno)) ;

tx_rollback ();

tpfree ((char *)transf),

tpend();

exit(0);

제11장 예제 249

Page 268: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

/* 트랜잭션 성공. */

if (tx_commit () < 0) {

fprintf(stderr, “tx_commit() failed ->%s!\n”, tpstrerror(tperrno)) ;

tpfree ((char *)transf);

tpend( );

exit(0);

}

tpfree ((char *)transf );

/* Tmax 연결을 끊음. */

tpend( ) ;

}

서버 프로그램

다음은 서버프로그램 예제이다.

< tdbsvr.ec>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include “info.s”

EXEC SQL include sqlca.h;

/* 서비스 명*/

INSERT(TPSVCINFO *msg)

{

/* 프로그램상의 Buffer형식 선언. */

struct info *INFO;

/* SQL문 내의 Buffer 형식 선언. */

EXEC SQL begin declare section;

varchar seq[8],buf01[128],buf02[128],buf03[128];

EXEC SQL end declare section;

/* 메시지 Buffer로 부터 구조체형으로 데이터를 전달 받는다. */

INFO = (struct info *)msg -> data;

/* 구조체 형식으로 전달받은 데이터를 데이터베이스 Buffer로 복사. */

strcpy(seq, INFO->seq);

strcpy(buf01, INFO->data01);

strcpy(buf02, INFO->data02);

250 Tmax Application Development Guide

Page 269: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

strcpy(buf03, INFO->data03);

/* SQL문의 인서트 수행 */

EXEC SQL insert into testdb1 (seq,data01,data02,data03)

values(:seq, :buf01, :buf02, :buf03);

/* 에러가 발생한다면 */

if ( sqlca.sqlcode ! = 0) {

/* Insert 실패를 알린다. */

printf(“SQL error => %d !” ,sqlca.sqlcode);

tpreturn (TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

/* Insert가 성공적으로 끝났을 때 */

tpreturn (TPSUCCESS, 0, NULL, 0, TPNOFLAGS);

}

테이블 생성 스크립트

다음은 Informix 테이블 생성 스크립트 예제이다.

<mktable.sql>

dbaccess << EOF

create database stores7 with buffered log;

grant connect to public;

database stores7;

drop table testdb1;

create table testdb1 (

seq VARCHAR(8) ,

data01 VARCHAR(120) ,

data02 VARCHAR(120) ,

data03 VARCHAR(120)

) lock mode row;

create unique index idx_tdb1 on testdb1(seq);

EOF

테이블 및 데이터 출력 스크립트

다음은 Informix 테이블 및 데이터 출력 스크립트예제이다.

<sel.sql>

제11장 예제 251

Page 270: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

dbaccess << EOF

database stores7;

select * from testdb1;

EOF

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR =”/home/tmax”, A

APPDIR =”/home/tmax/appbin”,

PATHDIR =”/home/tmax/path”

*SVRGROUP

svg1 NODENAME = tmax,

DBNAME = INFORMIX,

OPENINFO = “stores7”,

CLOSEINFO = “”,

TMSNAME = info_tms

*SERVER

tdbsvr SVGNAME = svg1, MIN = 1, MAX = 5

*SERVICE

INSERT SVRNAME = tdbsvr

다음은 환경 설정에 추가된 항목에 대한 설명이다.

요구 사항항목

사용 데이터베이스명을 설정한다.DBNAME

Informix 데이터베이스 연결 및 해제를 위한 정보를 tpsvrinfo(),

tpsvrdone()에서 호출한다.

OPENINFO, CLOSEINFO

- 트랜잭션 처리를 주재하는 프로세스 이름을 지정한다.TMSNAME

- OPENINFO 지정으로 인한 자동 트랜잭션 처리 svg1에 속한 해당

서비스를 자동 트랜잭션 상태에서 처리한다.

252 Tmax Application Development Guide

Page 271: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

11.3.4. Informix Select 프로그램

클라이언트는 사용자의 입력을 받아 구조체 버퍼에 넣어 서비스를 호출하며 서버 측은 이에 해당하는 모

든 데이터를 받아 구조체 배열을 사용하여 결과를 반환한다. 클라이언트는 트랜잭션을 지정하여 에러가

발생하였을 경우 rollback할 수 있도록 한다.

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

client.c에서 사용된 함수 모듈이다.cdate.c

서비스 프로그램 Informix 소스이다.sel_acct.ec

Tmax에서 제공되는 Makefile을 수정한다.Makefile

Tmax 환경파일이다.sample.m

데이터베이스를 생성하는 SQL 스크립트이다.mkdb.sql

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktables.sql

데이터베이스 테이블에 내용을 출력하는 SQL 스크립트이다.sel.sql

SDLFILE이다.acct.s

● 프로그램 특징

설명구분

- Tmax 접속 : 기본 접속클라이언트 부분

- 사용 버퍼 : 구조체 버퍼(STRUCT) 사용

- 통신 유형 : tpcall()에 의한 동기 통신

- 트랜잭션 처리: 클라이언트에서 트랜잭션 범위 지정

- 서비스 : SEL_ACCT서버 부분

- 데이터베이스 연결: Informix 데이터베이스

- 필요에 의해 버퍼 크기를 재조정

구조체 버퍼

다음은 사용 구조체 버퍼 예제이다.

<demo.s>

제11장 예제 253

Page 272: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

struct stru_acct {

int ACCOUNT_ID;

char PHONE[20];

char ADDRESS[80];

} ;

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<client.c>

#include <stdio.h>

#include <time.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

#include “acct.s”

#define NOTFOUND 1403

void htime(char *, int *);

main(int argc, char *argv[ ])

{

struct stru_acct *transf;

float tps;

int i, j, loop, cnt_data = 0, sec1, sec2;

long urcode, nrecv, narray;

char ts[30], te[30], phone[20], address[80];

int account_id, key;

if(argc != 2) {

fprintf(stderr,“Usage:$%sLOOP (NARRAY = 30) !\n”, argv[0]);

exit(0) ;

}

/*user가 원하는 수행 횟수만큼 loop를 돈다.*/

loop = atoi(argv[1]);

/* Tmax에 접속 */

if (tpstart((TPSTART_T *)NULL) == -1) {

fprintf(stderr, “tpstart(tpinfo) failed ->%s!\n”,

tpstrerror(tperrno));

exit(1) ;

}

/* sec1 = 시작시간 */

254 Tmax Application Development Guide

Page 273: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

htime(ts,&sec1); key=0;

/* message buffer 할당 */

for( i = 0; i < loop; i++) {

if ((transf=(struct stru_acct *)tpalloc("STRUCT","stru_acct",0))

==(struct stru_acct *)NULL) {

fprintf(stderr,“Tpalloc(STRUCT.. )failed->%s!\n” ,

tpstrerror(tperrno)) ;

tpend(); exit(1);

}

transf -> ACCOUNT_ID = key;

/* time-out value= 30 */

tx_set_transaction_timeout(30) ;

if (tx_begin() < 0) { /* transaction 시작 */

fprintf(stderr, “tx_begin() failed ->%s!\n”, tpstrerror(tperrno)) ;

tpfree((char*)transf);

tpend();

exit(0);

}

/* select service 호출 */

if (tpcall(“SEL_ACCT”, (char *)transf, 0, (char **)&transf, &nrecv,

TPNOFLAGS)== -1) {

/* service error : message buffer free &transaction 취소 & 접속 끊음 */

fprintf(stderr,“Tpcall(SELECT...)error->%s! ” ,

tpstrerror(tperrno)) ;

tpfree ((char *)transf);

tx_rollback ( ) ;

tpend( ) ;

exit ( 1 ) ;

}

urcode = tpurcode;

/*성공적인 서비스 완결 : transaction결과로 실제 resource변화시킴*/

if (tx_commit() < 0 ) {

fprintf(stderr, “tx_commit() failed ->%s!\n”, tpstrerror(tperrno)) ;

tpfree((char *)transf);

tpend();

exit(0);

}

/*data가 선택된 경우*/

if ( urcode != NOTFOUND) {

narray =urcode;

/* select한 데이터의 마지막 Record */

제11장 예제 255

Page 274: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

key=transf[narray-1].ACCOUNT_ID;

/* selsct한 개수 만큼 결과를 user에게 출력 */

for ( j = 0 ; j < narray ; j++ ) {

if ( j == 0)

printf(“%-10s%-14s%s\n”, “ACCOUNT_ID”, “PHONE”,“ADDRESS”) ;

account_id = transf[j].ACCOUNT_ID;

strcpy(phone, transf[j].PHONE);

strcpy(address, transf[j].ADDRESS);

printf(“%-10d %-14s %s\n”, account_id, phone, address);

}/* for2 end */

/* 전체 결과 개수 증가 */

cnt_data += j;

/* message buffer free */

tpfree ((char *)transf);

if(urcode == NOTFOUND) {

printf(“No records selected!\n”);

break ;

}

}/* for1 end */

/* message buffer free */

tpfree ((char *)transf);

/* Tmax 연결을 끊음. */

tpend ();

/* sec2 = 끝 시간 */

htime(te,&sec2);

/* data 하나당 처리 시간 계산. */

printf(“TOT.COUNT = %d\n”, cnt_data);

printf(“Start time = %s\n”, ts);

printf(“End time = %s\n”, te);

if ((sec2-sec1) ! = 0)

tps = (float) cnt_data / (sec2 - sec1);

else

tps = cnt_data;

printf(“Interval = %d secs ==> %10.2f T/S\n”, sec2-sec1,tps);

}

htime(char *cdate, int *sec)

{

long time(), timef, pt;

char ct[20], *ap;

struct tm *localtime(), *tmp;

256 Tmax Application Development Guide

Page 275: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

pt = time(&timef);

*sec = pt;

tmp = localtime(&timef);

ap = asctime(tmp);

sscanf(ap, “%*s%*s%*s%s”,ct);

sprintf( cdate, “%02d. %02d. %02d %s”, tmp->tm_year, ++tmp->tm_mon,

tmp->tm_mday,ct);

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<sel_acct.pc>

#include <stdio.h>

#include <usrinc/atmi.h>

#include <usrinc/tx.h>

#include “acct.s”

#define NFETCH 5

#define NOTFOUND 100

EXEC SQL include sqlca.h;

EXEC SQL begin declare section;

long account_id, key;

varchar phone[20], address[80];

EXEC SQL end declare section;

SEL_ACCT(TPSVCINFO *msg)

{

int i , j , nfetch;

int return_code;

struct stru_acct *ACCT_V;

/*클라이언트 데이터를 받는다. */

ACCT_V = (struct stru_acct *) msg->data;

/* select원하는 account id 값을 key에 옮김. */

key = ACCT_V->ACCOUNT_ID;

/* 클라이언트 buffer 사이즈 재할당*/

if ((ACCT_V = (struct stru_acct *)tprealloc((char *)ACCT_V,

sizeof(struct stru_acct)*NFETCH )) == (struct stru_acct *)NULL) {

fprintf(stderr, “tprealloc error =%s\n”, tpstrerror(tperrno));

tpreturn (TPFAIL, tperrno, NULL, 0, TPNOFLAGS);

제11장 예제 257

Page 276: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

/*buffer 초기화*/

ACCT_V->ACCOUNT_ID = 0;

strcpy(ACCT_V->PHONE,“ ” ) ;

strcpy(ACCT_V->ADDRESS,“ ” ) ;

/* ACCOUNT table로부터 phone, address 필드를 뽑음 */

EXEC SQL declare CUR_1 cursor for

select account_id,phone,address

into :account_id, :pfone, :address

from ACCOUNT

where account_id > :key;/* 필드키보다 account id가 클 때 */

/* cursor open */

EXEC SQL open CUR_1;

/* cursor open error */

if (sqlca.sqlcode ! = 0) {

printf(“open cursor error !\n”);

tpreturn(TPFAIL, sqlca.sqlcode, NULL, 0, TPNOFLAGS);

}

nfetch=0 ;

return_code = NOTFOUND;

/* cursor open success */

while (sqlca.sqlcode == 0) {

/* cursor서부터 data 하나씩 fetch */

EXEC SQL fetch CUR_1;

/* fetch error */

if (sqlca.sqlcode ! = 0) {

if (sqlca.sqlcode == NOTFOUND)

break ;

break ;

}

ACCT_V[nfetch].ACCOUNT_ID = account_id;

strcpy(ACCT_V[nfetch].PHONE, phone );

strcpy(ACCT_V[nfetch].ADDRESS, address );

/* select한 data 개수 증가 */

nfetch++;

return_code = nfetch

/* NFETCH 개수만큼 select 했다면 while문 벗어남 */

258 Tmax Application Development Guide

Page 277: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (nfetch > NFETCH) {

nfetch = NFETCH;

return_code = nfetch;

break ;

}

}

/* cursor close */

EXEC SQL close CUR_1;

/* select의 결과와 그 data를 클라이언트에게 return */

tpreturn ( TPSUCCESS, return_code, (char *)ACCT_V,

sizeof(struct stru_acct)*nfetch, TPNOFLAGS);

}

테이블 생성 스크립트

다음은 Informix 테이블 생성 스크립트 예제이다.

<mkdb.sql>

dbaccess << EOF

create database stores7 with buffered log;

grant connect to public;

database stores7;

drop table ACCOUNT;

create table ACCOUNT (

account_id INTEGER,

phone VARCHAR(20),

address VARCHAR(80)

) lock mode row;

create unique index idx_tdb1 on ACCOUNT(account_id);

EOF

테이블 및 데이터 출력 스크립트

다음은 Informix 테이블 및 데이터 출력 스크립트 예제이다.

<sel.sql>

dbaccess << EOF

database stores7;

제11장 예제 259

Page 278: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

select * from ACCOUNT;

EOF

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

resrc SHMKEY = 77990, MAXUSER = 256

*NODE

tmax TMAXDIR =”/home/tmax”,

APPDIR =”/home/tmax/appbin”,

PATHDIR =”/home/tmax/path”

*SVRGROUP

svg1 NODENAME = tmax,

DBNAME = INFORMIX,

OPENINFO = “stores7”,

CLOSEINFO = “”,

TMSNAME = info_tms

*SERVER

SEL_ACCT SVGNAME = svg1, MIN = 1, MAX = 5

*SERVICE

SEL_ACCT SVRNAME = sel_acct

다음은 환경 설정에 추가된 항목에 대한 설명이다.

요구 사항항목

사용하고자하는 데이터베이스를 설정한다.DBNAME

Informix 데이터베이스에 연결 및 해제를 위한 정보를 tpsvrinit(),

tpsvrdone()에서 호출한다.

OPENINFO, CLOSEINFO

- 트랜잭션 처리하는 프로세스 이름을 지정한다.TMSNAME

- OPENINFO 지정으로 인한 자동 트랜잭션 처리 svg1에 속한 해당

서비스를 자동 트랜잭션 상태에서 처리한다.

260 Tmax Application Development Guide

Page 279: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

11.4. 데이터베이스 연동 프로그램애플리케이션을 개발할 때 응용하여 사용할 수 있는 예제를 통해 실제 프로그래밍의 기법을 설명한다. 데

이터베이스 연동은 동일 기종 데이터베이스와 이기종 데이터베이스로 나뉜다.

11.4.1. 동기형 모드(동일 기종)

다음은 동기형 모드에서 동일 기종 데이터베이스에 접속하는 경우 프로그램 흐름에 대한 설명이다.

[그림 11.2] 동기형 모드 흐름도(동일 기종 데이터베이스)

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

서버 프로그램이다.update.pc, insert.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

Tmax 환경파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

SDLFILE이다.demo.s

환경파일이다.tmax.env

● 프로그램 특징

설명구분

- Tmax 연결 : NULL인자로 연결클라이언트 부분

- 버퍼 타입 : STRUCT

제11장 예제 261

Page 280: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구분

- 하위 유형 : input 구조체 파일을 sdlc로 컴파일 하여 SDL 파일 생성 필요

- 트랜잭션 여부: 클라이언트에서 트랜잭션 지정

- 서비스 수 : UPDATE 서비스에서 INSERT 서비스를 요청서버 부분

- 데이터베이스 연결 : Oracle 데이터베이스

- Tmax 환경파일의 SVRGROUP 절에 데이터베이스 정보 지정

● 프로그램 환경

설명구분

SunOS 5.7 32bit시스템

Oracle 8.0.5데이터베이스

구조체 버퍼다음은 구조체 버퍼의 예제이다.

<demo.s>

struct input {

int account_id;

int branch_id;

char phone[15];

char address[61];

};

클라이언트 프로그램다음은 클라이언트 프로그램 예제이다.

<client.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

#define TEMP_PHONE "6283-2114"

#define TEMP_ADDRESS "Korea"

int main(int argc, char *argv[])

{

262 Tmax Application Development Guide

Page 281: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

struct input *sndbuf;

char *rcvbuf;

int acnt_id, n, timeout;

long len;

if (argc != 2) {

fprintf(stderr, "Usage:%s account_id \n", argv[0]);

exit(1);

}

acnt_id = atoi(argv[1]);

timeout = 5;

n = tmaxreadenv("tmax.env", "tmax");

if (n < 0) {

fprintf(stderr, "tmaxreadenv fail! tperrno = %d\n", tperrno);

exit(1);

}

n = tpstart((TPSTART_T *)NULL);

if (n < 0) {

fprintf(stderr, "tpstart fail! tperrno = %s\n", tperrno);

exit(1);

}

sndbuf = (struct input *)tpalloc("STRUCT", "input", `

sizeof(struct input));

if (sndbuf == NULL) {

fprintf(stderr, "tpalloc fail: sndbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

rcvbuf = (char *)tpalloc("STRING", NULL, 0);

if (rcvbuf == NULL) {

fprintf(stderr, "tpalloc fail: rcvbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

sndbuf->account_id = acnt_id;

sndbuf->branch_id = acnt_id;

strcpy(sndbuf ->phone, TEMP_PHONE);

strcpy(sndbuf ->address, TEMP_ADDRESS);

tx_set_transaction_timeout(timeout);

n = tx_begin();

제11장 예제 263

Page 282: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (n < 0)

fprintf(stderr, "tx begin fail! tperrno = %d\n", tperrno);

n = tpcall("UPDATE", (char *)sndbuf, sizeof(struct input),

(char **)&rcvbuf, (long *)&len, TPNOFLAGS);

if (n < 0) {

fprintf(stderr, "tpcall fail! tperrno = %d\n", tperrno);

tpend();

exit(1);

}

n = tx_commit();

if (n < 0) {

fprintf(stderr, "tx commit fail! tx error = %d \n", n);

tx_rollback();

tpend();

exit(1);

}

printf("rtn msg = %s\n", rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

서버 프로그램

다음은 데이터베이스에 UPDATE하는 서버 프로그램의 예제이다.

<update.pc>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/sdl.h>

#include "../sdl/demo.s"

#define OKMSG "YOU COMPLETE THE TRANSACTION"

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

264 Tmax Application Development Guide

Page 283: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char ssn[15];

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

UPDATE(TPSVCINFO *msg)

{

struct input *rcvbuf;

int ret;

long acnt_id, rcvlen;

char *send;

rcvbuf = (struct input *)(msg->data);

send = (char *)tpalloc("STRING", NULL, 0);

if (send == NULL) {

fprintf(stderr, "tpalloc fail errno = %s\n", strerror(tperrno));

tpreturn(TPFAIL, 0, (char *)NULL, 0, 0);

}

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

다음은 데이터베이스에 INSERT하는 서버 프로그램의 예제이다.

< insert.pc>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/sdl.h>

#include "../sdl/demo.s"

#define OKMSG "YOU COMPLETE THE TRANSACTION"

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

char ssn[15];

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

INSERT(msg)

TPSVCINFO *msg;

제11장 예제 265

Page 284: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

{

struct input *rcvbuf;

int ret;

long acnt_id;

char *send;

rcvbuf = (struct input *)(msg->data);

send = (char *)tpalloc("STRING", NULL, 0);

if (send == NULL) {

fprintf(stderr, "tpalloc fail errno = %s\n", tpstrerror(tperrno));

tpreturn(TPFAIL, 0, (char *)NULL, 0, TPNOFLAGS);

}

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

strcpy(phone, rcvbuf->phone);

strcpy(address, rcvbuf->address);

strcpy(ssn, "1234567");

/* Declare && Open Cursor for Fetch */

EXEC SQL INSERT INTO ACCOUNT (

ACCOUNT_ID,

BRANCH_ID,

SSN,

PHONE,

ADDRESS )

VALUES (:account_id, :branch_id, :ssn, :phone, :address);

if (sqlca.sqlcode != 0 && sqlca.sqlcode != 1403 )

{

printf("insert failed sqlcode = %d\n", sqlca.sqlcode);

tpreturn(TPFAIL, -1, (char *)NULL, 0, TPNOFLAGS);

}

strcpy(send, OKMSG);

tpreturn(TPSUCCESS, 1, (char *)send, strlen(send), TPNOFLAGS);

}

테이블 생성 스크립트

다음은 데이터베이스 테이블을 생성하는 SQL 스크립트 예제이다.

<mktable.sql>

266 Tmax Application Development Guide

Page 285: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

$ORACLE_HOME/bin/sqlplus bmt/bmt <<!

drop table ACCOUNT;

create table ACCOUNT (

ACCOUNT_ID integer,

BRANCH_ID integer not null,

SSN char(13) not null,

BALANCE number,

ACCT_TYPE char(1),

LAST_NAME char(21),

FIRST_NAME char(21),

MID_INIT char(1),

PHONE char(15),

ADDRESS char(61),

CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)

);

quit

!

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

res SHMKEY=88000, MINCLH=1, MAXCLH=5, TPORTNO=8880, BLOCKTIME=60

*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, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/bmt/bmt+SesTm=60",

TMSNAME = svg1_tms

*SERVER

update SVGNAME=svg1

insert SVGNAME=svg1

제11장 예제 267

Page 286: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

*SERVICE

UPDATE SVRNAME=update

INSERT SVRNAME=insert

환경파일

다음은 환경파일 예제이다.

<tmax.env>

[tmax]

TMAX_HOST_ADDR=192.168.1.39

TMAX_HOST_PORT=8880

SDLFILE=/user/tmax/sample/sdl/tmax.sdl

TMAX_CONNECT_TIMEOUT=5

11.4.2. 동기형 모드(이기종)

다음은 동기형 모드에서 이기종 데이터베이스에 접속하는 경우 프로그램 흐름에 대한 설명이다.

[그림 11.3] 동기형 모드 흐름도(이기종 데이터베이스 접속)

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

서버 프로그램이다.update.pc, insert.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

268 Tmax Application Development Guide

Page 287: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구성

Tmax 환경파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

SDLFILE이다.demo.s

환경파일이다.tmax.env

● 프로그램 특징

설명구분

- Tmax 연결 : NULL 인자로 연결클라이언트 부분

- 버퍼 유형 : STRUCT

- 하위 유형 : input 구조체 파일을 sdlc로 컴파일 하여 SDL 파일 생성 필요

- 트랜잭션 여부 : 클라이언트에서 명시적으로 트랜잭션 범위 지정

- 서비스 수 : UPDATE 서비스에서 INSERT 서비스를 요청서버 부분

- 데이터베이스 연결 : Oracle 데이터베이스

- 시스템 구성 파일의 SVRGROUP에 데이터베이스 정보 지정

● 프로그램 환경

설명구분

SunOS 5.7 32bit, SunOS 5.8 32bit시스템

Oracle 8.0.5데이터베이스

Tmax 환경파일다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

res SHMKEY=88000, MINCLH=1, MAXCLH=5, TPORTNO=8880, BLOCKTIME=60

*NODE

tmax1 TMAXDIR="/user/ tmax ",

APPDIR="/user/ tmax /appbin",

PATHDIR = "/user/ tmax /path",

TLOGDIR = "/user/ tmax /log/tlog",

제11장 예제 269

Page 288: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

ULOGDIR="/user/ tmax /log/ulog",

SLOGDIR="/user/ tmax /log/slog"

tmax2 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 = tmax1, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/bmt/bmt+SesTm=60",

TMSNAME = svg1_tms

svg2 NODENAME = tmax2, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/bmt/bmt+SesTm=60",

TMSNAME = svg2_tms

*SERVER

update SVGNAME=svg1

insert SVGNAME=svg2

*SERVICE

UPDATE SVRNAME=update

INSERT SVRNAME=insert

환경파일

다음은 환경파일 예제이다.

[tmax1]

TMAX_HOST_ADDR=192.168.1.39

TMAX_HOST_PORT=8880

SDLFILE=/user/tmax/sample/sdl/tmax.sdl

TMAX_CONNECT_TIMEOUT=5

참고

1. 클라이언트와 서버프로그램 등 모두 “11.4.1. 동기형 모드(동일 기종)”경우와 같다.

2. 멀티 노드 환경 설정에 대한 자세한 내용은 "Tmax Administration Guide"를 참고한다.

270 Tmax Application Development Guide

Page 289: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

11.4.3. 비동기형 모드(동일 기종)

다음은 비동기형 모드에서 동일 기종데이터베이스에 접속하는 경우 프로그램 흐름에 대한 설명이다.

[그림 11.4] 비동기형 모드 흐름도(동일 기종 데이터베이스 접속)

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

서버 프로그램이다.update.pc

Tmax에서 제공되는 Makefile로 수정해야 한다.Makefile

Tmax 환경파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

SDLFILE이다.demo.s

환경파일이다.tmax.env

● 프로그램 특징

설명구분

- Tmax 연결 : NULL 인자로 연결클라이언트 부분

- 버퍼 유형 : STRUCT

- 하위 유형 : input 구조체 파일을 sdlc로 컴파일 하여 SDL 파일 생성 필요

- 트랜잭션 여부 : 클라이언트에서 트랜잭션 지정

- 서비스 수 : UPDATE 서비스 요청서버 부분

- 데이터베이스 연결: Orale 데이터베이스

제11장 예제 271

Page 290: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구분

- 시스템 구성 파일의 SVRGROUP 절에 데이터베이스 정보 지정

● 프로그램 환경

설명구분

SunOS 5.7 32bit시스템

Oracle 8.0.5데이터베이스

구조체 버퍼

다음은 구조체 버퍼에 대한 예제이다.

<demo.s>

struct input {

int account_id;

int branch_id;

char phone[15];

char address[61];

};

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<client.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

#define TEMP_PHONE "6283-2114"

#define TEMP_ADDRESS "Korea"

int main(int argc, char *argv[])

{

struct input *sndbuf;

char *rcvbuf;

int acnt_id, n, cd, timeout;

long len;

272 Tmax Application Development Guide

Page 291: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (argc != 2) {

fprintf(stderr, "Usage:%s account_id \n", argv[0]);

exit(1);

}

acnt_id = atoi(argv[1]);

timeout = 5;

n = tmaxreadenv("tmax.env", "tmax");

if (n < 0) {

fprintf(stderr, "tmaxreadenv fail! tperrno = %d\n", tperrno);

exit(1);

}

n = tpstart((TPSTART_T *)NULL);

if (n < 0) {

fprintf(stderr, "tpstart fail! tperrno = %s\n", tperrno);

exit(1);

}

sndbuf = (struct input *)tpalloc("STRUCT", "input", sizeof(struct input));

if (sndbuf == NULL) {

fprintf(stderr, "tpalloc fail: sndbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

rcvbuf = (char *)tpalloc("STRING", NULL, 0);

if (rcvbuf == NULL) {

fprintf(stderr, "tpalloc fail: rcvbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

sndbuf->account_id = acnt_id;

sndbuf->branch_id = acnt_id;

strcpy(sndbuf->phone, TEMP_PHONE);

strcpy(sndbuf->address, TEMP_ADDRESS);

tx_set_transaction_timeout(timeout);

n = tx_begin();

if (n < 0)

fprintf(stderr, "tx begin fail! tperrno = %d\n", tperrno);

cd = tpacall("UPDATE", (char *)sndbuf, sizeof(struct input), TPNOFLAGS);

if (cd < 0) {

fprintf(stderr, "tpacall fail! tperrno = %d\n", tperrno);

제11장 예제 273

Page 292: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

tpend();

exit(1);

}

n = tpgetrply(&cd, (char **)&rcvbuf, (long *)&len, TPNOFLAGS);

if (n < 0) {

fprintf(stderr, "tpgetrply fail! tperrno = %d\n", tperrno);

tpend();

exit(1);

}

n = tx_commit();

if (n < 0) {

fprintf(stderr, "tx commit fail! tx error = %d \n", n);

tx_rollback();

tpend();

exit(1);

}

printf("rtn msg = %s\n", rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<update.pc>

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

#define OKMSG "YOU COMPLETE THE TRANSACTION"

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

char ssn[15];

274 Tmax Application Development Guide

Page 293: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

UPDATE(TPSVCINFO *msg)

{

struct input *rcvbuf;

int ret, cd;

long acnt_id, rcvlen;

char *send;

rcvbuf = (struct input *)(msg->data);

send = (char *)tpalloc("STRING", NULL, 0);

if (send == NULL) {

fprintf(stderr, "tpalloc fail errno = %s\n", strerror(tperrno));

tpreturn(TPFAIL, 0, (char *)NULL, 0, TPNOFLAGS);

}

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

strcpy(phone, rcvbuf->phone);

strcpy(address, rcvbuf->address);

strcpy(ssn, "1234567");

EXEC SQL UPDATE ACCOUNT

SET BRANCH_ID = :branch_id,

PHONE = :phone,

ADDRESS = :address,

SSN = :ssn

WHERE ACCOUNT_ID = :account_id;

if (sqlca.sqlcode != 0 && sqlca.sqlcode != 1403 ) {

fprintf(stderr, "update failed sqlcode = %d\n", sqlca.sqlcode);

tpreturn(TPFAIL, -1, (char *)NULL, 0, TPNOFLAGS);

}

strcpy(send, OKMSG);

tpreturn(TPSUCCESS, 1, (char *)send, strlen(send), TPNOFLAGS);

}

테이블 생성 스크립트

다음은 데이터베이스에 테이블을 생성하는 SQL 스크립트 예제이다.

<mktable.sql>

제11장 예제 275

Page 294: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

$ORACLE_HOME/bin/sqlplus bmt/bmt <<!

drop table ACCOUNT;

create table ACCOUNT (

ACCOUNT_ID integer,

BRANCH_ID integer not null,

SSN char(13) not null,

BALANCE number,

ACCT_TYPE char(1),

LAST_NAME char(21),

FIRST_NAME char(21),

MID_INIT char(1),

PHONE char(15),

ADDRESS char(61),

CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)

);

quit

!

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

<sample.m>

*DOMAIN

res SHMKEY=88000, MINCLH=1, MAXCLH=5, TPORTNO=8880, BLOCKTIME=60

*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, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/bmt/bmt+SesTm=60",

TMSNAME = svg1_tms

*SERVER

update SVGNAME=svg1

276 Tmax Application Development Guide

Page 295: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

*SERVICE

UPDATE SVRNAME=update

환경파일

다음은 환경파일 예제이다.

<tmax.env>

[tmax]

TMAX_HOST_ADDR=192.168.1.39

TMAX_HOST_PORT=8880

SDLFILE=/user/tmax/sample/sdl/tmax.sdl

TMAX_CONNECT_TIMEOUT=5

11.4.4. 대화형 모드(동일 기종)

다음은 대화형 모드에서 동일 기종 데이터베이스에 접속하는 경우 프로그램 흐름에 대한 설명이다.

[그림 11.5] 대화형 모드 흐름도(동일 기종 데이터베이스 접속)

제11장 예제 277

Page 296: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● 프로그램 구성

설명구성

클라이언트 프로그램이다.client.c

서버 프로그램이다.update.pc

Tmax에서 제공되는 Makefile을 수정해야 한다.Makefile

Tmax 환경파일이다.sample.m

데이터베이스에 테이블을 생성하는 SQL 스크립트이다.mktable.sql

SDLFILE이다.demo.s

환경파일이다.tmax.env

● 프로그램 특징

설명구분

- Tmax 연결 : NULL 인자로 연결클라이언트 부분

- 버퍼 유형 : STRUCT

- 하위 유형 : input 구조체 파일을 sdlc로 컴파일 하여 SDL 파일 생성 필요

(애플리케이션을 실행시키기 위해 필요)

- 트랜잭션 여부 : 클라이언트에서 트랜잭션 지정

- 서비스 수 : UPDATE 서비스를 요청서버 부분

- 데이터베이스 연결 : Oracle 데이터베이스

- Tmax 환경파일의 SVRGROUP 절에 데이터베이스 정보 지정

● 프로그램 환경

설명구분

SunOS 5.7 32bit시스템

Oracle 8.0.5데이터베이스

구조체 버퍼다음은 구조체 버퍼의 예제이다.

<demo.s>

278 Tmax Application Development Guide

Page 297: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

struct input {

int account_id;

int branch_id;

char phone[15];

char address[61];

};

클라이언트 프로그램

다음은 클라이언트 프로그램 예제이다.

<client.c>

#include <stdio.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

#define TEMP_PHONE "6283-2115"

#define TEMP_ADDRESS "Korea"

void main(int argc, char *argv[])

{

struct input *sndbuf;

char *rcvbuf;

int acntid, timeout;

long revent, rcvlen;

int cd, n;

if (argc != 2) {

fprintf(stderr, "Usage:%s acntid\n", argv[0]);

exit(1);

}

acntid = atoi(argv[1]);

timeout = 5;

n = tmaxreadenv("tmax.env", "tmax");

if (n < 0) {

fprintf(stderr, "tmaxreadenv fail tperrno = %d\n", tperrno);

exit(1);

}

n = tpstart((TPSTART_T *)NULL);

if (n < 0) {

fprintf(stderr, "tpstart fail tperrno = %s\n", tperrno);

exit(1);

제11장 예제 279

Page 298: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

}

printf("tpstart ok!\n");

sndbuf = (struct input *)tpalloc("STRUCT", "input", sizeof(struct input));

if (sndbuf == NULL) {

fprintf(stderr, "tpalloc fail: sndbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

rcvbuf = (char *)tpalloc("CARRAY", NULL, 0);

if (rcvbuf == NULL) {

fprintf(stderr, "tpalloc fail: rcvbuf tperrno = %d\n", tperrno);

tpend();

exit(1);

}

sndbuf->account_id = acntid;

sndbuf->branch_id = acntid;

strcpy(sndbuf->phone, TEMP_PHONE);

strcpy(sndbuf->address, TEMP_ADDRESS);

tx_set_transaction_timeout(timeout);

n = tx_begin();

if (n < 0)

fprintf(stderr, "tx begin fail tx error = %d\n", n);

printf("tx begin ok!\n");

cd = tpconnect("UPDATE", (char *)sndbuf, 0, TPSENDONLY);

if (cd < 0) {

fprintf(stderr, "tpconnect fail tperrno = %d\n", tperrno);

tpend();

exit(1);

}

while (1) {

n = tpsend(cd, (char *)sndbuf, sizeof(struct input), TPRECVONLY,

&revent);

if (n < 0) {

fprintf(stderr, "tpsend fail revent = 0x%08x\n", revent);

tx_rollback();

tpend();

exit(1);

}

printf("tpsend ok\n");

n = tprecv(cd, (char **)&rcvbuf, (long *)&rcvlen, TPNOTIME, &revent);

280 Tmax Application Development Guide

Page 299: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (n < 0 && revent != TPEV_SENDONLY) {

fprintf(stderr, "tprecv fail revent = 0x%08x\n", revent);

tx_rollback();

tpend();

exit(1);

}

printf("tprecv ok\n");

sndbuf->account_id++;

if (revent != TPEV_SENDONLY)

break;

}

n = tprecv(cd, (char **)&rcvbuf, (long *)&rcvlen, TPNOTIME, &revent);

if (n < 0 && revent != TPEV_SVCSUCC) {

fprintf(stderr, "tprecv fail revent = 0x%08x\n", revent);

tx_rollback();

tpend();

exit(1);

}

printf("rcvbuf = [%s]\n", rcvbuf);

n = tx_commit();

if (n < 0) {

fprintf(stderr, "tx commit fail tx error = %d\n", n);

tx_rollback();

tpend();

exit(1);

}

printf("tx commit ok!\n");

printf("rtn msg = %s\n", rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

서버 프로그램

다음은 서버 프로그램 예제이다.

<update.pc>

제11장 예제 281

Page 300: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <stdio.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include "../sdl/demo.s"

void _db_work();

#define OKMSG "YOU COMPLETE THE TRANSACTION"

EXEC SQL include sqlca.h;

EXEC SQL BEGIN DECLARE SECTION;

int account_id;

int branch_id;

char ssn[15];

char phone[15];

char address[61];

EXEC SQL END DECLARE SECTION;

struct input *rcvbuf;

UPDATE(TPSVCINFO *msg)

{

int ret, count;

long acnt_id;

long revent, rcvlen, flag;

char *send;

rcvbuf = (struct input *)tpalloc("STRUCT", "input", 0);

send = (char *)tpalloc("CARRAY", NULL, 0);

count = 1;

flag = 0;

while (1) {

ret = tprecv(msg->cd, (char **)&rcvbuf, &rcvlen, TPNOTIME, &revent);

if (ret < 0 && revent != TPEV_SENDONLY) {

fprintf(stderr, "tprecv fail revent = 0x%08x\n", revent);

tpreturn(TPFAIL, -1, (char *)rcvbuf, 0, TPNOFLAGS);

}

printf("tprecv ok!\n");

if (count == 10) {

flag &= ~TPRECVONLY;

flag |= TPNOTIME;

}

else

282 Tmax Application Development Guide

Page 301: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

flag |= TPRECVONLY;

ret = tpsend(msg->cd, (char *)send, strlen(send), flag, &revent);

if (ret < 0) {

fprintf(stderr, "tpsend fail revent = 0x%08x\n", revent);

tpreturn(TPFAIL, -1, (char *)NULL, 0, TPNOFLAGS);

}

printf("tpsend ok!\n");

_db_work();

/* break after 10 iterations */

if (count == 10)

break;

count++;

}

strcpy(send, OKMSG);

printf("tpreturn ok!\n");

tpreturn(TPSUCCESS, 1, (char *)send, strlen(send), TPNOFLAGS);

}

void _db_work() {

account_id = rcvbuf->account_id;

branch_id = rcvbuf->branch_id;

strcpy(phone, rcvbuf->phone);

strcpy(address, rcvbuf->address);

strcpy(ssn, "1234567");

EXEC SQL UPDATE ACCOUNT

SET BRANCH_ID = :branch_id,

PHONE = :phone,

ADDRESS = :address,

SSN = :ssn

WHERE ACCOUNT_ID = :account_id;

if (sqlca.sqlcode != 0 && sqlca.sqlcode != 1403 )

{

fprintf(stderr, "update failed sqlcode = %d\n", sqlca.sqlcode);

tpreturn(TPFAIL, -1, (char *)NULL, 0, 0);

}

}

제11장 예제 283

Page 302: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

테이블 생성 스크립트

다음은 데이터베이스에 테이블을 생성하는 SQL 스크립트 예제이다.

<mktable.sql>

$ORACLE_HOME/bin/sqlplus bmt/bmt <<!

drop table ACCOUNT;

create table ACCOUNT (

ACCOUNT_ID integer,

BRANCH_ID integer not null,

SSN char(13) not null,

BALANCE number,

ACCT_TYPE char(1),

LAST_NAME char(21),

FIRST_NAME char(21),

MID_INIT char(1),

PHONE char(15),

ADDRESS char(61),

CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)

);

quit

!

Tmax 환경파일

다음은 Tmax 환경파일 예제이다.

*DOMAIN

res SHMKEY=88000, MINCLH=1, MAXCLH=5, TPORTNO=8880, BLOCKTIME=60

*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, DBNAME = ORACLE,

OPENINFO = "ORACLE_XA+Acc=P/bmt/bmt+SesTm=60",

TMSNAME = svg1_tms

284 Tmax Application Development Guide

Page 303: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

*SERVER

update SVGNAME=svg1, CONV=YES

*SERVICE

UPDATE SVRNAME= update

환경파일

<tmax.env>

[tmax]

TMAX_HOST_ADDR=192.168.1.39

TMAX_HOST_PORT=8880

SDLFILE=/user/tmax/sample/sdl/tmax.sdl

TMAX_CONNECT_TIMEOUT=5

11.5. TIP를 이용한 프로그램Tmax에서는 TIP(Tmax Information Provider)를 사용하여 시스템 환경 정보, 통계 정보 확인, 시스템 운용

관리 등 다양한 기능을 수행할 수 있다.

TIP은 TIPSVC를 처리하기 위하여 Tmax에서 제공하는 기능 프로세스로서 TIP을 사용하여 다음의 기능

을 수행할 수 있다.

● 시스템 환경 정보 확인 : 시스템의 정적인 환경 정보를 확인한다.

● 시스템 통계 정보 확인 : 시스템 운영 중에 각각 프로세스의 상태 등을 확인한다.

● 시스템 운용 관리 : 프로세스를 추가로 기동하거나 종료한다.

11.5.1. TIP 구조

TIPSVC를 처리하기 위한 별도의 기능 프로세스인 TIP 서버는 SYS_SVR 서버 타입을 가지며, TIP 서버

그룹에 속한다. 클라이언트 혹은 서버의 요청을 받은 TIP 서버는 그 요청을 CLH/TMM에게 전달하여 처리

결과를 다시 요청자에게 돌려준다. TIP 서버는 필드 키를 바탕으로 서비스를 처리한다. 요청하는 클라이

언트나 서버는 필드 버퍼에 요구하려는 데이터를 실어 요청을 하며, 그 결과를 필드 버퍼로 받는다.

다음은 TIPSVC에 요청하기 위하여 포함해야 할 데이터이다.

● 조직(TIP_OPERATION)

제11장 예제 285

Page 304: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

시스템의 정적인 환경 정보, 통계 정보의 확인, BOOT/DOWN 시스템 운용 관

리할 경우에는 GET으로 설정한다.

GET

시스템 설정 상태를 변경하려고 하는 경우에 SET으로 설정한다. 현재는 GET

만 사용된다.

SET

● 세그먼트(TIP_SEGMENT)

어떤 기능을 수행할지 결정하기 위하여 이 필드를 사용한다.

다음은 TIP_SEGMENT 필드에 설정할 수 있는 값이다.

설명설정값

시스템 정적인 설정 정보를 확인한다.CONFIGURATION

시스템의 운영 중에 통계 정보를 확인한다.STATISTICS

시스템 운용 관리(BOOT/DOWN)를 확인한다.ADMINISTRATION

● 절(TIP_SECTION)

TIP_SECTION을 설정했을 경우 어떤 항목에 대하여 처리를 할 것인지 세부 항목을 결정한다.

설명설정값

DOMAIN / NODE / SVRGROUP / SERVER / SERVICE / ROUTING / RQ /

GATEWAY

CONFIGURATION

NODE / SPR / SERVICE / RQSTATISTICS

BOOT / DOWN / CHLOG / CHTRCADMINISTRATION

● 명령어(TIP_CMD)

필드는 TIP_SECTION이 ADMINISTRATION일 경우에만 사용된다.

설명설정값

Tmax 시스템을 기동한다.TIP_BOOT

Tmax 시스템을 다운한다.TIP_DOWN

11.5.2. TIP 사용

TIP의 사용 방법과 에러 확인하는 방법에 대해 설명한다.

286 Tmax Application Development Guide

Page 305: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TIP 사용 방법

● 환경 설정

TIP 서버는 Tmax에서 제공하는 기능 프로세스이기 때문에 사용자가 서비스를 작성할 필요가 없다. 단,

환경 파일에 TIP 서버를 등록해야 한다.

다음은 환경 설정의 예제이다.

*DOMAIN

res ..., TIPSVC = TIPSVC

*NODE

tmaxs1 ...

*SVRGROUP

tsvg ..., SVGTYPE=TIP

*SERVER

TIP SVGNAME=tsvg, SVRTYPE=SYS_SVR

– DOMAIN 절에는 TIPSVC를 등록한다. 등록하지 않을 경우에는 기본값으로 TIPSVC가 등록된다.

– SVRGROUP 절에는 TIP 서버 그룹(SVGTYPE=TIP)을 등록한다.

– SERVER 절에는 TIP 서버(SVRTYPE=SYS_SVR)를 등록한다.

● 시스템 접속

사용자는 Tmax 시스템 접속할 때에 TPSTART_T 구조체의 usrname 항목에 .tpadmin 을 설정해야 한

다. TIP_SEGMENT 가 ADMINISTRATION일 경우에만 usrname을 설정하며, 다른 경우에는 설정하지

않아도 된다. 잘못된 usrname이 설정되었을 경우에는 TIP_ERROR 필드에 TIPEAUTH 에러가 설정된

다.

strcpy(tpinfo->usrname, “.tpadmin”);

● 버퍼 할당

TIP 서버는 필드키를 바탕으로 서비스를 처리하므로, 요청하는 클라이언트나 서버 프로그램은 필드키

버퍼를 할당해야 한다.

● TIP 요청 항목 설정

설명항목

시스템 환경정보 변경 및 확인할 경우 설정한다.TIP_OPERATION

시스템 정보확인 및 운영관리를 위해서 설정한다.TIP_SEGMENT

제11장 예제 287

Page 306: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명항목

SEGMENT에서 설정항목에 대한 세부처리를 설정한다.TIP_SECTION

TIP_SEGMENT가 ADMINISTRATION일 경우만 설정한다.TIP_CMD

멀티 노드일 경우만 설정하며, 단일 노드일 경우, 지정하지 않으면 기본값으

로 로컬 노드가 설정된다. 잘못 설정하였을 경우 TPEINVAL 에러가 발생한

다.

TIP_NODENAME

● TIPSVC 요청

TIP 요청 항목을 설정하였다면, 설정한 필드 버퍼를 sndbuf로 하여, tpcall이나 tpacall을 이용하여 TIPSVC

로 요청을 한다. 클라이언트, 서버에서 모두 요청할 수 있으며, 트랜잭션은 지원하지 않는다.

● 결과 수신

수신 필드키 버퍼에 서비스 결과가 저장된다.

에러 확인

● 에러가 발생하지 않은 경우

수신 필드키 버퍼의 TIP_ERROR 항목에 0이 설정된다.

● 에러가 발생한 경우

내용에러

TIP_ERROR에 설정된 에러 내용에 대하여 상세한 에러 내용을 확인할 수 있

다.

TIP_STATUS

에러를 유발시킨 필드를 확인할 수 있다.TIP_BADFIELD

수신 필드키 버퍼의 TIP_ERROR 항목에 0보다 큰 값이 설정된다. 이는 /us

rinc/tip.h에서 확인할 수 있다.

TIP_ERROR

다음은 TIP_ERROR에 설정되는 에러 값에 대한 설명이다.

설명설정값

에러가 발생하지 않는다.TIPNOERROR

유효하지 않은 필드키가 사용되었다. 일반적으로 fdlc utility를 사용하여 컴파

일되지 않은 필드키가 사용되었을 경우 TIP_ERROR는 TIPEBADFLD로 설

정된다.

TIPEBADFLD

구현되지 않은 기능에 대하여 요청한 경우이다.TIPEIMPL

현재의 권한으로는 허용되지 않는 서비스이다.TIPEAUTH

288 Tmax Application Development Guide

Page 307: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명설정값

운영 시스템 또는 시스템 에러로서 메모리 할당 실패, Tmax 시스템에 접속

실패, 또는 네트워크 상태가 불안정할 경우 등에 나타나는 에러이다.

TIPEOS

존재하지 않는 항목을 접근하는 경우에 발생한다.TIPENOENT

TIP 서비스 루틴이 에러가 발생하여 TPFAIL로 tpreturn()을 호출하였다.TIPESVCFAIL

11.5.3. TIP 사용 예제

TIP를 사용한 예제를 보여준다.

환경 파일

다음은 단일 노드를 사용한 예제이다.

<cfg.m>

*DOMAIN

res SHMKEY=78850, MAXUSER=200, MINCLH=1, MAXCLH=5,

TPORTNO=8850, BLOCKTIME=60, TXTIME=50, RACPORT=3355

*NODE

tmaxh4 TMAXDIR="/data1/starbj81/tmax",

APPDIR="/data1/starbj81/tmax/appbin",

PATHDIR ="/data1/starbj81/tmax/path",

TLOGDIR ="/data1/starbj81/tmax/log/tlog",

ULOGDIR="/data1/starbj81/tmax/log/ulog",

SLOGDIR="/data1/starbj81/tmax/log/slog"

*SVRGROUP

tsvg NODENAME = "tmaxh4", SVGTYPE=TIP

svg1 NODENAME = "tmaxh4"

*SERVER

TIP SVGNAME=tsvg, SVRTYPE=SYS_SVR, MIN=1, MAX=1

svr SVGNAME=svg1, MIN=1

*SERVICE

TOUPPER SVRNAME=svr

다음은 멀티 노드를 사용한 예제이다.

<cfg.m>

제11장 예제 289

Page 308: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

*DOMAIN

tmax SHMKEY=98850,

TPORTNO=8850,

BLOCKTIME=60,

RACPORT=3355,

MAXUSER=10

*NODE

Tmaxh4 TMAXDIR="/data1/starbj81/tmax",

APPDIR="/data1/starbj81/tmax/appbin",

PATHDIR = "/data1/starbj81/tmax/path",

TLOGDIR = "/data1/starbj81/tmax/log/tlog",

ULOGDIR="/data1/starbj81/tmax/log/ulog",

SLOGDIR="/data1/starbj81/tmax/log/slog"

tmaxh2 TMAXDIR="/data1/starbj81/tmax",

APPDIR="/data1/starbj81/tmax/appbin",

PATHDIR = "/data1/starbj81/tmax/path",

TLOGDIR = "/data1/starbj81/tmax/log/tlog",

ULOGDIR="/data1/starbj81/tmax/log/ulog",

SLOGDIR="/data1/starbj81/tmax/log/slog"

*SVRGROUP

tsvg NODENAME = "tmaxh4", SVGTYPE=TIP

svg1 NODENAME = "tmaxh4", COUSIN = "svg2"

svg2 NODENAME = "tmaxh2"

*SERVER

TIP SVGNAME=tsvg, SVRTYPE=SYS_SVR, MIN=1, MAX=1

svr SVGNAME=svg1, MIN=1, MAX=5

*SERVICE

TOUPPER SVRNAME=svr, ROUTING = "rout1"

*ROUTING

rout1 FIELD="STRING", RANGES = "'bbbbbbb'-'ccccccc' : svg1, * :

svg2

필드키 테이블

다음은 필드키 테이블의 예제이다.

< tip.f >

290 Tmax Application Development Guide

Page 309: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#

# common field

#

# name number type flags comments

*base 16000001

TIP_OPERATION 0 string

TIP_SEGMENT 1 string

TIP_SECTION 2 string

TIP_NODE 3 string

TIP_OCCURS 4 int

TIP_FLAGS 5 int

TIP_CURSOR 6 string

TIP_SESTM 7 int

TIP_ERROR 8 int

TIP_STATE 9 int

TIP_MORE 10 int

TIP_BADFIELD 11 string

TIP_CMD 12 string

TIP_CLID 13 int

TIP_MSG 14 string

#

# DOMAIN section fields

#

# name number type flags comments

*base 16000100

TIP_NAME 0 string

TIP_SHMKEY 1 int

TIP_MINCLH 2 int

TIP_MAXCLH 3 int

TIP_MAXUSER 4 int

TIP_TPORTNO 5 int

TIP_RACPORT 6 int

TIP_MAXSACALL 7 int

TIP_MAXCACALL 8 int

TIP_MAXCONV_NODE 9 int

TIP_MAXCONV_SERVER 10 int

TIP_CMTRET 11 int

TIP_BLOCKTIME 12 int

TIP_TXTIME 13 int

TIP_IDLETIME 14 int

TIP_CLICHKINT 15 int

TIP_NLIVEINQ 16 int

TIP_SECURITY 17 string

TIP_OWNER 18 string

TIP_CPC 19 int

#TIP_LOGINSVC 20 string

제11장 예제 291

Page 310: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#TIP_LOGOUTSVC 21 string

TIP_NCLHCHKTIME 22 int

TIP_DOMAINID 23 int

TIP_IPCPERM 24 int

TIP_MAXNODE 25 int

TIP_MAXSVG 26 int

TIP_MAXSVR 27 int

TIP_MAXSVC 28 int

TIP_MAXSPR 29 int

TIP_MAXTMS 30 int

TIP_MAXCPC 31 int

TIP_MAXROUT 32 int

TIP_MAXROUTSVG 33 int

TIP_MAXRQ 34 int

TIP_MAXGW 35 int

TIP_MAXCOUSIN 36 int

TIP_MAXCOUSINSVG 37 int

TIP_MAXBACKUP 38 int

TIP_MAXBACKUPSVG 39 int

TIP_MAXTOTALSVG 40 int

TIP_MAXPROD 41 int

TIP_MAXFUNC 42 int

TIP_TXPENDINGTIME 43 int

TIP_NO 44 int

TIP_TIPSVC 45 string

TIP_NODECOUNT 46 int

TIP_SVGCOUNT 47 int

TIP_SVRCOUNT 48 int

TIP_SVCCOUNT 49 int

TIP_COUSIN_COUNT 50 int

TIP_BACKUP_COUNT 51 int

TIP_ROUT_COUNT 52 int

TIP_STYPE 53 string

TIP_VERSION 54 string

TIP_EXPDATE 55 string

TIP_DOMAINCOUNT 56 int

TIP_RSVG_GCOUNT 57 int

TIP_RSVG_COUNT 58 int

TIP_CSVG_GCOUNT 59 int

TIP_CSVG_COUNT 60 int

TIP_BSVG_GCOUNT 61 int

TIP_BSVG_COUNT 62 int

TIP_PROD_COUNT 63 int

TIP_FUNC_COUNT 64 int

TIP_SHMSIZE 65 int

TIP_CRYPT 66 string

TIP_DOMAIN_TMMLOGLVL 67 string

292 Tmax Application Development Guide

Page 311: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TIP_DOMAIN_CLHLOGLVL 68 string

TIP_DOMAIN_TMSLOGLVL 69 string

TIP_DOMAIN_LOGLVL 70 string

TIP_DOMAIN_MAXTHREAD 71 int

#

# NODE section fields

#

# name number type flags comments

*base 16000200

#TIP_NAME 0 string

TIP_DOMAINNAME 1 string

#TIP_SHMKEY 2 int

#TIP_MINCLH 3 int

#TIP_MAXCLH 4 int

TIP_CLHQTIMEOUT 5 int

#TIP_IDLETIME 6 int

#TIP_CLICHKINT 7 int

#TIP_TPORTNO 8 int

#TIP_TPORTNO2 9 int

#TIP_TPORTNO3 10 int

#TIP_TPORTNO4 11 int

#TIP_TPORTNO5 12 int

#TIP_RACPORT 13 int

#TIP_TMAXPORT 14 string

TIP_CMPRPORT 15 string

TIP_CMPRSIZE 16 int

#TIP_MAXUSER 17 int

TIP_TMAXDIR 18 string

TIP_TMAXHOME 19 string

TIP_APPDIR 20 string

TIP_PATHDIR 21 string

TIP_TLOGDIR 22 string

TIP_SLOGDIR 23 string

TIP_ULOGDIR 24 string

TIP_ENVFILE 25 string

#TIP_LOGINSVC 26 string

#TIP_LOGOUTSVC 27 string

TIP_IP 28 string

#TIP_PEER 29 string

TIP_TMMOPT 30 string

TIP_CLHOPT 31 string

#TIP_IPCPERM 32 int

#TIP_MAXSVG 33 int

#TIP_MAXSVR 34 int

#TIP_MAXSPR 35 int

#TIP_MAXTMS 36 int

제11장 예제 293

Page 312: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#TIP_MAXCPC 37 int

TIP_MAXGWSVR 38 int

TIP_MAXRQSVR 39 int

TIP_MAXGWCPC 40 int

TIP_MAXRQCPC 41 int

TIP_CPORTNO 42 int

TIP_REALSVR 43 string

TIP_RSCPC 44 int

TIP_AUTOBACKUP 45 int

TIP_HOSTNAME 46 string

TIP_NODETYPE 47 int

TIP_CPU 48 int

#TIP_MAXRSTART 49 int

#TIP_GPERIOD 50 int

#TIP_RESTART 51 int

TIP_CURCLH 49 int

TIP_LIVECTIME 50 string

TIP_NODE_TMMLOGLVL 51 string

TIP_NODE_CLHLOGLVL 52 string

TIP_NODE_TMSLOGLVL 53 string

TIP_NODE_LOGLVL 54 string

TIP_NODE_MAXTHREAD 55 int

TIP_EXTPORT 56 int

TIP_EXTCLHPORT 57 int

#

# SVRGROUP section fields

#

# name number type flags comments

*base 16000300

#TIP_NAME 0 string

#TIP_NODENAME 1 string

TIP_SVGTYPE 2 string

#TIP_PRODNAME 3 string

TIP_COUSIN 4 string

TIP_BACKUP 5 string

TIP_LOAD 6 int

#TIP_APPDIR 7 string

#TIP_ULOGDIR 8 string

TIP_DBNAME 9 string

TIP_OPENINFO 10 string

TIP_CLOSEINFO 11 string

TIP_MINTMS 12 int

#TIP_MAXTMS 13 int

TIP_TMSNAME 14 string

#TIP_SECURITY 15 string

294 Tmax Application Development Guide

Page 313: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#TIP_OWNER 16 string

#TIP_ENVFILE 17 string

#TIP_CPC 18 int

TIP_XAOPTION 19 string

TIP_SVG_TMSTYPE 20 string

TIP_SVG_TMSOPT 21 string

TIP_SVG_TMSTHREADS 22 int

TIP_SVG_TMSLOGLVL 23 string

TIP_SVG_LOGLVL 24 string

TIP_NODENAME 25 string

#

# SERVER section fields

#

# name number type flags comments

*base 16000350

#TIP_NAME 0 string

TIP_SVGNAME 1 string

#TIP_NODENAME 2 string

TIP_CLOPT 3 string

TIP_SEQ 4 int

TIP_MIN 5 int

TIP_MAX 6 int

#TIP_ULOGDIR 7 string

TIP_CONV 8 int

TIP_MAXQCOUNT 9 int

TIP_ASQCOUNT 10 int

TIP_MAXRSTART 11 int

TIP_GPERIOD 12 int

TIP_RESTART 13 int

TIP_SVRTYPE 14 string

#TIP_CPC 15 int

TIP_SCHEDULE 16 int

#TIP_MINTHR 17 int

#TIP_MAXTHR 18 int

TIP_TARGET 19 string

TIP_DEPEND 20 string

TIP_CASCADE 21 int

TIP_PROCNAME 22 string

TIP_LIFESPAN 23 string

TIP_DDRI 24 string

TIP_CURSVR 25 int

TIP_SVGNO 26 int

TIP_SVR_LOGLVL 27 string

#

제11장 예제 295

Page 314: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

# SERVICE section fields

#

# name number type flags comments

*base 16000400

#TIP_NAME 0 string

TIP_SVRNAME 1 string

TIP_PRI 2 int

TIP_SVCTIME 3 int

TIP_ROUTING 4 string

TIP_EXPORT 5 int

TIP_AUTOTRAN 6 int

#

# ROUTING section fields

#

# name number type flags comments

*base 16000425

#TIP_NAME 0 string

TIP_FLDTYPE 1 string

TIP_RANGES 2 string

TIP_SUBTYPE 3 string

TIP_ELEMENT 4 string

TIP_BUFTYPE 5 string

TIP_OFFSET 6 int

TIP_FLDLEN 7 int

#TIP_FLDOFFSET 8 int

#

# RQ section fields

#

# name number type flags comments

*base 16000450

#TIP_NAME 0 string

#TIP_SVGNAME 1 string

TIP_PRESVC 2 string

TIP_QSIZE 3 int

TIP_FILEPATH 4 string

TIP_BOOT 5 string

TIP_FSYNC 6 int

TIP_BUFFERING 7 int

#TIP_ENQSVC 8 int

#TIP_FAILINTERVAL 9 int

#TIP_FAILRETRY 10 int

#TIP_FAILSVC 11 string

#TIP_AFTERSVC 12 string

296 Tmax Application Development Guide

Page 315: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#

# GATEWAY section fields

#

# name number type flags comments

*base 16000500

#TIP_NAME 0 string

TIP_GWTYPE 1 string

TIP_PORTNO 2 int

#TIP_CPC 3 int

TIP_RGWADDR 4 string

TIP_RGWPORTNO 5 int

#TIP_BACKUP 6 string

#TIP_NODENAME 7 string

TIP_KEY 8 string

TIP_BACKUP_RGWADDR 9 string

TIP_BACKUP_RGWPORTNO 10 int

TIP_TIMEOUT 11 int

TIP_DIRECTION 12 string

TIP_MAXINRGW 13 int

TIP_GWOWNER 15 string

TIP_RGWOWNER 16 string

TIP_RGWPASSWD 17 string

#

# FUNCTION section fields

#

# name number type flags comments

*base 16000550

#TIP_NAME 0 string

#TIP_SVRNAME 1 string

TIP_FQSTART 2 int

TIP_FQEND 3 int

TIP_ENTRY 4 string

#

# STATISTICS segment fields

#

# name number type flags comments

*base 16000600

#TIP_NAME 0 string

TIP_STATUS 1 string

TIP_STIME 2 string

TIP_TTIME 3 int

TIP_SVC_STIME 4 int

TIP_COUNT 5 int

제11장 예제 297

Page 316: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#TIP_NO 6 int

TIP_NUM_FREE 7 int

TIP_NUM_REPLY 8 int

TIP_NUM_FAIL 9 int

TIP_NUM_REQ 10 int

TIP_ENQ_REQS 11 int

TIP_DEQ_REQS 12 int

TIP_ENQ_REPLYS 13 int

TIP_DEQ_REPLYS 14 int

TIP_CLHNO 15 int

TIP_SVR_NAME 16 string

TIP_SVC_NAME 17 string

TIP_AVERAGE 18 float

TIP_QCOUNT 19 int

TIP_CQCOUNT 20 int

TIP_QAVERAGE 21 float

TIP_MINTIME 22 float

TIP_MAXTIME 23 float

TIP_FAIL_COUNT 24 int

TIP_ERROR_COUNT 25 int

TIP_PID 26 int

TIP_TOTAL_COUNT 27 int

TIP_TOTAL_SVCFAIL_COUNT 28 int

TIP_TOTAL_ERROR_COUNT 29 int

TIP_TOTAL_AVG 30 float

TIP_TOTAL_RUNNING_COUNT 31 int

TIP_TMS_NAME 32 string

TIP_SVG_NAME 33 string

TIP_SPRI 34 int

TIP_TI_THRI 35 int

TIP_TI_AVG 36 float

TIP_TI_XID 37 string

TIP_TI_XA_STATUS 38 string

TIP_GW_NAME 39 string

TIP_GW_NO 40 int

TIP_GW_HOSTN 41 string

TIP_GW_CTYPE 42 string

TIP_GW_CTYPE2 43 string

TIP_GW_IPADDR 44 string

TIP_GW_PORT 45 int

TIP_GW_STATUS 46 string

#

# ADMIN segment fields

#

# name number type flags comments

*base 16000650

298 Tmax Application Development Guide

Page 317: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TIP_IPADDR 0 string

TIP_USRNAME 1 string

TIP_MODULE 2 int

TIP_LOGLVL 3 string

TIP_SPEC 4 string

#

# EXTRA flag fields

#

# name number type flags comments

*base 16000700

TIP_EXTRA_OPTION 0 int

11.5.4. 시스템 환경 정보 조회 프로그램

다음은 시스템의 환경 정보를 확인하는 클라이언트 프로그램 예제이다.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/fbuf.h>

#include <usrinc/tip.h>

#define SEC_DOMAIN 1

#define SEC_NODE 2

#define SEC_SVGROUP 3

#define SEC_SERVER 4

#define SEC_SERVICE 5

#define SEC_ROUTING 6

#define SEC_RQ 7

#define SEC_GATEWAY 8

main(int argc, char *argv[])

{

FBUF *sndbuf, *rcvbuf;

TPSTART_T *tpinfo;

int i, n, sect;

long rcvlen;

char nodename[NAMELEN];

int pid, count = 0;

if (argc != 3) {

printf("Usage: %s section nodename\n", argv[0]);

printf("section:\n");

제11장 예제 299

Page 318: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

printf("\t1: domain\n");

printf("\t2: node\n");

printf("\t3: svrgroup\n");

printf("\t4: server\n");

printf("\t5: service\n");

printf("\t6: routing\n");

printf("\t7: rq\n");

printf("\t8: gateway\n");

exit(1);

}

if (!isdigit(argv[3][0])) {

printf("fork count must be a digit\n");

exit(1);

}

count = atoi(argv[3]);

sect = atoi(argv[1]);

if (sect < SEC_DOMAIN || sect > SEC_GATEWAY) {

printf("out of section [%d - %d]\n", SEC_DOMAIN, SEC_GATEWAY);

exit(1);

}

strncpy(nodename, argv[2], sizeof(nodename) - 1);

n = tmaxreadenv("tmax.env", "TMAX");

if (n < 0) {

fprintf(stderr, "can't read env\n");

exit(1);

}

tpinfo = (TPSTART_T *)tpalloc("TPSTART", NULL, 0);

if (tpinfo == NULL) {

printf("tpalloc fail tperrno = %d\n", tperrno);

exit(1);

}

strcpy(tpinfo->usrname, ".tpadmin");

if (tpstart((TPSTART_T *)tpinfo) == -1){

printf("tpstart fail [%s]\n", tpstrerror(tperrno));

exit(1);

}

if ((sndbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

300 Tmax Application Development Guide

Page 319: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if ((rcvbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

n = fbput(sndbuf, TIP_OPERATION, "GET", 0);

n = fbput(sndbuf, TIP_SEGMENT, "CONFIGURATION", 0);

switch (sect) {

case SEC_DOMAIN:

n = fbput(sndbuf, TIP_SECTION, "DOMAIN", 0);

break;

case SEC_NODE:

n = fbput(sndbuf, TIP_SECTION, "NODE", 0);

break;

case SEC_SVGROUP:

n = fbput(sndbuf, TIP_SECTION, "SVGROUP", 0);

break;

case SEC_SERVER:

n = fbput(sndbuf, TIP_SECTION, "SERVER", 0);

break;

case SEC_SERVICE:

n = fbput(sndbuf, TIP_SECTION, "SERVICE", 0);

break;

case SEC_ROUTING:

n = fbput(sndbuf, TIP_SECTION, "ROUTING", 0);

break;

case SEC_RQ:

n = fbput(sndbuf, TIP_SECTION, "RQ", 0);

break;

case SEC_GATEWAY:

n = fbput(sndbuf, TIP_SECTION, "GATEWAY", 0);

break;

}

n = fbput(sndbuf, TIP_NODENAME, nodename, 0);

n = tpcall("TIPSVC", (char *)sndbuf, 0, (char **)&rcvbuf, &rcvlen,

TPNOFLAGS);

if (n < 0) {

printf("tpcall fail [%s]\n", tpstrerror(tperrno));

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

제11장 예제 301

Page 320: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

exit(1);

}

#if 1

fbprint(rcvbuf);

#endif

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

[결과]

해당 프로그램의 결과(Domain Conf)를 나타내는 예제이다.

$ client 1 tmaxh4

fkey = 217326601, fname = TIP_ERROR, type = int, value = 0

...

fkey = 485762214, fname = TIP_CRYPT, type = string, value = NO

fkey = 485762215, fname = TIP_DOMAIN_TMMLOGLVL, type = string, value = DEBUG1

fkey = 485762216, fname = TIP_DOMAIN_CLHLOGLVL, type = string, value = DEBUG2

fkey = 485762217, fname = TIP_DOMAIN_TMSLOGLVL, type = string, value = DEBUG3

fkey = 485762218, fname = TIP_DOMAIN_LOGLVL, type = string, value = DEBUG4

fkey = 217326763, fname = TIP_DOMAIN_MAXTHREAD, type = int, value = 128

11.5.5. 시스템 통계 정보 조회 프로그램

다음은 시스템의 통계 정보를 확인하는 프로그램의 예제이다.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <usrinc/atmi.h>

#include <usrinc/fbuf.h>

#include <usrinc/tip.h>

#define SEC_NODE 1

#define SEC_TPROC 2

#define SEC_SPR 3

#define SEC_SERVICE 4

#define SEC_RQ 5

#define SEC_TMS 6

#define SEC_TMMS 7

#define SEC_CLHS 8

302 Tmax Application Development Guide

Page 321: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#define NODE_NAME_SIZE 32

main(int argc, char *argv[])

{

FBUF *sndbuf, *rcvbuf;

TPSTART_T *tpinfo;

int i, n, sect;

long rcvlen;

char nodename[NODE_NAME_SIZE];

int stat;

if (argc != 3) {

printf("Usage: %s section node\n", argv[0]);

printf("section:\n");

printf("\t1: node\n");

printf("\t2: tproc\n");

printf("\t3: spr\n");

printf("\t4: service\n");

printf("\t5: rq\n");

printf("\t6: tms\n");

printf("\t7: tmms\n");

printf("\t8: clhs\n");

exit(1);

}

sect = atoi(argv[1]);

if (sect < SEC_NODE || sect > SEC_CLHS) {

printf("out of section [%d - %d]\n",SEC_NODE, SEC_TMMS);

exit(1);

}

memset(nodename, 0x00, NODE_NAME_SIZE);

strncpy(nodename, argv[2], NODE_NAME_SIZE - 1);

n = tmaxreadenv("tmax.env", "TMAX");

if (n < 0) {

fprintf(stderr, "can't read env\n");

exit(1);

}

tpinfo = (TPSTART_T *)tpalloc("TPSTART", NULL, 0);

if (tpinfo == NULL) {

printf("tpalloc fail tperrno = %d\n", tperrno);

exit(1);

}

strcpy(tpinfo->dompwd, "xamt123");

제11장 예제 303

Page 322: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (tpstart((TPSTART_T *)tpinfo) == -1){

printf("tpstart fail tperrno = %d\n", tperrno);

exit(1);

}

if ((sndbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

if ((rcvbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

n = fbput(sndbuf, TIP_OPERATION, "GET", 0);

n = fbput(sndbuf, TIP_SEGMENT, "STATISTICS", 0);

switch (sect) {

case SEC_NODE:

n = fbput(sndbuf, TIP_SECTION, "NODE", 0);

break;

case SEC_TPROC:

n = fbput(sndbuf, TIP_SECTION, "TPROC", 0);

break;

case SEC_SPR:

n = fbput(sndbuf, TIP_SECTION, "SPR", 0);

break;

case SEC_SERVICE:

n = fbput(sndbuf, TIP_SECTION, "SERVICE", 0);

break;

case SEC_RQ:

n = fbput(sndbuf, TIP_SECTION, "RQ", 0);

break;

case SEC_TMS:

stat = 1;

n = fbput(sndbuf, TIP_SECTION, "TMS", 0);

n = fbput(sndbuf, TIP_EXTRA_OPTION, (char *)&stat, 0);

break;

case SEC_TMMS:

n = fbput(sndbuf, TIP_SECTION, "TMMS", 0);

break;

case SEC_CLHS:

n = fbput(sndbuf, TIP_SECTION, "CLHS", 0);

break;

}

304 Tmax Application Development Guide

Page 323: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

n = fbput(sndbuf, TIP_NODENAME, nodename, 0);

n = tpcall("TIPSVC", (char *)sndbuf, 0, (char **)&rcvbuf,

&rcvlen, TPNOFLAGS);

if (n < 0) {

printf("tpcall fail [%s]\n", tpstrerror(tperrno));

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

exit(1);

}

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

[결과]

해당 프로그램의 결과(TMS STATISTICS)를 나타내는 예제이다.

$ client 3000 1 2

fkey = 217326601, fname = TIP_ERROR, type = int, value = 0

fkey = 485762680, fname = TIP_TMS_NAME, type = string, value = tms_ora2

fkey = 485762681, fname = TIP_SVG_NAME, type = string, value = xa1

fkey = 217327226, fname = TIP_SPRI, type = int, value = 0

fkey = 485762649, fname = TIP_STATUS, type = string, value = RUN

fkey = 217327197, fname = TIP_COUNT, type = int, value = 0

fkey = 351544938, fname = TIP_AVERAGE, type = float, value = 0.000000

fkey = 217327212, fname = TIP_CQCOUNT, type = int, value = 0

fkey = 217327227, fname = TIP_TI_THRI, type = int, value = 1

fkey = 351544956, fname = TIP_TI_AVG, type = float, value = 0.000000

fkey = 485762685, fname = TIP_TI_XID, type = string, value = 00000013664

fkey = 485762686, fname = TIP_TI_XA_STATUS, type = string, value = COMMIT

11.5.6. 서버 프로세스 기동 및 종료 프로그램

예제1

다음은 서버 프로세스를 추가로 기동하거나 종료시키는 프로그램 예제이다.

< cli.c >

제11장 예제 305

Page 324: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/fbuf.h>

#include <usrinc/tmaxapi.h>

#include <usrinc/tip.h>

#define NODE_NAME_SIZE 32

main(int argc, char *argv[])

{

FBUF *sndbuf, *rcvbuf;

TPSTART_T *tpinfo;

int i, n, type, clid, count, flags;

long rcvlen;

char svrname[TMAX_NAME_SIZE];

char svgname[TMAX_NAME_SIZE];

char nodename[NODE_NAME_SIZE];

int pid, forkcnt;

if (argc != 6) {

printf("Usage: %s type svrname count nodename forkcnt\n", argv[0])

;

printf("type 1: BOOT, 2: DOWN, 3: DISCON\n");

exit(1);

}

type = atoi(argv[1]);

if ((type != 1) && (type != 2) && (type != 3)) {

printf("couldn't support such a type %d\n", type);

exit(1);

}

if (strlen(argv[2]) >= TMAX_NAME_SIZE) {

printf("too large name [%s]\n", argv[1]);

exit(1);

}

strcpy(svrname, argv[2]);

count = atoi(argv[3]);

flags = 0;

strncpy(nodename, argv[4], NODE_NAME_SIZE - 1);

forkcnt = atoi(argv[5]);

n = tmaxreadenv("tmax.env", "TMAX");

306 Tmax Application Development Guide

Page 325: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if (n < 0) {

fprintf(stderr, "can't read env\n");

exit(1);

}

tpinfo = (TPSTART_T *)tpalloc("TPSTART", NULL, 0);

if (tpinfo == NULL) {

printf("tpalloc fail tperrno = %d\n", tperrno);

exit(1);

}

strcpy(tpinfo->usrname, ".tpadmin");

for (i = 1; i < forkcnt; i++) {

if ((pid = fork()) < 0)

exit(1);

else if (pid == 0)

break;

}

if (tpstart((TPSTART_T *)tpinfo) == -1){

printf("tpstart fail tperrno = %d\n", tperrno);

exit(1);

}

if ((sndbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

if ((rcvbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

n = fbput(sndbuf, TIP_OPERATION, "GET", 0);

n = fbput(sndbuf, TIP_SEGMENT, "ADMINISTRATION", 0);

if (type == 1)

n = fbput(sndbuf, TIP_CMD, "BOOT", 0);

else if (type == 2)

n = fbput(sndbuf, TIP_CMD, "DOWN", 0);

else

n = fbput(sndbuf, TIP_CMD, "DISCON", 0);

if (type == 3) {

clid = count; /* at type 3 */

제11장 예제 307

Page 326: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

flags |= TIP_SFLAG;

n = fbput(sndbuf, TIP_CLID, (char *)&clid, 0);

n = fbput(sndbuf, TIP_FLAGS, (char *)&flags, 0);

} else {

flags |= TIP_SFLAG;

n = fbput(sndbuf, TIP_SVRNAME, svrname, 0);

n = fbput(sndbuf, TIP_COUNT, (char *)&count, 0);

n = fbput(sndbuf, TIP_FLAGS, (char *)&flags, 0);

}

n = fbput(sndbuf, TIP_NODENAME, nodename, 0);

n = tpcall("TIPSVC", (char *)sndbuf, 0, (char **)&rcvbuf,

&rcvlen, TPNOFLAGS);

if (n < 0) {

printf("tpcall failed! errno = %d[%s]\n", tperrno, tpstrerror(tperrno));

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

exit(1);

}

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

● CHLOG section (로그 레벨 변경 예제)

TIP 서비스를 호출할 경우, 필드 버퍼에 아래를 설정하여 TIPSVC를 호출한다.

설명항목

GET으로 설정한다.TIP_OPERATION (string)

ADMINISTRATION으로 설정한다.TIP_SEGMENT (string)

CHLOG로 설정한다.TIP_SECTION (string)

동적으로 로그를 변경하고 싶은 모듈을 설정한다.TIP_MODULE (int)

TIP_TMM | TIP_CLH | TIP_TMS | TIP_SVR 중 하나를 선택한다.

flags를 설정한다.TIP_FLAGS (int)

308 Tmax Application Development Guide

Page 327: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명항목

TIP_VFLAG | TIP_GFLGA | TIP_NFLAG 중 하나를 선택한다.

해당 서버 이름을 설정한다.TIP_SVRNAME (string)

TIP_FLAGS를 TIP_VFLAG로 설정한 경우에만 설정한다.

해당 서버 그룹 이름을 설정한다.TIP_SVGNAME (string)

TIP_FLAGS를 TIP_GFLAG로 설정한 경우에만 설정한다.

해당 노드 이름을 설정한다.TIP_NODENAME (string)

TIP_FLAGS를 TIP_NFLAG로 설정한 경우에만 설정한다.

변경하고자 하는 로그 레벨을 설정한다.TIP_LOGLVL (string)

compact | basic | detail | debug1 | debug2 | debug3 | debug4 중 하나를

선택하여야 하며 반드시 소문자로 설정한다.

결과로 받아오는 값들은 아래와 같다.

에러값이 설정된다. 설정되는 에러값은 다음과 같다.TIP_ERROR (int)

- TIPESVCFAIL : 해당 서비스를 제대로 처리하지 못한 경우

- TIPEOS : 메모리 할당에 실패한 경우

- TIPEBADFLD : TIP_MODULE 값을 설정하지 않은 경우

예제2

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <usrinc/atmi.h>

#include <usrinc/fbuf.h>

#include <usrinc/tmaxapi.h>

#include <usrinc/tip.h>

#include "../fdl/tip_fdl.h"

#define NFLAG 32

#define GFLAG 8

#define VFLAG 1024

int case_chlog(int, char *[], FBUF *);

제11장 예제 309

Page 328: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

#define NODE_NAME_SIZE 32

main(int argc, char *argv[])

{

FBUF *sndbuf, *rcvbuf;

TPSTART_T *tpinfo;

int i, ret, n, type, clid, count, flags = 0;

long rcvlen;

char svrname[TMAX_NAME_SIZE];

char svgname[TMAX_NAME_SIZE];

char nodename[NODE_NAME_SIZE];

int pid, forkcnt;

if (argc < 6) {

printf("Usage: %s svgname svrname nodename [chlogmodule] [flags]

[loglvl]\n", argv[0]);

printf("chlogmodule 1: TIP_TMM, 2: TIP_CLH, 4: TIP_TMS, 8: TIP_SVR\n");

printf("flags 1: NFLAGS, 2: GFLAGS, 3: VFLAGS\n");

printf("loglvl : 1: compact, 2: basic, 3: detail, 4: debug1, 5: debug2,

6: debug3, 7: debug4\n");

exit(1);

}

n = tmaxreadenv("tmax.env", "TMAX");

if (n < 0) {

fprintf(stderr, "can't read env\n");

exit(1);

}

tpinfo = (TPSTART_T *)tpalloc("TPSTART", NULL, 0);

if (tpinfo == NULL) {

printf("tpalloc fail tperrno = %d\n", tperrno);

exit(1);

}

strcpy(tpinfo->usrname, ".tpadmin");

strcpy(svgname, argv[1]);

strcpy(svrname, argv[2]);

strncpy(nodename, argv[3], NODE_NAME_SIZE - 1);

if (tpstart((TPSTART_T *)tpinfo) == -1){

printf("tpstart fail tperrno = %d\n", tperrno);

exit(1);

}

310 Tmax Application Development Guide

Page 329: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if ((sndbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

if ((rcvbuf = (FBUF *)tpalloc("FIELD", NULL, 0)) == NULL) {

printf("tpalloc failed! errno = %d\n", tperrno);

tpend();

exit(1);

}

ret = case_chlog(argc, argv, sndbuf);

n = fbput(sndbuf, TIP_OPERATION, "GET", 0);

n = fbput(sndbuf, TIP_SEGMENT, "ADMINISTRATION", 0);

n = fbput(sndbuf, TIP_CMD, "CHLOG", 0);

n = fbput(sndbuf, TIP_NODENAME, nodename, 0);

n = fbput(sndbuf, TIP_SVGNAME, svgname , 0);

n = fbput(sndbuf, TIP_SVRNAME, svrname, 0);

n=tpcall("TIPSVC", (char *)sndbuf, 0, (char **)&rcvbuf, &rcvlen, TPNOFLAGS);

if (n < 0) {

printf("tpcall failed! errno = %d[%s]\n", tperrno,

tpstrerror(tperrno));

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

exit(1);

}

fbprint(rcvbuf);

tpfree((char *)sndbuf);

tpfree((char *)rcvbuf);

tpend();

}

int case_chlog(int argc2, char *argv2[], FBUF *sndbuf)

{

int chlogmdl, loglvl, flags, n=0;

char cloglvl[TMAX_NAME_SIZE];

const int true = 1, false = 0;

chlogmdl = atoi(argv2[4]);

제11장 예제 311

Page 330: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

if( (chlogmdl != 1) && (chlogmdl != 2) && (chlogmdl != 4) &&

(chlogmdl != 8)

{

printf("couldn't support such a chlogmdl\n");

exit(1);

}

flags = atoi(argv2[5]);

if( (flags != NFLAG) && (flags != GFLAG) && (flags != VFLAG) )

{

printf("couldn't support such a flags\n");

exit(1);

}

loglvl = atoi(argv2[6]);

if( (loglvl < 1) || (loglvl > 7) )

{

printf("couldn't support such a loglvl\n");

exit(1);

}

switch (loglvl)

{

case 1 :

strcpy(cloglvl, "compact");

break;

case 2 :

strcpy(cloglvl, "basic");

break;

case 3 :

strcpy(cloglvl, "detail");

break;

case 4 :

strcpy(cloglvl, "debug1");

break;

case 5 :

strcpy(cloglvl, "debug2");

break;

case 6 :

strcpy(cloglvl, "debug3");

break;

case 7 :

strcpy(cloglvl, "debug4");

break;

}

n = fbput(sndbuf, TIP_MODULE, (char *)&chlogmdl, 0);

n = fbput(sndbuf, TIP_FLAGS, (char *)&flags , 0);

312 Tmax Application Development Guide

Page 331: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

n = fbput(sndbuf, TIP_LOGLVL, cloglvl , 0);

return 1;

}

[결과] (TIP_SVR, => DEBUG4)

$ client xa1 svr23_stat_ins $HOSTNAME 8 1024 7

fkey = 217326601, fname = TIP_ERROR, type = int, value = 0

>>> tmadmin (cfg -v)

loglvl = DEBUG2

● CHTRC section

TIP 서비스를 호출할 경우, 필드 버퍼에 아래를 설정하여 TIPSVC를 호출한다.

설명항목

GET으로 설정해야 한다.TIP_OPERATION (string)

ADMINISTRATION으로 설정해야 한다.TIP_SEGMENT (string)

CHTRC로 설정해야 한다.TIP_SECTION (string)

flags를 설정한다.TIP_FLAGS (int)

TIP_PFLAG | TIP_VFLAG | TIP_GFLAG | TIP_NFLAG 중 하나를 지정한

다.

spri 를 설정한다.TIP_SPRI (int)

TIP_FLAGS를 TIP_PFLAG로 설정한 경우에만 설정한다.

해당 서버 그룹 이름을 설정한다.TIP_SVGNAME (string)

TIP_FLAGS를 TIP_GFLAG로 설정한 경우에만 설정한다.

해당 노드 이름을 설정한다.TIP_NODENAME (string)

TIP_FLAGS를 TIP_NFLAG로 설정한 경우에만 설정한다.

변경하고자 하는 filter spec, receiver spec, trigger spec을 설정한다.TIP_SPEC (string)

결과로 받아오는 값들은 아래와 같다.

에러값이 설정된다. 설정되는 에러값은 다음과 같다.TIP_ERROR (int)

- TIPESVCFAIL : 해당 서비스를 제대로 처리하지 못한 경우

- TIPEOS : 메모리 할당에 실패한 경우

- TIPEBADFLD : TIP_MODULE 값을 설정하지 않은 경우

제11장 예제 313

Page 332: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

11.6. Local recursive call서버에서 tpcall()을 할 경우 같은 서버에 존재하는 서비스일 경우에도 내부에서 recursive하게 호출할 수

있도록 기능이 추가되었다. 이는 서버에서 multicontext 기법을 통해 tpcall()에 한해서 local recursive call

이 가능하도록 한 것으로, 무한 loop를 방지하기 위해서 최대 depth는 8로 제한한다.

주의

Local recursive call을 사용하기 위해서는, 서버 프로그램을 컴파일 할 때 반드시 CFLAGS에

–D_MCONTEXT를 추가해 주어야 하며, libsvr.so 대신 libsvrmc.so 서버 라이브러리를 이용해 컴파

일해야 한다.

서버 프로그램

다음은 서버 프로그램 예제이다.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <usrinc/atmi.h>

SVC15004_1(TPSVCINFO *msg)

{

int i;

char *rcvbuf;

long rcvlen;

if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL)

printf("rcvbuf tpalloc fail[%s]\n",tpstrerror(tperrno));

if (tpcall("SVC15004_2", msg->data, 0, &rcvbuf, &rcvlen, 0) == -1)

{

printf("tpcall fail [%s]\n", tpstrerror(tperrno));

tpfree((char *)rcvbuf);

tpreturn(TPFAIL, 0, 0, 0, 0);

}

strcat(rcvbuf, "_Success");

tpreturn(TPSUCCESS,0,(char *)rcvbuf, 0,0);

}

SVC15004_2(TPSVCINFO *msg)

{

314 Tmax Application Development Guide

Page 333: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

int i;

char *rcvbuf;

long rcvlen;

if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL)

printf("rcvbuf tpalloc fail \n");

}

if (tpcall("SVC15004_3", msg->data, 0, &rcvbuf, &rcvlen, 0) == -1)

{

printf("tpcall fail [%s]\n", tpstrerror(tperrno));

tpfree((char *)rcvbuf);

tpreturn(TPFAIL, 0, 0, 0, 0);

}

strcat(rcvbuf, "_Success");

tpreturn(TPSUCCESS,0,(char *)rcvbuf, 0,0);

}

SVC15004_3(TPSVCINFO *msg)

{

int i;

char *rcvbuf;

long rcvlen;

if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL)

printf("rcvbuf tpalloc fail \n");

if (tpcall("SVC15004_4", msg->data, 0, &rcvbuf, &rcvlen, 0) == -1)

{

printf("tpcall fail [%s]\n", tpstrerror(tperrno));

tpfree((char *)rcvbuf);

tpreturn(TPFAIL, 0, 0, 0, 0);

}

strcat(rcvbuf, "_Success");

tpreturn(TPSUCCESS,0,(char *)rcvbuf, 0,0);

}

Makefile

<Makefile.c.mc>

제11장 예제 315

Page 334: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

# Server makefile

TARGET = $(COMP_TARGET)

APOBJS = $(TARGET).o

NSDLOBJ = $(TMAXDIR)/lib64/sdl.o

LIBS = -lsvrmc -lnodb

OBJS = $(APOBJS) $(SVCTOBJ)

SVCTOBJ = $(TARGET)_svctab.o

CFLAGS = -O -Ae -w +DSblended +DD64 -D_HP -I$(TMAXDIR) -D_MCONTEXT

APPDIR = $(TMAXDIR)/appbin

SVCTDIR = $(TMAXDIR)/svct

LIBDIR = $(TMAXDIR)/lib64

#

.SUFFIXES : .c

.c.o:

$(CC) $(CFLAGS) -c $<

#

# server compile

#

$(TARGET): $(OBJS)

$(CC) $(CFLAGS) -L$(LIBDIR) -o $(TARGET) $(OBJS) $(LIBS) $(NSDLOBJ)

mv $(TARGET) $(APPDIR)/.

rm -f $(OBJS)

$(APOBJS): $(TARGET).c

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

$(SVCTOBJ):

cp -f $(SVCTDIR)/$(TARGET)_svctab.c .

touch ./$(TARGET)_svctab.c

$(CC) $(CFLAGS) -c ./$(TARGET)_svctab.c

#

clean:

-rm -f *.o core $(APPDIR)/$(TARGET)

316 Tmax Application Development Guide

Page 335: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

제12장 에러 처리

Tmax의 API는 에러가 발생하는 경우 상황에 따른 적절한 에러 번호를 설정하여 준다. 에러 메시지를 참

고하면 에러에 대한 원인 규명에 많은 도움을 준다. 이외에 API 내부 시스템 콜 레벨의 에러정보가 알고

싶다면 tuxinc/Uunix.h에 정의되어 있는 에러 메시지와 API들을 참고한다.

애플리케이션 레벨이 아닌 Tmax 시스템 운영상에 발생하는 문제를 도출하는데 도움을 주기 위해 운영상

의 여러가지 정보를 콘솔에 보여주는 디버깅용 CLH를 제공하므로 참고한다.

12.1. API 레벨 에러 처리Tmax API가 실패하는 경우의 반환 값은 API 마다 다르며 전역변수 tperrno에는 에러 상황에 대한 에러 번

호가 설정된다.

참고

Tmax 운영 중에 발생하는 에러 메시지는 Tmax 안내서 중 "Tmax Error Message Reference Guide"를

참고한다.

12.1.1. tpstrerror

서버/클라이언트에서 사용되는 함수로 에러 번호에 해당하는 메시지를 출력한다. Tmax 함수 이용 중 에

러가 발생할 경우 해당 에러 코드는 tperrno라는 전역변수에 설정된다. tpstrerror() 함수는 tperrno에 설정

된 에러에 대한 메시지를 출력하는 함수이다.

● 프로토타입

# include <atmi.h>

char *tpstrerror (int tperrno)

● 파라미터

설명파라미터

에러 메시지를 출력하고자 하는 에러 코드이다.tperrno

● 반환값

설명반환값

에러 코드에 대한 메시지가 있는 경우에러 메시지

제12장 에러 처리 317

Page 336: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명반환값

에러 코드에 대한 메시지가 없는 경우NULL

(tpstrerror()는 에러가 발생하지 않는다.)

● 예제

#include <stdio.h>

#include <usrinc/atmi.h>

void main(int argc, char *argv[])

{

int ret;

char buf;

TPSTART_T *tpinfo;

tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T));

if (tpinfo==NULL) { error processing }

strcpy(tpinfo->dompwd, “tuxedo”);

if (tpstart(tpinfo) == -1){

printf(“tpstart fail , err = %s\n”, tpstrerror(tperrno));

exit(1);

}

buf = (char *)tpalloc(“CARRAY”, NULL, 20);

if (buf==NULL) {error processing };

data process....

tpfree((char *) buf);

tpend();

}

함수 에러 메시지

함수의 에러 메시지는 다음과 같다.

● TPEBADDESC

2구분

유효하지 않은 구별자이다. 구별자를 인수로 하는 API를 사용할 경우 발생한다.내용

해당 서비스 호출 API가 반환하는 값을 사용해야 한다.대응 방법

● TPEBLOCK

3구분

318 Tmax Application Development Guide

Page 337: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

요청한 서비스가 Block 상태로 되어 있어 즉시 서비스를 수행 할 수 없다.내용

TPNOBLOCK 플래그를 설정한 API에서 발생한다. Block 상태가 해제된 후에 다시 시도

해야 한다.

대응 방법

● TPEINVAL

4구분

API 호출시 인수가 유효하지 않다.내용

예를 들어 지원되지 않는 플래그를 설정하거나 송, 수신 간에 tpalloc()으로 할당되지 않

은 버퍼를 사용하였거나 API에서 지원하지 않는 인수를 사용한 경우이다. 해당 경우 API

인수값을 정확히 체크해야 한다.

대응 방법

● TPELIMIT

5구분

시스템 자원 또는 Tmax에서 제공하는 자원의 부족이다.내용

운영체제에서 제공하는 자원, 예를 들면 FD_SET이 부족한 경우이다.대응 방법

● TPENOENT

6구분

서비스 테이블에 서비스가 존재하지 않는 서비스를 호출한 경우 이거나 Tmax 엔진에서

서비스를 인식하지 못하는 경우이다.

내용

환경파일이 수정되었다면 gst로 서비스 테이블을 새로 만들어 서버 애플리케이션을 컴파

일할 때 같이 컴파일 해야 한다

대응 방법

● TPEOS

7구분

OS 레벨의 오류이다. 예를 들면 malloc() 등이 실패한 경우이다.내용

운영체제를 비롯하여 네트워크 및 기존 운영되던 환경이 변경되었는지 제반환경을 점검

해 보아야 한다

대응 방법

● TPEPROTO

9구분

부적절한 상황에서 API가 호출되었다.내용

tpstart()가 2번 수행되거나 서비스를 재귀적으로 호출한 경우이다. 대화형 모드에서 대화

주도권이 없는 쪽에서 송신을 시도하는 경우에도 발생한다.

대응 방법

제12장 에러 처리 319

Page 338: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● TPESVCERR

10구분

정상적으로 서비스가 종료되지 않았다.내용

tpreturn()으로 서비스 완료할 때 종료되지 않은 대화형 모드나 비동기형 서비스 호출이

남아 있는 경우, 서비스 루틴 내에서 시작된 트랜잭션이 완료되지 않은 경우이다. 서버

프로세서를 확인해야 한다.

대응 방법

● TPESVCFAIL

11구분

서비스 루틴에서 서비스 수행을 실패한 것으로 간주하였다.내용

tpreturn()에 TPSUCCESS 이외의 값을 지정하여 클라이언트에게 넘긴 경우이다. 정상적

인 서비스 실패이다.

대응 방법

● TPESYSTEM

12구분

Tmax 시스템에 이상이 발견되었다.내용

주로 네트워크 에러로 인해 발생하며 이 경우 tpreset()을 사용한 후 재접속 하도록 한다.대응 방법

● TPETIME

13구분

환경파일 혹은 애플리케이션에서 설정한 타임아웃 시간을 초과하였다.내용

타임아웃 시간을 조절하거나 네트워크 설정 상의 문제가 없는지를 확인한다.대응 방법

● TPETRAN

14구분

트랜잭션을 지원하지 않는 서비스를 트랜잭션 모드로 호출하였다.내용

해당 API의 플래그를 TPNOTRAN으로 설정하여 사용한다.대응 방법

● TPEGOTSIG

15구분

TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.내용

시그널을 사용하는 경우 해당 API를 TPSIGRSTRT를 설정하여 사용한다.대응 방법

320 Tmax Application Development Guide

Page 339: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● TPEITYPE

17구분

버퍼 타입을 잘못 사용한 경우이다.내용

Tmax에서 지원되지 않는 버퍼 타입을 사용하였거나 해당 API에서 사용할 수 없는 버퍼

를 사용한 경우, DDR 사용할 때 라우팅을 할 수 없는 버퍼를 사용한 경우이다.

대응 방법

● TPEOTYPE

18구분

클라이언트와 서버 프로그램의 버퍼 타입이 서로 일치하지 않는 경우이다.내용

TPNOCHANGE가 설정된 경우 서버에서 보낸 버퍼 타입과 클라이언트가 제공한 버퍼 타

입이 일치하지 않는 경우이다. 데이터값을 확인해야 한다.

대응 방법

● TPEEVENT

22구분

대화형 모드에서 이벤트가 발생한 경우이다.내용

이벤트가 발생하였다. 자세한 내용은 revent에 설정된다.대응 방법

● TPEMATCH

23구분

RQ를 사용할 때 발생하며 서비스명에 해당하는 데이터가 저장되어 있지 않은 경우이다.내용

tpdeq()로 데이터를 꺼내올 때 RQ 데이터 파일 내에 서비스 이름에 해당하는 데이터가

존재하지 않는다.

대응 방법

● TPENOREADY

24구분

서비스가 준비되지 않은 것이거나 구동은 되어있으나 활성화가 안되어있는 경우이다.내용

tmadmin에서 st –s 로 서비스에 대한 상태를 확인하여 NRDY로 나타난다면 제대로 구동

되어 있지 않은 것이다. 서버 프로세서를 다시 확인하고 다시 구동해야 한다.

대응 방법

● TPESECURITY

25구분

Tmax 보안 시스템에 설정되지 않은 사용자가 접속을 시도하였다.내용

사용자 아이디와 암호 등을 확인한다.대응 방법

제12장 에러 처리 321

Page 340: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

● TPEQFULL

26구분

요청된 서비스가 지정한 MAX 큐에 도달했다.내용

Tmax 환경파일 또는 동적으로 Tmadmin 툴에서 MAX 큐값을 조절할 수 있다.대응 방법

● TPEQPURGE

27구분

큐에 저장된 클라이언트의 서비스 요청을 관리자가 지운 경우이다.내용

관리자는 ASQCOUNT 등으로 서비스의 부하를 조절하는 설정한다.대응 방법

● TPECLOSE

28구분

Tmax가 구동되지 않았거나 접속을 할 수 없는 경우이다.내용

Tmax 시스템이 정상적으로 구동되었는지를 확인한다.대응 방법

● TPESVRDOWN

29구분

서버 프로세스가 다운된 상태이다.내용

서버 프로세서가 정상 작동 중인지를 확인해 본다.대응 방법

● TPEPRESVC

30구분

전처리 서비스를 수행할 때 에러가 발생하였다.내용

RQ를 사용할 때 PRESVC를 지정하여 사용할 수 있는데 전처리 서비스에서 오류가 발생

하였다.

대응 방법

● TPEMAXNO

31구분

운영 중인 Tmax 시스템이 한번에 관리할 수 있는 최대 사용자 수를 초과하였다.내용

클라이언트 접속 상태를 확인한 후 타임아웃 시간 등을 조절한다.대응 방법

322 Tmax Application Development Guide

Page 341: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

12.2. 시스템 레벨 에러 처리Tmax API는 많은 시스템 호출을 사용한다. 운영체제나 플랫폼 상에 문제가 있어서 특정 시스템 호출에서

에러가 나는 경우 이를 확인하고 싶을 경우나 에러 메시지가 다른 이종 플랫폼으로 포팅하고자 하는 경우

에러 메시지를 통합하여 관리하고 싶을 때 아래에 소개하는 API를 사용하면 도움이 된다.

사용하는 헤더 파일의 위치는 TMAXDIR/tuxinc/Uunix.h이다.

12.2.1. Uunixerr

시스템 호출 도중 에러가 발생할 경우 통합된 에러번호가 설정되는 변수이다.

int Uunix_err

12.2.2. Uunix_err

● 프로토타입

void Uunix_err (char *msg)

● 파라미터

설명파라미터

에러가 난 시스템 호출에 앞서 추가하고 싶은 메시지이다. 일반적으로 프로

그램명을 기록한다.

msg

● 예제

ret=tmaxreadenv("NO THAT FILE", "TMAX");

if (ret<0) {

Uunix_err("myprog");

exit(1);

}

[결과]

mypog: UOPEN

12.2.3. Ustrerror

● 프로토타입

제12장 에러 처리 323

Page 342: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

char * Uunix_err (int err)

● 파라미터

설명파라미터

알고 싶은 에러 메시지의 통합 에러 번호이다.err

● 예제

ret=tmaxreadenv("NO THAT FILE", "TMAX");

if (ret<0)

{

printf("%d->%s\n", Uunixerr, Ustrerror(Uunixerr));

exit(1);

}

[결과]

11->UOPEN

12.3. 디버그

12.3.1. 디버그 CLH

TMAXDIR/bin 디렉터리에 clh.dbg 라는 이름의 파일이 있다.

파일을 clh로 이름을 바꾸어 사용하면 CLH에서 이루어지는 모든 메시지 전달의 내용을 확인할 수 있다.

반드시 원본 clh를 백업해둔다.

/home/navis/tmax/bin> tmboot

TMBOOT for node(aix5l) is starting:

Welcome to Tmax demo system: it will expire 2002/9/15

Today: 2002/7/16

TMBOOT: TMM is starting: Tue Jul 16 22:39:13 2002

TMBOOT: CLL is starting: Tue Jul 16 22:39:13 2002

TMBOOT: CLH is starting: Tue Jul 16 22:39:13 2002

COM: waiting for TMM reply

LIB: read 96 bytes

(I) CLH Current Tmax Configuration:

Number of client handler(MINCLH) = 1

Supported maximum user per node = 3944

Supported maximum user per handler = 3944

324 Tmax Application Development Guide

Page 343: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

LIB: read 96 bytes

CLH: bootpid = 31202

TMBOOT: SVR(sub) is starting: Tue Jul 16 22:39:13 2002

TMBOOT: SVR(svr2) is starting: Tue Jul 16 22:39:13 2002

CLH: request_from_server: clh = 0, ind = 0, fd = 8

CLH: msg from server: msgtype = 101, svcname = , len = 0

CLH: register_from_server, spri = 32, svri = 0, maxtms = 32

CLH: reply_to_server: clh = 0, ind = 32, fd =8

CLH: msg to server: msgtype = 1101, svcname = , len = 0

CLH: request_from_server: clh = 0, ind = 0, fd = 9

CLH: msg from server: msgtype = 135, svcname = , len = 0

.....

12.3.2. 디버그 라이브러리

TMAXDIR/lib 디렉터리에 libsvrd.a / libsvr.so라는 라이브러리가 존재한다. libsvr.a / libsvr.so 대신에 이들

라이브러리를 사용하면 콘솔 창으로 여러가지 데이터 값을 보여주므로 서버 라이브러리에서 일어나는 흐

름을 파악할 수 있고 에러가 발생하는 시점을 찾는데도 편리하다. libsvrd.so의 경우 이름만 libsvr.so로 이

름만 바꿔쓰면 되며 libsvrd.a의 경우는 재컴파일을 필요로 한다.

/oracle/navis/tmax385/lib> tmboot

TMBOOT for node(tmaxc1) is starting:

Welcome to Tmax demo system: it will expire 2002/9/30

........

GETOPT1: -b 255859

GETOPT1: -s svr2

GETOPT1: -d -1

SVR: delay = -1, _use_lock = 1

COM: waiting for TMM reply

LIB: read 96 bytes

register_to_tmm success

init_shm(78990, 139364) success

init_svctab success

SVR: my info--1 32 0 0 -3

init_clh success

LIB: read 96 bytes

register_to_clh success

init_txinfo success

check_node success

_tmax_init = 1

GETOPT1: -b 255859

GETOPT1: -s fdltest

GETOPT1: -d -1

제12장 에러 처리 325

Page 344: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

SVR: delay = -1, _use_lock = 1

COM: waiting for TMM reply

LIB: read 96 bytes

register_to_tmm success

......

326 Tmax Application Development Guide

Page 345: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

Appendix A. Tmax 환경 설정

A.1. 환경파일Tmax 환경파일은 Tmax 시스템 구성을 설정하며, Tmax 관리자가 작성한다. 이 파일은 서비스 테이블 생

성과 Tmax 시스템 시동에 사용된다.

환경파일의 구성내용은 다음과 같다.

필수 여부설명절

필수하나의 독립적인 Tmax 시스템의 전체 환경정의한다.DOMAIN

필수DOMAIN을 이루는 각 노드에 관계된 환경정의한다.NODE

필수서버 그룹 및 데이터 베이스에 관련된 사항을 정의한다.SVRGROUP

필수서버에 관련된 사항을 정의한다.SERVER

필수서비스에 관련된 사항을 정의한다.SERVICE

선택도메인간 게이트웨이에 관련된 사항을 정의한다.GATEWAY

선택데이터 의존 라우팅에 관련된 사항을 정의한다.ROUTING

선택신뢰성 큐에 관련된 사항을 정의한다.RQ

각 절 이름은 별표(*)로 시작 (예: *DOMAIN, *NODE 등)하고 각 절 이름과 절의 하위 개체 이름은 반드시

줄의 첫 번째 칸에서 시작한다. 하나의 하위 개체에 대한 정의는 쉼표(,)로 구분한다.

참고

Tmax 환경 설정에 대한 자세한 내용은 Tmax 안내서 중에 "Tmax Administration Guide"를 참고한다.

일반 텍스트 파일로 Tmax 환경파일이 만들어지며 cfl 명령어로 컴파일 한다. 컴파일 후 생성된 이진파일

은 서비스 테이블 생성과 Tmax 시스템이 시동될 때 참조된다.

cfl -i Tmax 환경파일 이름

다음은 Tmax 환경파일의 예제이다. ( “< >” 로 싸여있는 부분은 대체 가능)

*DOMAIN

<resrc_name> SHMKEY = <UNIQUE IPCKEY>,

MAXUSER = 256

*NODE

Appendix A. Tmax 환경 설정 327

Page 346: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

<uname> TMAXDIR = “<TMAX installed directory>”

APPDIR = “<APPLICATION DIRECTORY>” ,

PATHDIR = “<path directory>”

*SVRGROUP

<svg_name> NODENAME = <uname> ,

OPENINFO = “Oracle_XA+Acc=P/scott/tiger+SesTm=60”

*SERVER

<svr_name> SVGNAME = <sgrpname> , MIN = 1, MAX = 3

*SERVICE

<svc_name> SVRNAME = <svrname>

DOMAIN 절

Tmax 시스템 구성을 설정한다.

*DOMAIN

<resrc_name> SHMKEY = <UNIQUE IPCKEY>,

MAXUSER = 256

설명구성

하나의 Tmax 시스템(Domain)의 고유한 이름으로 16자 이내로 정의한다.<resrc_name>

내부적으로 공유메모리를 할당하기 위한 값으로 전체 시스템에서 유일한 값

이어야 하고, 32,768 ~ 262,143 사이를 선택한다.

SHMKEY

Domain에 동시에 접속 가능한 최대 클라이언트 수이다.MAXUSER

NODE 절

Domain을 이루는 각 노드들에 대한 정보를 설정한다.

*NODE

<uname> TMAXDIR = “<TMAX installed directory>”

APPDIR = “<APPLICATION DIRECTORY>” ,

328 Tmax Application Development Guide

Page 347: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

PATHDIR = “<path directory>”

설명구성

16자 이내의 문자열로 정의되는 노드의 이름을 나타낸다. 이것은 “uname –n”

명령으로 반환되는 값을 사용한다.

<uname>

hostname”의 반환값과 “uname –n”의 반환값이 동일해야 한다.

Tmax 소프트웨어가 존재하는 디렉터리 정보이다.TMAXDIR

응용프로그램이 존재하는 디렉터리 정보이다.APPDIR

Tmax 프로세스들의 내부적인 통신을 위한 디렉터리 정보이다.PATHDIR

SVRGROUP 절

논리적인 연관성을 지닌 서버들의 모임으로써, 데이터베이스 사용이나 부하조절, 장애대책 등의 기본단

위가 된다. 그리고, 하나의 머신에 대해 적어도 1개의 서버그룹이 정의되어 있다.

*SVRGROUP

<svg_name> NODENAME = <uname> ,

OPENINFO = “Oracle_XA+Acc=P/scott/tiger+SesTm=60”

설명구성

서버그룹의 이름으로 16자 이내의 문자열로 표현되며, SVRGROUP 절에서

유일하여야 한다.

<svg_name>

서버그룹이 존재하는 노드의 이름이다. 또한, 서버그룹에는 데이터베이스에

대한 정의가 포함된다. 따라서 데이터베이스를 사용하는 경우, DBNAME,OP

NEINFO,TMSNAME 3개의 항목들을 정의할 필요가 있다.

NODENAME

사용하는 데이터베이스명(예:ORACLE)을 정의하는 항목이다.DBNAME

데이터베이스와 연결을 맺기 위한 정보를 등록하는 항목으로 256자 이내의

문자열로 정의되며, 데이터베이스 종류에 따라 등록방식이 다르다.

OPENINFO

- Oracle

OPENINFO = “Oracle_XA+Acc = P/account/password+SesTm = 60”

- Informix

OPENINFO = “데이터베이스명”

CLOSEINFO 데이터베이스와의 연결 해제에 필요한 정보를 등록하는 항목

으로 256자 이내의 문자열로 정의되며, 데이터베이스 종류에 따라 등록방식

Appendix A. Tmax 환경 설정 329

Page 348: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구성

이 다르다. 생략 가능하다. CLOSEINFO=“” 인포믹스 데이터베이스에서

CLOSEINFO은 “ ”로 설정해준다.

- TMSNAME

TMS 프로세스의 이름으로 16자 이내로 정의한다.

SERVER 절

응용서버에 대한 정보를 등록한다.

*SERVER

<svr_name> SVGNAME = <sgrpname> , MIN = 1, MAX = 3

설명구성

서비스를 제공하는 서버의 실행파일의 이름으로 16자 이내로 정의된다.<svr_name>

서버 프로세스가 속한 서버 그룹명으로 *SVRGROUP에 정의되어 있어야 한

다.

SVGNAME

명령어 라인상의 옵션을 넘기기 위한 매개변수로, 하이픈(—)을 구분자로 시

스템 옵션과 사용자 옵션을 구분한다. 이 라인은 tpsvrinit() 함수에서 처리한

다.

CLOPT

- MIN : 하나의 서버를 여러 개 동작시키고자 할 경우 기본적으로 동작시킬

서버의 개수이다.

MIN, MAX

- MAX : 동적으로 추가 동작시킬 수 있는 서버의 최대 개수이다.

값이 Y이면 대화형 통신이 이루어지는 대화형 서버임을 나타낸다.( 기본값 :

N )

CONV

SERVICE 절

서비스에 대한 정보를 설정한다.

*SERVICE

<svc_name> SVRNAME = <svrname>

330 Tmax Application Development Guide

Page 349: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

설명구성

클라이언트에서 호출하는 함수명으로 16자 이내로 정의되며 유일한 이름이

어야 한다. SERVICE 절에 등록된 서비스만 지원 가능하다.

<svr_name>

서비스를 제공하는 서버명이다.SVRNAME

A.2. Makefile

Oracle을 위한 TMS Makefile

다음은 Oracle을 위한 TMS Makefile(solaris 32bit) 예제이다.

#

include $(ORACLE_HOME)/precomp/lib/env_precomp.mk

ORALIBDIR = $(LIBHOME)

ORALIB = $(PROLDLIBS) $(LIBCLNTSH)

TARGET = tms_ora

APOBJ = dumy.o

APPDIR = $(TMAXDIR)/appbin

TMAXLIBD= $(TMAXDIR)/lib

TMAXLIBS = -ltms –loras –lsocket -lnsl

all: $(TARGET)

$(TARGET): $(APOBJ)

$(CC) -L$(TMAXLIBD) -o $(TARGET) -L$(ORALIBDIR) $(ORALIB) $(APOBJ)

$(TMAXLIBS)

mv $(TARGET) $(APPDIR)

$(APOBJ):

$(CC) -c dumy.c

#

clean:

-rm -f *.o core $(TARGET)

Informix를 위한 TMS Makefile

다음은 Informix를 위한 TMS Makefile(solaris 32bit) 예제이다.

Appendix A. Tmax 환경 설정 331

Page 350: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

TARGET = tms_info

INFOLIBDIR = ${INFORMIXDIR}/lib

INFOELIBDIR = ${INFORMIXDIR}/esql

INFOLIBD = ${INFORMIXDIR}/lib/esql

INFOLIBS = -lifsql -lifasf -lifgen -lifgls -lifos –lnsl –lsocket –laio –elf -lm –ldl

${INFOLIBDIR}/esql/checkapi.o -lifglx -lifxa

TMAXLIBDIR = $(TMAXDIR)/lib

TMAXLIBS = -ltms -linfs

$(TARGET):

$(CC) -o $(TARGET) -L$(TMAXLIBDIR) -L$(INFOLIBD) -L$(INFOLIBDIR)

–L$(INFOELIBDIR) $(TMAXLIBS) $(INFOLIBS)

cp $(TARGET) $(TMAXDIR)/appbin

#

clean:

-rm -f core $(TARGET)

332 Tmax Application Development Guide

Page 351: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

색인

Symbols2PC, 4, 45

AACID, 45

AP, 47

Atomicity, 45

CCommit 단계, 46

Consistency, 45

CRM, 47

DDurability, 45

IIsolation, 45

LLocal recursive call, 314

MMulticontext, 54

Multithread, 53

NNon-XA 모드, 50

OOSI-TP, 47

PPrepare 단계, 46

RRDP, 17

RM, 47

TTCS, 17

TIP (Tmax Information Provider), 285

TM, 47

Tmax 애플리케이션, 1

TMS, 48

TPSVCINFO 구조체, 174

UUCS, 17

XXA모드, 48

대화형 통신, 35, 38

동기형 통신, 35, 36

로컬 트랜잭션, 45

비동기 통신, 35

비동기형 통신, 37

사용자 인증 보안, 66

서버 프로그램, 2

서비스 접근 제어 기능, 68

시스템 접속 보안, 65

전역 트랜잭션, 45, 225

클라이언트 프로그램, 1

색인 333

Page 352: Tmax Application Development Guide · 9.7.1. tpalloc ..... 113 9.7.2. tprealloc ..... 115

트랜잭션, 45

표준 통신형 버퍼, 42

334 Tmax Application Development Guide