Tmax Gateway Guide (TCP/IP) Tmax v5.0 SP1 Copyright 2009 TmaxSoft Co., Ltd. All Rights Reserved.
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 Gateway Guide (TCP/IP) 발행일 : 2009-08-10 소프트웨어버전 : Tmax v5.0 SP1 안내서버전 : v2.1.1
내용목차 안내서에대하여... vii 제1장 소개... 1 1.1. 게이트웨이기타기능... 2 1.1.1. 게이트웨이헤더... 2 1.1.2. 다중응답처리... 3 1.1.3. 서비스명을찾는순서... 3 1.1.4. 사용자임의의채널지정... 3 1.1.5. 코드변환... 4 제2장 서비스의유형... 7 2.1. 동기형 TCPGW... 7 2.1.1. 서비스블록형방식... 7 2.1.2. 서비스 NON 블록형방식... 9 2.1.3. 리모트동기형호출방식... 10 2.2. 비동기형 TCPGW... 11 2.2.1. Tmax에서서비스요청방식... 11 2.2.2. 리모트에서서비스요청방식... 11 2.3. 서버 TCPGW... 12 2.4. 클라이언트 TCPGW... 13 제3장 환경설정... 15 3.1. Tmax 환경구성... 15 3.1.1. TCPGW의사용옵션... 17 3.1.2. 서버 / 클라이언트 TCPGW의환경파일... 21 3.1.3. 서비스블록형 TCPGW의환경파일... 22 3.1.4. 서비스 NON-블록형 TCPGW의환경파일... 23 3.1.5. 리모트동기형과비동기형 TCPGW 환경파일... 24 3.1.6. 재연결 TCPGW 환경파일... 25 3.1.7. 여러리모트노드와연결을맺는클라이언트 TCPGW... 26 3.2. 사용자헤더환경설정및사용방법... 26 3.2.1. 사용자헤더환경파일... 27 3.2.2. 사용자헤더사용방법... 27 3.3. E 옵션사용시채널백업설정... 28 3.4. Ping 메시지체크시데이터전송... 28 제4장 사용자프로그램... 31 4.1. custom.h 수정... 31 4.2. custom.c 수정... 32 4.3. register.c 수정... 47 제5장 예제... 51 5.1. OUTBOUND TCPGW 예제... 51 5.1.1. 프로그램구성... 51 Tmax iii
5.2. 동기 INBOUND TCPGW 예제... 59 5.2.1. 프로그램구성... 60 5.3. NON 블록킹 TCPGW 예제... 71 5.3.1. 프로그램구성... 71 Appendix A. CUSTOM INFO... 81 A.1. 구조체... 81 A.2. CUSTOM INFO Flags... 82 Appendix B. TCPGW 에러코드... 83 iv Tmax Gateway Guide (TCP/IP)
그림목차 [ 그림 1.1] TCPGW 동작구조... 1 [ 그림 1.2] 동기 / 비동기 TCPGW 동작구조... 2 [ 그림 2.1] 블록형동기 TCPGW... 8 [ 그림 2.2] NON 블록형동기 TCPGW... 9 [ 그림 2.3] 리모트요청동기형 TCPGW... 10 [ 그림 2.4] 비동기형 TCPGW... 11 [ 그림 2.5] 비동기형 TCPGW... 12 [ 그림 2.6] 서버 TCPGW... 12 [ 그림 2.7] 클라이언트 TCPGW... 13 [ 그림 5.1] OUTBOUND TCP/IP 게이트웨이... 51 [ 그림 5.2] 동기 INBOUND TCP/IP 게이트웨이... 59 [ 그림 5.3] NON BLOCKING TCPGW 예제... 71 Tmax v
안내서에대하여 안내서의대상 본안내서는 Tmax ( 이하 Tmax) TCP/IP 게이트웨이를사용하여개발하는개발자를대상으로한다. 본안내서는 Tmax 서버와 Non Tmax 서버의인터페이스를담당하는 Tmax에서제공되는 TCP/IP 게이트웨이에대해기술한안내서이다. 안내서의전제조건 본안내서는 Tmax 시스템에대한전반적인이해와 Tmax 시스템이제공하는각종기능및특성에대한습득을위한기본서이다. 본안내서를원활하게이해하기위해서는다음과같은사항을미리알고있어야한다. 미들웨어 (Middleware) 및 UNIX 시스템에대한이해 Tmax 의기본개념이해 Java, C 프로그래밍의이해 안내서의제한조건 본안내서를읽기전에 Tmax 의기본개념을숙지하고있어야한다. 실무에서의구체적인사용방법이나 관리및운용에관한사항은각제품의안내서를참고한다. 참고 Tmax 시스템개발에대한기본적인내용은 "Tmax Administration Guide" 나 "Tmax Application Devel oment Guide" 를참고한다. Tmax에서제공하는명령어와 C API에대한설명은 Tmax Reference Guide 를참고한다. 안내서에대하여 vii
안내서구성 Tmax Gateway Guide (TCP/IP) 는총 5개의장과 Appendix로구성되어있다. 각장의주요내용은다음과같다. 제1장 : 소개 TCP/IP 게이트웨이시스템의개요에대해기술한다. 제 2 장 : 서비스의유형 TCP/IP 게이트웨이시스템에서제공하는서비스유형에대해기술한다. 제 3 장 : 환경설정 TCP/IP 게이트웨이환경설정방법에대해기술한다. 제 4 장 : 사용자프로그램 TCP/IP 게이트웨이를사용하기위해 custom.h, custom.c, regidster.c 를수정하는방법에대해기술한 다. 제 5 장 : 예제 TCP/IP 게이트웨이서비스유형에대한예제를기술한다. Appendix A.: CUSTOM INFO CUSTOM INFO 구조체, INFO Flags 에대해기술한다. Appendix B.: TCPGW 에러코드 에러코드에대해기술한다. viii Tmax Gateway Guide (TCP/IP)
안내서규약 표기 <AaBbCc123> <Ctrl>+C [Button] 진하게 " "( 따옴표 ) ' 입력항목 ' 하이퍼링크 > +---- ---- 참고 의미프로그램소스코드의파일명 Ctrl과 C를동시에누름 GUI의버튼또는메뉴이름강조다른관련안내서또는안내서내의다른장및절언급화면 UI에서입력항목에대한설명메일계정, 웹사이트메뉴의진행순서하위디렉터리또는파일있음하위디렉터리또는파일없음참고또는주의사항 [ 그림 1.1] [ 표 1.1] AaBbCc123 그림이름 표이름 명령어, 명령어수행후화면에출력된결과물, 예제코드 [ ] 옵션인수값 선택인수값 안내서에대하여 ix
시스템사용환경 요구사항 Platform IBM AIX 5.x HP-UX 11.xx Solaris 7~9 (SunOS 5.7~5.9) Hardware 최소 120MB 하드디스크공간 256MB 이상메모리공간 1GB 이상하드디스크와 512MB 이상메모리공간권장 Database Oracle 9i 또는 10g x Tmax Gateway Guide (TCP/IP)
관련안내서 안내서 Tmax Administration Guide 설명 Tmax 를이용하기위한환경설정을하는방법과시스템운영방식을 기술한안내서이다. 안내서에대하여 xi
연락처 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: info@tmax.co.kr 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: info@tmaxsoft.com 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: info.jp@tmaxsoft.com Web (Japanese): http://www.tmaxsoft.co.jp xii Tmax Gateway Guide (TCP/IP)
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: info.cn@tmaxsoft.com 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: info.asean@tmaxsoft.com Web (English): http://asean.tmaxsoft.com 안내서에대하여 xiii
제 1 장소개 TCP/IP Gateway( 이하 TCPGW) 는 Tmax 서버와 Non Tamx 서버 ( 이하리모트노드 ) 사이의인터페이스를담당하는 Tmax에서제공되는게이트웨이이다. TCPGW는 Tmax 서버의한종류로써 TCP/IP로연결되어있는 UNIX/Windows 서버등과의게이트웨이역할을한다. TCPGW는 Tmax 서버의한종류로서 Tmax 환경파일에서버로등록해야만사용할수있다. 하지만일반다른서버들을만드는방식과는다르게생성해주어야한다. 일반서버는 TCS나 UCS용서버라이브러리를이용하여서버를생성하나, TCPGW는외부와통신을담당하는라이브러리 (libtcpgw.a, libtcpgw.so) 와사용자가작성한프로그램 (custom.c) 과링크하여서버를생성한다. Non Tmax에서보내온메시지를 TCPGW는해당서비스를 tpacall() 하며, 서비스결과는처음요청한 Non Tmax 서버로전송한다. 반대로 Tmax 서비스에서 TCPGW를 tpcall() 이나기타다른방식으로서비스를요청하면 TCPGW는 Non Tmax로요청메시지를보낸후응답이오면자신을 call한서비스로 tpreturn() 한다. 복잡하게타시스템과 TCP/IP로연결하기위해필요한작업들, 예를들어소켓을열고메시지를주고받는일등은모두 TCP/IP 게이트웨이에서처리해주고, 개발자는업무로직만을작성하면되므로개발자들은손쉽게타시스템과연결할수있다. TCPGW 의동작구조는다음과같다. [ 그림 1.1] TCPGW 동작구조 TCPGW는위의그림에서보듯이리모트노드로부터서비스요청을받아서처리할수있고 ( 그림 1-1 에서실선표시 ), Tmax 클라이언트는서비스로부터서비스요청을받아서리모트노드로서비스요청을할수도있다.( 그림 1.1에서점선표시 ) 이와같이리모트노드로부터서비스요청을받아서처리하는것을 OUTBOUND 서비스라하고, Tmax 클라이언트로부터서비스요청을받아서리모트노드로서비스요청을하는것을 INBOUND 서비스라한다. 제 1 장소개 1
[ 그림 1.2] 동기 / 비동기 TCPGW 동작구조 Tmax 클라이언트나서비스에서 TCPGW를바로호출하고응답이올때까지기다리는동기적인호출방식 ( 그림 1.2 에서점선표시 ) 이있다. 이와는달리비동기적인호출방식은 Tmax 클라이언트가 Tmax 서비스를호출하면그서비스에서 TCPGW로제어권이넘어가서해당서비스는다른서비스요청을받을수있게되고, TCPGW가리모트노드로부터응답을받게되면응답을처리하는서비스로요청을넘겨주는방식으로동작하게된다.( 그림 1-2 에서실선표시 ) 여러가지동작방식에대해서는 제2장서비스의유형 에서좀더상세히설명하도록한다. 여러가지유형에맞추어 TCPGW를작성하기위해서는 Tmax 환경을적절히설정하고프로그램 (custom.c, custom.h) 을작성해야하므로더자세한사항은본안내서의 제3장환경설정 과 제4장사용자프로그램 에서설명한다. 1.1. 게이트웨이기타기능 본절에서는게이트웨이가가지고있는기타기능에대해설명한다. 1.1.1. 게이트웨이헤더 TCPGW는 Tmax 클라이언트나서버에서호출시게이트웨이헤더를사용할수있다. 이를사용하기위해서는 TCPGW의다른라이브러리를사용해야한다. 보통은 libtcpgw.a, libtcpgw.so를사용하나게이트웨이헤더를사용하고자하는경우에는 libtcpgw.gwh.a나 libtcpgw.gwh.so를사용해야한다. 게이트웨이헤더는모든데이터버퍼의가장처음 Offset에위치해야한다. 즉, 사용자헤더를사용할경우에게이트웨이헤더다음에사용자헤더가와야한다. 게이트웨이헤더는여러가지다양한목적으로사용하는데, TCPGW에서는여러항목중에서 svc 항목만사용가능하다. 이항목은 NON 블록킹모드로사용하는경우나비동기방식으로사용할때응답데이터에대해처리할서비스명을지정하고자하는경우에사용한다. 게이트웨이헤더는보통사용자헤더를사용하지않을경우에응답을처리할서비스를메시지별로처리하고자하는경우에사용한다. 2 Tmax Gateway Guide (TCP/IP)
TCPGW 는응답을처리할서비스를찾는순서는가장먼저게이트웨이헤더, 두번째는사용자헤더, 세 번째는 -S 옵션으로지정한순서대로찾는다. 1.1.2. 다중응답처리 일반적인 TCPGW 처리방식은한번의요청에대해서하나의응답을받는형태이다. 때에따라서여러번의응답이올수있는데이를처리하기위해서 TCPGW는 custom.c의 get_msg_info 함수의호출을통해서이를처리한다. 여러번의응답이오는경우에매번 get_msg_info 함수가호출되는데, 사용자는수신받은데이터가마지막데이터인지를판단하여적절한값을반환해주면된다. 연속데이터인경우에반환값으로 3을반환해주면 TCPGW는다음데이터가있다고판단하여서비스를요청한클라이언트나서비스에응답을주지않고다음데이터를기다린다. 사용자는마지막데이터를수신한경우에 REPLY 값 (1) 를반환해주면 TCPGW는이전에저장한데이터와마지막데이터를서비스를요청한클라이언트나서비스에돌려준다. 1.1.3. 서비스명을찾는순서 NON 블록형 TCPGW나또는비동기형 TCPGW인경우리모트노드에서온요청이나응답을처리할 Tmax 의서비스가있어야한다. TCPGW는이서비스명을알수가없으므로사용자가적당한서비스명을지정해야하는데 TCPGW는 3가지방식으로서비스명을찾는다. 다음에서설명하는서비스명은반드시 Tmax config 파일에등록되어있어야한다. 1. 게이트웨이헤더를사용할경우에만가능하다. Tmax 클라이언트나서비스에서 TCPGW를요청할때게이트웨이헤더에서비스명을넣어서 TCPGW를호출하면 TCPGW는가장우선적으로이서비스명을사용한다. 2. 사용자헤더에서서비스명을찾는다. Tmax 클라이언트나서비스에서 TCPGW 를요청할때사용자헤 더에서비스명을넣은후에사용자함수 get_service_name 에서서비스명을얻을수있다. 3. CLOPT 의 -S 옵션에지정한서비스를이용한다. 이런경우에는모든메시지에대해서동일한서비스 가적용된다. 이와같은순서로 TCPGW 는서비스명을찾는다. 단, 리모트노드에서최초로서비스를요청할경우에는 위의방식을따르지않고사용자가 get_msg_info 에서서비스명을지정해야한다. 1.1.4. 사용자임의의채널지정 완전한비동기방식으로 TCPGW를구성한경우에사용자는리모트노드로전송할채널을지정할수있다. CLOPT 절에 -a 를사용한다. 완전한비동기방식은서로간에응답이없다. 응답데이터도서비스요청형식으로전달되어야한다. 제 1 장소개 3
예를들어 Tmax의클라이언트나서비스에서 TCPGW로 tpacall에 TPNOREPLY 로호출하면 TCPGW는서비스요청에대한 UID와어떤정보데이터도보관하지않고리모트노드로데이터를전송하고해당서비스를종료한다. 나중에리모트노드로부터응답에대한메시지를수신받았을경우에도이를서비스요청으로처리한다. 반대인경우에 ( 리모트노드에서먼저요청 ) 도동일하게처리한다. 위와같은경우에사용자는리모트노드로전송할채널번호를지정할수있다. CLOPT 절에 -u 옵션을사용한다. 채널지정은다음과같은 2가지경우가있다. Tmax에서먼저서비스를리모트노드로요청한경우 TCPGW는 get_channel_num 함수를호출하는데사용자는전송데이터를분석하여채널을지정할수있다. 리모트노드에서먼저요청한경우인데, 리모트노드에서서비스요청시 get_msg_info 함수에서리모트노드에서요청한채널을데이터에보관하여 Tmax 서비스를호출한다. Tmax 서비스는결과를리모트노드로전송하기위해 tpacall에 TPNOREPLY 로다시 TCPGW로서비스를보낸다. 사용자는 get_channel_num에서이전에보관한채널을사용하여리모트노드로응답을전송할수있다. 이방식을사용함으로써 TCPGW와 Tmax 엔진간의채널이블록되지않고서비스를요청한채널로응답을전송할수있다. 1.1.5. 코드변환 TCPGW가실행되는 Machine는모두 ASCII 코드 ( 한글은완성형 ) 를사용한다. 리모트노드는사용하는코드가다른 Machine에있어이들과메시지를주고받기위해서는코드를일치시켜야한다. 이러한코드변환은리모트에서할수도있고, 아니면 TCPGW에서할수도있다. TCPGW는모든코드를변환하지않고 ASCII <-> EBCDIC, 조합형 <-> 완성형코드만을서로변환한다. TCPGW에서리모트노드로메시지를전송하는경우에는 ASCII에서 EBCDIC, 완성형에서조합형으로코드를변환하고, 리모트에서수신하는경우에는 EBCDIC에서 ASCII, 조합형에서완성형으로코드를변환한다. TCPGW는코드변환을서비스처리단위별로변환한다. 다시말해, TCPGW는서비스단위별로송수신포맷을등록 (Map 파일 ) 하여변환한다. 사용자는 TCPGW와리모트노드간에코드를변환하려면모든서비스에대해서 Map 파일을등록해야한다. 또한 TCPGW에서코드변환기능을이용하려면반드시게이트웨이헤더를사용해야만한다. 리모트로전송하는서비스에대해서 TCPGW는서비스명을알수가없으므로게이트웨이헤더를사용하여 TCPGW 에리모트서비스명을전달해야하기때문이다. 게이트웨이헤더중 pgmname 항목에리모트서비스명을주고, TCPGW는이항목의값으로 Map 파일을로드하여코드를변환한다. TCPGW는 Tmax 클라이언트나서비스에서리모트로서비스요청시에는게이트웨이헤더의 pgmname 항목의값으로 Map 파일을로드하고, 리모트노드에서 Tmax로서비스를요청하는경우에는 get_msg_info 함수에서지정한서비스명으로 Map 파일을로드한다. 사용자가 Map 파일을등록하는방법에대해서설명한다. Map 파일은사용자가텍스트파일로지정한형식에맞게등록해주면된다. 4 Tmax Gateway Guide (TCP/IP)
# COMMSIZE는 INPUT/OUTPUT에서같이사용해야함으로 INPUT/OUTPUT중 # 큰 size의값을입력해야합니다. *COMMSIZE 1024 *INPUT #--------------------------------------------------------------- # item-name length data-type # data-type: CHAR, NUMERIC(UNPACK), KOREAN, BINARY, USER-TYPE #--------------------------------------------------------------- a 10 CHAR b 10 KOREAN c 5 NUMERIC d 10 BINARY *OUTPUT a 10 CHAR b 10 KOREAN c 5 NUMERIC d 10 BINARY e 3 USER1 e1 6 CHAR e2 10 KOREAN e3 8 BINARY COMMSIZE 리모트노드와송수신하는데이터의길이를지정하는항목이다. 모든서비스메시지 ( 송수신포함 ) 중가 장큰메시지의길이를입력해야한다. INPUT TCPGW에서리모트노드로전송하는메시지에대해서등록하는항목이다. TCPGW에서리모트노드로서비스를요청하는경우에이항목에리모트노드로요청하는메시지의포맷을등록하고, 반대로리모트노드에서 Tmax로서비스를요청하는경우에는 Tmax 서비스의처리결과에대한포맷을등록한다. OUTPUT 리모트노드에서 TCPGW로수신받은메시지에대해서등록하는항목이다. TCPGW에서리모트노드로서비스를요청하는경우에는리모트노드에서처리한결과를수신받는메시지의포맷을등록하고, 반대로리모트노드에서 Tmax로서비스를요청하는경우에는 Tmax로서비스를요청하는메시지에대해서포맷을등록한다. 항목명 제 1 장소개 5
단순히사용자가참조용으로만사용하는이름이다. TCPGW 는항목명으로인식하고내부에서는사용 하지않는다. 항목길이 송수신데이터의각항목의실제길이를나타낸다. 각항목의길이만표현하면 TCPGW 내부에서 Offset 로변환하여사용한다. Offset 는항상 0 부터시작한다. 데이터타입 송수신각항목의데이터타입을지정한다. CHAR : 데이터가모든문자 ( 영문자, 숫자, 한글 ) 을포함할수있는항목을나타낸다. NUMERIC : 데이터가숫자만을나타내는경우이다. 코드변환은 CHAR 타입과동일하게코드를변 환한다. 타입 NUMERIC 라해서 Integer 를나타내는것은아니다. KOREAN: 데이터는모두한글을경우에사용한다. TCPGW는이타입의데이터는항상 2 Bytes 단위로코드를변환한다. CHAR에서한글이포함된경우에한글과다른코드 ( 영문자, 숫, 특수문자 ) 사이에한글의시작과끝문자가포함되는데반해이타입의데이터는모두한글문자로인식하기때문에처음과끝에만한글시작과끝문자가포함된다. BINARY: 데이터는코드를변환하지않는다. 사용자는데이터중코드를변환하지않고자하는경우 에는이타입으로지정하면된다. USER-TYPE: 데이터는 Array 형식의데이터타입을지정하고자할경우에사용한다. 예를들어화면에여러개의항목이반복하서여러번나올경우에각항목을반복횟수만큼등록해야하는번거로움이있다. 또는반복횟수를데이터로표현하는경우에는몇번의반복이되는지를알수없어코드변환이어렵다. 이를위해서사용자는사용자정의타입을지정하여 Array 형태의데이를쉽게변환할수있다. 위의 Map 파일에서 USER1는사용자가지정한사용자정의타입이다. 타입이름은사용자가임의로지정하면된다. 사용자정의타입의데이터는 Array 데이터의반복을나타내는항목이므로반드시숫자로이루어져야한다. TCPGW는사용자정의타입을만나면이를 Array의횟수로인식한다. Array의끝은마지막항목의이름을 / 로시작하면된다. 위의경우에는 e1, e2, e3을 Array 항목으로인식해서 e 항목으로지정한횟수만큼코드를변환한다. 주의 Array 횟수는 Map 파일에등록하지않고 TCPGW 와리모트노드사이에데이터전문에표현한다. 6 Tmax Gateway Guide (TCP/IP)
제 2 장서비스의유형 TCPGW는 Tmax에서제공하는라이브러리 (libtcpgw.a, libtcpgw.so) 와개발자가작성하는 custom.c, cus tom.h를함께링크하여만들어진다. 이렇게만들어진 TCPGW는리모트노드와통신을하며, Tmax 클라이언트의요청을리모트노드로보내기도하고리모트노드의요청을 Tmax 서비스에서처리하도록중간역할을해준다. TCPGW는크게동작하는방식에따라동기형 TCPGW와비동기형 TCPGW로나눌수있고, 기동하는방법에따라서버 TCPGW와클라이언트 TCPGW로나눌수있다. 서버와클라이언트모드는리모트노드와 TCPGW 사이에연결시어떤쪽에서먼저연결을시도하는지에따른모드이다. 일단상대방과연결되면어느쪽에서나먼저서비스를요청할수있기때문에서버나클라이언트모드는의미가없다. 본장에서 4가지의 TCPGW의서비스유형에대해서설명한다. 2.1. 동기형 TCPGW 동기형방식은 Tmax의클라이언트나서버에서서비스를요청하고서비스를요청한클라이언트나서버로응답이오는방식을말한다. 반대로리모트노드에서서비스를요청하면 TCPGW는 Tmax의서비스를요청하고그결과로서비스를요청한리모트노드에되돌려주는방식이다. 전자인경우리모트노드로서비스를요청한 Tmax 서비스가블록되는가, 또는블록되지않는가에따라 TCPGW는다르게동작한다. 또한, 후자인경우에는리모트노드에서요청한처리결과를돌려줄때요청한채널로돌려주는방식이다. Tmax의클라이언트나서버에서리모트노드로동기형방식으로서비스를요청할경우에는반드시 TCPGW 와리모트노드간에 UID(Unique Id.) 를서로공유해야한다. 2.1.1. 서비스블록형방식 Tmax의서버나클라이언트에서 TCPGW로서비스를요청하고, 그결과가올때까지기다리는가장일반적인방식이다. 아래그림처럼 Tmax 클라이언트의요청을받은서비스에서 TCPGW 서비스로 tpcall을하면리모트노드에서처리결과를송신할때까지 Tmax 서비스 (SVC1) 가블록되어있게된다. 제 2 장서비스의유형 7
[ 그림 2.1] 블록형동기 TCPGW 블록형동기 TCPGW 동작방식은다음과같다. 1. TCPGW 와리모트노드는연결되어있는상태이다. 2. Tmax 클라이언트는 Tmax 서비스를 tpcall 한다. 3. Tmax 서비스에서는클라이언트의요청을받아들여 TCPGW 로서비스를 tpcall 한다. 4. TCPGW 는연결되어있는리모트노드에서비스를요청한다. 5. 리모트노드에서결과가오면에러인지아닌지를판단하여 TCPGW 서비스를호출한 Tmax 서비스로 tpreturn 한다. 6. 결과를받은 Tmax 서비스는 Tmax 클라이언트로 tpreturn 한다. 이와같은방식으로 TCPGW를동작시키게되면 Tmax 클라이언트에서호출한 Tmax 서비스는 TCPGW 를호출한후에결과를받을때까지블록이되어있게된다. (tpacall() 을한경우도 tpgetrply() 로응답을받는곳에서블록이되기때문에 tpcall() 과마찬가지로블록이되게된다.) 많은수의요청을받아들이기위해서는블록이되는시간까지감안하여많은수의서버를실행해야한다. 이는대외기관통신에서는대외기관의장애 ( 머신, 네트워크 ) 에따라서많은수의서버가필요로하기때문이다. 8 Tmax Gateway Guide (TCP/IP)
2.1.2. 서비스 NON 블록형방식 서비스 NON 블록형방식은 Tmax 클라이언트에서직접 TCPGW 를요청하는방식에서는사용할수없고, TCPGW에서비스를요청하고결과를수신하는서버를중간에두어서처리하는방식이다. 즉, TCPGW 앞에송신서비스와수신서비스를두고 Tmax 클라이언트는송신서비스를호출하고, 송신서비스는 TCPGW 로서비스를전달하고서비스를종료한다. TCPGW 는리모트노드로서비스를요청하여그결과를수신하면, 해당결과를수신서비스에게전달한다. 수신서비스는 TCPGW로부터결과를수신받아클라이언트에게전달하면서비스사이클이종료되는방식이다. 결과적으로클라이언트는서비스를요청하고결과를받는동기방식이나서버는요청을전달하고종료하는비동기방식과같이동작한다. [ 그림 2.2] NON 블록형동기 TCPGW NON 블록형동기 TCPGW 동작방식은다음과같다. 1. Tmax 클라이언트는 Tmax 서비스를 tpcall 한다. 2. Tmax 서비스에서는클라이언트의요청을받아들여 TCPGW 서비스를 tpforward 한다. 3. TCPGW 는연결되어있는리모트노드에메시지를전송한다. 4. 리모트노드에서결과가오면에러인지아닌지를판단하여 tprelay 할서비스로 tprelay 한다. 5. TCPGW 서비스로부터결과를받은서비스 (Tmax 클라이언트로부터 tprelay 할서비스로지정된서비 스 ) 는 Tmax 클라이언트로 tpreturn 한다. 이와같이동작하는 TCPGW 는블록형방식에서수행하는방식보다도적은서버로도많은처리를할수있다. 블록형방식은서비스가 TCPGW 를호출하고블록되기때문에동시에많은처리를위해서는보다많은서버프로세스를실행해야하지만, NON 블록형방식에서는자신의일만처리하고서비스를종료하기때문에적은서버프로세스로도많은일을할수있다. 대외기간간에통신을처리하는경우에는 NON 블록형방식이보다효율적이라고할수있다. 제 2 장서비스의유형 9
2.1.3. 리모트동기형호출방식 리모트노드에서 TCPGW로먼저서비스를요청하는방식이다. TCPGW는리모트노드에서요청한서비스를호출하고그결과를받아서해당서비스를요청한채널로결과를전송한다. 리모트노드는동시에 TCPGW로 Tmax Config에정의되어있는 MAXSACALL 개수를초과하여호출할수없다. [ 그림 2.3] 리모트요청동기형 TCPGW 리모트요청동기형 TCPGW 의동작방식은다음과같다. 1. TCPGW 와리모트노드는연결되어있는상태이다. 리모트노드는 TCPGW 와연결된채널로메시지를 전송한다. 2. TCPGW 는 tpacall() 로 Tmax 서비스를호출한다. 서비스처리결과를 TCPGW 는받아서메시지를요 청한채널을찾는다. 3. 해당채널이정상적으로연결되어있으면결과를전송한다. 이와같은동작방식은리모트노드에서 Tmax의서비스를호출하는가장보편적인방식이다. TCPGW 는리모트노드의채널정보를보관하였다가서비스로부터결과를수신받으면, 보관하고있는채널중에서해당채널을찾아서결과를전송한다. 이때해당채널로결과를되돌려주기전에다른요청은얼마든지가능하다. TCPGW는리모트노드에서요청한채널은블록시키지않고다음요청을받을수있도록처리하기때문에 TCPGW를어떻게운영하는방식에따라서다르게처리할수있다. 10 Tmax Gateway Guide (TCP/IP)
2.2. 비동기형 TCPGW 비동기형호출방식은 Tmax의클라이언트나서버, 또는리모트노드에서 TCPGW 서비스를요청만하고, 그결과는받지않거나또는서비스를요청한곳이아닌다른프로그램에서처리하는방식을말한다. 먼저 Tmax의서비스에서 TCPGW로서비스를요청하고그결과는다른서비스로받을수있다. 클라이언트인경우에는비동기형으로처리할때는 tpacall 로써응답을받지않는경우에만가능하다. 반대로, 리모트노드에서서비스를먼저요청하는경우에위에서와같이서비스만요청하고결과를받지않을수도있고, 서비스를요청하고결과는다른채널로돌려주는방식이비동기형방식이다. 2.2.1. Tmax 에서서비스요청방식 Tmax의서비스에서 TCPGW로 tpacall에 TPNOREPLY 로요청하고해당서비스는종료한다. TCPGW는리모트노드로요청를보내고해당결과가수신되면 Tmax의다른서비스를 tpacall에 TPNOREPLY 로호출하여결과를처리하게하는방식이다. [ 그림 2.4] 비동기형 TCPGW Tmax 에서비동기형 TCPGW 의동작방식은다음과같다. 1. Tmax 서비스에서 TCPGW 로서비스를요청한다.(tpacall 에 TPNOREPLY) 2. TCPGW 는리모트노드로데이터를전송한다. 3. TCPGW 는리모트노드로부터데이터를수신한다. 4. TCPGW 는 Tmax 의다른서비스를호출한다. (tpacall 에 TPNOREPLY) 2.2.2. 리모트에서서비스요청방식 리모트노드에서먼저서비스를 TCPGW 로요청하면, TCPGW는 tpacall로 Tmax 서비스를요청한다. Tmax의서비스처리가완료되면 TCPGW 는리모트노드와연결된채널중에서사용가능한채널중아무채널에처리결과를전송한다. 제 2 장서비스의유형 11
[ 그림 2.5] 비동기형 TCPGW 리모트에서비동기형 TCPGW 의동작방식은다음과같다. 1. 리모트노드에서 TCPGW 로서비스를요청한다. 2. TCPGW 는 Tmax 의서비스를 tpacall 로요청한다. 3. Tmax 의서비스를처리결과를 TCPGW 에전달한다. 4. TCPGW 는리모트노드와연결된채널중에서채널테이블에서채널을검색하여결과를전송한다. 2.3. 서버 TCPGW 서버 TCPGW와클라이언트 TCPGW는연결을맺을때만차이가있고연결이맺어진이후에는기능상차이가없다. 서버 TCPGW는 TCPGW에서 Listen하고있으면리모트노드에서연결하게된다. 서버 TCPGW는클라이언트 TCPGW와마찬가지로리모트노드와 Tmax 클라이언트어디서든지서비스요청을할수있다. [ 그림 2.6] 서버 TCPGW 서버 TCPGW 의동작방식은다음과같다. 1. TCPGW 는 Tmax boot 할때리모트노드에서연결할수있도록연결을기다리고있는다. 12 Tmax Gateway Guide (TCP/IP)
2. 리모트노드에서는 TCPGW 로연결을한다. 2.4. 클라이언트 TCPGW 클라이언트 TCPGW는리모트노드에서기다리고있는포트로연결을맺으면서기동된다. 서버 TCPGW 는클라이언트 TCPGW 와마찬가지로리모트노드와 Tmax 클라이언트어디서든지서비스요청을할수있다. [ 그림 2.7] 클라이언트 TCPGW 클라이언트 TCPGW 의동작방식은다음과같다. 1. 리모트노드에서는 TCPGW 가연결할수있도록연결을기다리고있는다. 2. TCPGW 는 Tmax boot 할때리모트노드와연결을한다. 제 2 장서비스의유형 13
제 3 장환경설정 TCPGW 서버가구성되려면다음과같은파일들이존재하여야한다. 다음은 UNIX 에서사용되는파일이다. 디렉터리 lib lib64 파일명 libtcpgw.a, libtcpgw.so libtmaxgw.a libtmaxgw.so libtcpgw.a, libtcpgw.so libtmaxgw.a libtmaxgw.so 다음은 Windows 에서사용되는파일이다. 디렉터리 bin lib 파일명 tcpgw.dll tmaxgw.dll tcpgw.lib tmaxgw.lib 위의파일 (TCPGW 라이브러리 ) 들은 Tmax 설치할때각디렉터리아래에만들어지지만 custom.c 나 custom.h 는따로제공되므로필요할경우기술지원담당자에게요청해야한다. TCPGW 라이브러리와적절하게구현한 custom.c, custom.h 를컴파일하여 TCPGW 를생성하게된다. 3.1. Tmax 환경구성 TCPGW를사용하기위해서는 Tmax 환경파일에 TCPGW를서버로서등록해야한다. Tmax 서버중 UCS 형서버와등록방법이비슷하며, 차이점은 SVRTYPE이 UCS에서 CUSTOM_GATEWAY 라는차이밖에없다. 등록하는방법은아래와같다. *DOMAIN tmax SHMKEY = 88000, MINCLH = 1, MAXCLH=1, TPORTNO=8800 *NODE tmax1 TMAXDIR="/home/tmax", APPDIR="/home/tmax/appbin" *SVRGROUP svg1 NODENAME=tmax1 제 3 장환경설정 15
*SERVER tcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=10, SVRTYPE=CUSTOM_GATEWAY, CLOPT="-- -P 5050 -N 10 -k 71673" *SERVICE TCPGW1 TCPGW2 SVRNAME=tcpgw, SVCTIME=20 SVRNAME=tcpgw, SVCTIME=25 TCPGW를사용하기위해 Tmax 환경파일을수정할때는 SERVER, SERVICE 절만적절히설정하면된다. MIN TCPGW의프로세스개수를지정하는항목으로써이항목의값이 1보다클경우에 TCPGW가서버모드인지, 클라이언트모드인지에따라서사용하는포트번호가다르다. 항목 서버모드 설명 MIN 값이 2 이상이면 2개이상의프로세스에서같은포트를 Listen할수없으므로 TCPGW는아래에설명하는옵션중 P 옵션으로입력하는포트번호에자신의서버번호를사용한다. 예를들어포트번호가 5050이면첫번째프로세스는 5050 포트번호를, 두번째프로세스는 5051를이런식으로 1씩증가되면서프로세스개수만큼포트를사용한다. 그러므로프로세스수가 2개이상이면지정한프로세스수만큼포트번호가사용가능한지확인해야한다. 클라이언트모드 클라이언트로동작할경우에는 3 가지방식으로사용할수있다. 첫번째는리모트노드에서하나의포트번호를 Listen하고, 모든 TCPGW 프로세스는리모트노드에서 Listen하고있는포트로연결하는방식이다. 두번째는 C 옵션을사용하여서버모드처럼포트번호를 TCPGW 프로세스별로다르게사용할수있다. p 옵션으로지정한포트번호에서버번호를더해서리모트노드에연결을시도한다. 이경우에리모트노드는여러개의포트번호를 Listen하고있어야한다. 또한프로세스수만큼지정한포트가사용가능해야한다. 세번째는 f 옵션을사용하여여러개의리모트노드에연결하는방식으로연결하고자하는리모트노드의정보를별도의파일에등록하고 " f" 옵션을사용하여해당파일명을지정하면 TCPGW는해당파일의정보를로드하여리모트클라이언트와연결한다. 16 Tmax Gateway Guide (TCP/IP)
CPC CPC 항목은 Tmax 엔진과 TCPGW간의채널수를지정하는항목으로써, Tmax의클라이언트나서비스에서리모트노드로요청하는경우에는동시에요청하는수만큼 CPC 수를지정해야한다. 이경우에도 NON 블록형인경우에는동시요청수만큼지정할필요가없이적당한수만큼만지정하면된다. 반대인경우에는 TCPGW는 Tmax 엔진 tpacall로요청하므로많은채널을사용할필요는없다. CLOPT: 3.1.1. TCPGW 의사용옵션 설명을참고한다. SVCTIME: TCPGW는하나의서버프로세스에여러개의서비스를지정하여서비스마다 SVCTIME 값을다르게적용할수있다. 이를위해서 *SERVICE 절에여러개의서비스를지정하고, 서비스마다 SVCTIME 값을다르게지정하면 TCPGW는해당요청한서비스별로지정한서비스 Time 값을사용한다. 3.1.1. TCPGW 의사용옵션 TCPGW는 Tmax config 파일에등록할수있는항목이제안되어있는관계로 CLOPT 항목에많은옵션을설정할수있다. 아래에설명하는옵션에따라서 TCPGW 동작방식이다르므로아래의설명을정확히이해해야한다. 옵션 R 설명 서버모드로 TCPGW 가동작할경우에 Listen 하고자하는 IP 주소를지정하는옵션이다. 이항목은지정한 IP 주소에대해서만연결을받아들이고자하는경우에사용한다. 클라이언트모드로 TCPGW가동작하는경우 -M 옵션을같이사용하여동작모드를변경하여 TCPGW가연결하고자하는리모트노드의 IP를지정할수있다. 예를들어옵션을 -R 1.1.1.1 P 8080 r 2.2.2.2 p 8081 M 1 N 10 n 10 지정하면 TCPGW는들어오는채널에대해서는 1.1.1.1 IP 주소에 8080 포트로 10개의채널을연결하고, 나가는채널에대해서는 2.2.2.2 IP 주소에 8081 포트로 10개의채널을연결한다. 이와같이클라이언트로동작하는경우에리모트노드의 IP 주소를따로지정할수있다. r TCPGW 가클라이언트모드로동작할경우리모트노드의 IP 주소를지정하는옵션이다. 클라이언트모드에서백업기능및멀티서버채널정보설정을위해서다음과같이문법 이강화되었다. -r mainaddr[:mainport][/backupaddr[:backupport]][(type)][,...]mainaddr, backupaddr은 IP 주소이며, mainport, backupport는포트번호이다. type은 I(IN CHANNEL), O(OUT CHANNEL), A(ANY CHANNEL) 로설정할수있다. - I(IN CHANNEL): IN CHANNEL이 -N 옵션으로지정된수만큼생성된다. - O(OUT CHANNEL) : OUT CHANNEL이 -n 옵션으로지정된수만큼생성된다. 제 3 장환경설정 17
옵션 설명 - A(ANY CHANNEL) : IN CHANNEL 이 -N 옵션, OUTCHANNEL 이 -n 옵션으로지정된 수만큼생성된다. P 서버모드인경우에는 Listen 하고자하는포트번호이다. 해당포트번호는다른프로세스 에서사용하지않은포트번호여야한다. 클라이언트모드인경우에는 -R 옵션에서설명한것처럼클라이언트포트번호로도사 용할수있다. p M 리모트노드가 Listen 하고있는포트번호를설정한다. 해당포트번호는다른프로세스에 서 Listen 하지않은포트번호이어야한다. 서버모드로입력한 IP 주소와포트번호를클라이언트모드로바꾸는옵션이다. -R P 옵션으로입력한값은서버모드의 IP 주소와포트번호인데, 이를리모트노드에연결하고자하는리모트노드의 IP 주소와포트번호로바뀌도록하는옵션이다. -M 0 의미는기본적인 TCPGW의모드값이다. 그러나 -M 1 로하면서버모드에서클라이언트모드로변경된다. ( 기본값 : 0) m TCPGW 와통신하는리모트노드의코드체계가다를경우에데이터를변환하는옵션이 다. 송수신데이터를 ASCII EBCDIC, 조합형한글완성형한글로변환한다. 옵션을사용 할경우에사용자는송수신데이터의 map 파일을등록해야한다. 코드변환에대해서는아래의설명을참고한다.( 기본값 : 변환하지않음 ) N n k 리모트노드에서 TCPGW로들어오는채널수를지정하는옵션이다. 서버모드나클라이언트모드에관계없이사용하는옵션이다. TCPGW에서리모트노드로나가는채널수를지정하는옵션이다. TCPGW가클라이언트로동작하는경우에만의미가있다. 사용자가공유메모리를확보하여위에서설명한 -N n 으로주어진채널의상태를사용자가저장할수있도록공유메모리의키값을입력하는옵션이다. TCPGW는이옵션으로미리공유메모리를확보하지않고전적으로사용자에게전달하여사용자가임의로사용하도록전달하는역할만한다. 보통이옵션은 TCPGW가최초실행시사용자 Routine(init_remote_info) 를호출할때넘겨주어서사용자가공유메모리를확보하는데사용한다. F 특수용도록사용하는옵션으로 CLOPT 항목의옵션으로위에서설명한 IP 주소나포트 번호를입력하지않고 Config 파일에등록하여사용하는옵션이다. 특수용도로사용함으로일반사용자는사용할수없다. f TCPGW 를클라이언트로사용하는경우에사용하는옵션으로 " r p" 옵션이하나의리 모트노드의 ip 와연결하는것이라면 " f " 옵션은여러리모트노드와의연결을맺기위한 옵션이다. 이경우에연결하고자하는리모트정보를별도의파일에등록하고 f 옵션을 18 Tmax Gateway Guide (TCP/IP)
옵션 설명 사용하여해당파일명을지정하면 TCPGW는해당파일의정보를로드하여리모트노드와연결한다. " r", " p" 옵션과함께사용할수없으며또한 TCPGW를서버로사용하는경우에는사용할수없다. 단지클라이언트모드에서만사용가능하다. 그리고매요청시마다리모트노드에연결하는 " E " 옵션도사용할수없다. " f " 옵션을사용하면리모트노드와항상연결을맺고있어야한다. C TCPGW가클라이언트모드로동작하면서동시에같은 TCPGW 프로세스가 2개이상 (MIN=2) 실행시리모트노드와연결하는포트번호를지정하는옵션이다. 옵션을지정하면 TCPGW는 -p 으로지정한포트번호에서버번호를더한포트번호로리모트노드에연결을시도한다. 예를들어 -p 8080 C 옵션을사용하고 MIN=3 으로했을경우첫번째 TCPGW 프로세 스는 8080 포트번호를, 두번째 TCPGW 프로세스는 8081 포트번호를, 세번째는 8082 포 트번호를사용한다. c 리모트노드와통신시 TCPGW 로들어오는채널과나가는채널을분리하여사용하고자 하는경우에사용한다. 또는요청이 Tmax 에서리모트노드로발생할경우에만의미가있 다. TCPGW는옵션이지정되면 Tmax에서들어온요청을나가는채널로전송한다. 그리고리모트노드로부터나가는채널로데이터가수신되면이를이전에전송한데이터의 ACK 응답으로처리하고, 요청에대한응답은들어오는채널로수신한다. 즉, TCPGW와리모트노드사이에요청한데이터에대해서잘받았다는 ACK 정보를주고받고자하는경우에사용하는옵션이다. 반대로요청에대한 ACK는보내지않는다. S NON 블록킹모드로 TCPGW 를사용하거나또는비동기방식으로사용하고자할때 TCPGW 가요청할서비스명을등록하는옵션이다. NON 블록킹모드로사용할때 Tmax의송신서비스는 TCPGW로 tpforward하고, 리모트노드에서수신한응답을 TCPGW는수신서비스에게 tprelay하기위해서 relay될서비스명을등록한다. 또한, 비동기통신방식에서 Tmax 클라이언트나서비스는 TCPGW로서비스를요청 (tpacall with TPNOREPLY) 하고끝난다. 이후에리모트노드에서수신받은응답은일반적으로는 TPNOREPLY 로호출했으므로데이터를버리게되는데, 서비스명을지정하면 TCPGW는지정한서비스에 tpacall로응답데이터를전달한다. 옵션으로지정한서비스는반드시등록되어있는서비스명이어야한다. H Tmax 클라이언트나서비스와 TCPGW 사이에사용자정보데이터를주고받고자하는경우에사용한다. 옵션으로지정한데이터는리모트노드로전송하지않고임시 TCPGW 에서보관하였다가응답이수신되면사용자정보데이터에응답데이터를붙여서호출한서비스에게전달하고자하는경우에사용하다. 제 3 장환경설정 19
옵션 설명 보통 NON 블록킹모드로사용할때, 송신서비스와수신서비스가분리되어있어송신 서비스에서수신서비스에게데이터를전달하고자하는경우에많이사용한다. ( 기본값 : 0) h d 위의 -H 옵션과동일한옵션이다. 위의옵션은동기방식이나비동기방식모두에적용하는옵션인데반해단지 tpforward에 tprelay로사용하는호출에대해서만적용된다. ( 기본값 : 0) 리모트노드에서 Tmax의서비스를호출하고응답데이터를리모트노드에전송시전송하는채널을선택하는방법을지정하는옵션이다. 옵션을지정하면리모트노드에서요청한응답은반드시요청한채널에전송하게된다. 옵션을지정하지않으면리모트노드와연결된채널중임의의사용가능한채널을선택하여전송한다. 추후확장을위하여임의의값을설정해주어야한다. 예를들어 -d 0 와같이사용하며, 현재설정된값은무시된다. E a u TCPGW가클라이언트모드로동작시매요청마다채널을연결하고해제하고자하는경우에사용한다. 옵션을사용하면리모트노드와의연결된채널이없기때문에리모트노드에서먼저서비스를요청할수없다. 또한이옵션을사용하면매번채널이연결되고해제되므로처리속도가감소된다.OUTBOUND 요청에의한연결시도실패의경우 -X OUTBOUND_REQ 옵션을사용시 outmsg_recovery가호출되고 TPESYSTEM 에러가리턴된다. TCPGW를비동기통신방식으로사용하고자할때사용하는옵션이다. 위에서설명한것처럼비동기통신방식은서비스를요청하고종료하는형태이다. 서비스에대한응답도 TCPGW는다른서비스에대한요청으로간주한다. Tmax 클라이언트나서비스에 TCPGW로리모트노드에서비스를요청할때사용자가채널을지정할수있도록사용하는옵션이다. 옵션을사용하기위해서는사용자는 -k 옵션을사용하여채널에대한상태정보를보관하고있어야한다. 사용자가지정한채널이사용할수없으면 TCPGW 는에러를반환한다. w 리모트노드와 TCPGW 사이의통신시둘사이에는많은통신장비나또는방어벽이있을 수있다. 이경우에특정장비나방어벽에둘사이의채널이일정시간동안사용하지않 으면일방적으로채널을끊을수있다. 채널이끊어진경우보통은 TCPGW나리모트노드의프로세스에서이를감지하여채널을다시연결할수있으나, 끊어진것을감지하지못하는경우가종종발생한다. 이를위해서 TCPGW에서이옵션으로지정한시간 ( 초 ) 동안해당채널이사용되지않으면무조건채널을끊고다시연결을맺도록설정하고자하는경우에사용하는옵션이다. Y 리모트노드에서 Tmax 의서비스를요청한이후에서비스는정상적으로처리되었으나 결과를리모트노드에전송할수없는경우, 이전에처리한서비스에대해서취소처리를 할수있도록복구서비스를지정하는옵션이다. 20 Tmax Gateway Guide (TCP/IP)
옵션 설명 리모트노드에서 Tmax의서비스를호출한이후에리모트노드와때세션이모두끊어지면서비스처리결과는리모트노드로전송하지않고버려지게된다. 이경우에서비스는정상처리하였으나리모트노드입장에서는오류로보기때문에문제가발생할수있다. 사용자가이옵션에서비스명을지정하면게이트웨이는리모트로결과를전송할수없는경우에리모트노드로전송할데이터를지정한서비스로호출하게된다. t TCPGW가클라이언트모드로동작하는경우에 TCPGW는먼저리모트노드와연결을맺게되는데리모트노드와맺어진연결이끊어지거나또는연결이맺어지지않는경우에옵션을설정해주지않으면일정시간 (3초) 이나서비스요청이오는경우에다시연결을맺게된다. 이럴경우잦은리모트노드와의연결시도때문에시스템에부하가발생하게된다. 해결하기위해리모트노드와의연결을시도하는시간간격 ( 초 ) 을정해준후 " t " 옵션으 로시간을지정해주면 TCPGW 는이시간간격으로리모트노드와의연결을시도하게 된다. i x 리모트노드로부터데이터를수신할때데이터의끝을나타내는특정문자혹은비트스트림이존재할경우에필요한옵션이다. 옵션을지정하면데이터수신시사용자의 chk_end_msg 가호출된다. 채널장애여부감지 (TCP 레벨의 PING/PONG) 기능을활성화시킨다. - 인자로 0을줄경우 (-x 0): 메인채널장애복구가감지되면바로메인채널로전환된다. - 인자로 1을줄경우 (-x 1): 메인채널장애복구가감지되더라도안전한시점 ( 채널비사용시 ) 에메인채널로전환된다. ( 기본값 : 0) 옵션은 set_ping_msg 및 chk_pong_msg 함수와함께사용된다. y UID 로활용될수있는메시지번호 (sequence number) 의최대값을설정하는옵션이다. 기본값은 50000 이며최대 268435455 까지지정가능하다. -y 옵션으로지정된값보다 +1 되어적용된다. 따라서디폴트는 1~500001 까지발번됨. 3.1.2. 서버 / 클라이언트 TCPGW 의환경파일 서버 / 클라이언트 TCPGW 의환경설정은아래와같다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, 제 3 장환경설정 21
MIN=1, MAX=1, CPC=10, SVRTYPE=CUSTOM_GATEWAY, # 클라이언트 TCPGW의경우 1 CLOPT="-- -r 168.126.185.131 -p 5050 -n 5 -k 71673 " # 서버 TCPGW의경우 2 #CLOPT="-- -P 5050 -N 5 -k 71673" *SERVICE TESTTCPGW SVRNAME=testtcpgw 위와같이환경파일을작성한경우 testtcpgw라는이름의 TCPGW는 1개가 Tmax boot시에기동된다. testtcpgw의서비스명은 TESTTCPGW이고 Timeout 값은설정되어있지않으므로무한대기한다. 1은 TCPGW는클라이언트로리모트노드의 IP주소는 168.126.185.131이고, 리모트노드의 Listen 포트번호는 5050이된다. testtcpgw는기동시에리모트노드와 5개의연결을맺는다. 2의환경설정은서버로동작하는것으로서 Listen 포트번호는 5050이고리모트노드와 testtcpgw는 5개의연결을맺게된다. "-k " 옵션으로지정한값은 custom.c의함수 (init_remote_info()) 의인자로전달되어사용자가저장해야할내용등을이 key를이용하여공유메모리에저장할수있다. 3.1.3. 서비스블록형 TCPGW 의환경파일 TCPGW 는일단리모트노드와연결이이루어진이후에는서버 / 클라이언트의미가없이동기형 / 비동기형 모두사용할수있으므로여기서는서버 / 클라이언트모드를별도로설명하지않는다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=10, SVRTYPE=CUSTOM_GATEWAY, # 클라이언트 TCPGW의경우 CLOPT="-- -r 168.126.185.131 -p 5050 -n 5 -k 71673 -d 0" # 서버 TCPGW의경우 #CLOPT="-- -P 5050 -N 5 -k 71673 d 0" 22 Tmax Gateway Guide (TCP/IP)
*SERVICE TESTTCPGW SVRNAME=testtcpgw, SVCTIME=30 위와같이환경파일을작성한경우 testtcpgw라는이름의 TCPGW는 1개가 Tmax boot시에기동된다. testtcpgw의서비스명은 TESTTCPGW이고 Timeout 30초이므로 30초이내에응답이없으면 Timeout을반환한다. Timeout은 Tmax의클라이언트나서비스에서리모트노드로요청한것에대해서만 Timeout을체크하고, 리모트노드에서요청한서비스에대해서는요청한해당서비스에서 Timeout을설정해야한다. Tmax의클라이언트나서버에서리모트노드에서비스요청시 TCPGW는 UID를사용한다. UID는메시지별유일한값으로써요청에대한응답시반드시 TCPGW에넘겨주어야해당서비스를요청한서비스나클라이언트에게돌려주게된다. 리모트노드에서서비스요청시 TCPGW는요청에대한응답을요청한채널에전송한다. 단, 요청한채널이끊어진경우에데이터는소멸된다. 3.1.4. 서비스 NON- 블록형 TCPGW 의환경파일 TCPGW는일반적으로 Tmax의서비스에서리모트노드로서비스를요청하는경우에주로사용하며일반 Tmax 클라이언트에서는직접이방식으로서비스를호출할수없다. Tmax 클라이언트에서직접사용할수있는방식은블록형방식이나비동기방식만사용가능하다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw sendsvr secvsvr SVGNAME=svg1, MIN=1, MAX=1, CPC=5, SVRTYPE=CUSTOM_GATEWAY, # 클라이언트 TCPGW의경우 CLOPT="-- -r 168.126.185.131 -p 5050 -n 5 -k 71673 -S RECVSVC -H 20 -d 0" # 서버 TCPGW의경우 #CLOPT="-- -P 5050 -N 5 -k 71673 -S RECVSVC -H 20 d 0" MIN=1, MAX=1 MIN=1, MAX=1 *SERVICE TESTTCPGW SVRNAME=testtcpgw, SVCTIME=30 제 3 장환경설정 23
SENDSVC RECVSVC SVRNAME=sendsvr SVRNAME=recvsvr 위와같이환경파일을작성한경우 testtcpgw라는이름의 TCPGW는 1개가 Tmax boot시에기동된다. testtcpgw의서비스명은 TESTTCPGW이고 Timeout 이 30초이므로 30초이내에응답이없으면 Timeout 을반환한다. Tmax의클라이언트나서버에서먼저 SENDSVC 서비스를호출하면 SENDSVC에서사전작업을수행한후에 TESTTCPGW 서비스로컨트롤을넘긴다.(tpforward) TCPGW는일단 Tmax 엔진에채널해제메시지를전송한후에리모트노드로서비스를요청하고, 서비스에응답을수신시 -S 옵션에지정한서비스로결과를전달 (tprelay) 한다. RECVSVC는처리결과에대한작업을수행후반환하면원래 SENDSVC를호출한클라이언트나서비스에게로응답이전달된다. 이방식을사용하면적은수의서비스 (SENDSVC) 를가지고보다많은처리를할수있다. 블록형처럼반드시 UID는사용해야한다. 리모트노드의응답이지정한시간 (30초) 을초과하면 TCPGW는 Timeout을 RECVSVC에전달 (tprelay) 한다. RECVSVC 서비스에서는반드시 tpurcode값을확인하여값이 0보다크면에러가발생한경우이므로이에대한적절한처리를해야한다. Timeout 뿐만아니라모든에러에대해서는 tpurcode에값이전달되며, 에러에대한자세한사항은 Ap pendix B. TCPGW 에러코드 를참고한다. 3.1.5. 리모트동기형과비동기형 TCPGW 환경파일 리모트노드에서요청하는서비스에대한동기형비동기형구분은 -d 옵션을사용하느냐에따라서결정되거나, 또는사용자정의함수 (get_msg_info) 에서 flags에 TPNOREPLY 를설정하면된다. 전자의경우 -d 옵션을사용하지않으면서비스에대한응답은다른채널로전송될수있다. 후자인경우에는리모트노드로응답을전송하지않는다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=5, SVRTYPE=CUSTOM_GATEWAY, # 비동기형 CLOPT=" -- -P 5050 -N 5 -k 71673" # 동기형 #CLOPT="-- -P 5050 -N 5 -k 71673 d 0" 24 Tmax Gateway Guide (TCP/IP)
*SERVICE TESTTCPGW SVRNAME=testtcpgw -d 옵션을지정하였을경우에도사용자정의함수 (get_msg_info) 에서 flags에 TPNOREPLY 를설정하면서비스응답은리모트노드에전송되지않는다. 리모트노드에서 Tmax의서비스요청시 TCPGW는 tpacall을사용함으로응답을받지않고동시에 tpacall 을사용할수있는개수가제한되어있다.( 기본값 8개 ) 동시에요청이 8개이상인경우에는 *DOMAIN 절에 MAXSACALL 개수를적당하게지정해야한다. 3.1.6. 재연결 TCPGW 환경파일 보통리모트노드와통신시두채널사이에는복잡한통신장비를거쳐서통신이이루어지거나또는방어벽을사이에두는경우가많다. 이러한경우에둘사이의채널이일정시간동안사용하지않으면통신장비나또는방어벽에서해당채널을끊어서둘사이에통신이이루어지지않는경우가발생한다. 이를방지하기위해둘사이에일정간격으로 signal를주고받을수도있으나이를위해서는 TCPGW 뿐만아니라상대방의프로그램을감안해야하기때문에이방법을사용하지않고일정시간동안해당채널을사용하지않으면채널을끊고다시연결하는방법을사용한다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=5, SVRTYPE=CUSTOM_GATEWAY, # 비동기형 CLOPT=" -- -P 5050 -N 5 -k 71673 -w 600" # 동기형 #CLOPT="-- -P 5050 -N 5 -k 71673 -w 600" *SERVICE TESTTCPGW SVRNAME=testtcpgw 위와같이설정하면 TCPGW 는 600 초 (10 분 ) 간격으로 600 초동안한번도사용하지않은채널은연결을 끊고다시연결을맺는다. 제 3 장환경설정 25
3.1.7. 여러리모트노드와연결을맺는클라이언트 TCPGW 여러노드의 IP 와연결을맺는클라이언트 TCPGW 의환경설정은아래와같다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=10, SVRTYPE=CUSTOM_GATEWAY, CLOPT="-- -f config -n 5 -k 71673 " *SERVICE TESTTCPGW SVRNAME=testtcpgw *config 파일 # tcpgw_no ip_addr port_no in_channel out_channel 0 192.168.1.1 7717 5 5 1 192.168.1.2 7727 5 5 2 192.168.1.3 7737 5 5 3 192.168.1.4 7747 5 5 config 파일의각항목에대한설명은아래와같다. tcpgw_no ip_addr port_no in_channel out_channel TCPGW process number. 0부터시작함 remote hostname or ip address remote port number input channel number output channel number 3.2. 사용자헤더환경설정및사용방법 TCPGW는서버 / 클라이언트모드, 동기형 / 비동기형방식모두에서사용자헤더를설정하여사용할수있다. 사용자헤더는 Tmax 클라이언트나서비스에서리모트노드로서비스를요청하는경우에만사용가능하고, 그반대인경우에는사용할수없다. 사용자헤더로지정한데이터는리모트노드로전송되지않고임시 TCPGW에서 UID 별로보관하였다가응답이오면응답데이터에서 UID를찿아서해당 UID의사용자헤더데이터와응답데이터를전달하게된다. 사용자헤더데이터의길이는최대 (256 Bytes) 까지만사용할수있다. 26 Tmax Gateway Guide (TCP/IP)
3.2.1. 사용자헤더환경파일 사용자헤더는어떤모드에서도사용할수있는옵션이다. 사용자헤더는두가지로나누어서지정할수있는데, tpforward 방식으로사용할때 (NON 블록킹 ) 와그외의다른서비스 ( 블록형, 비동기형 ) 를사용하는경우사용자헤더길이를다르게지정할수있다. *DOMAIN... *NODE... *SVRGROUP... *SERVER testtcpgw SVGNAME=svg1, MIN=1, MAX=1, CPC=10, SVRTYPE=CUSTOM_GATEWAY, # 클라이언트 TCPGW의경우 CLOPT="-- -r 168.126.185.131 -p 5050 -n 5 -H 9 -h 10" # 서버 TCPGW의경우 2 #CLOPT="-- -P 5050 -N 5 -H 9 -h 10" *SERVICE TESTTCPGW SVRNAME=testtcpgw -H 옵션은모든종류의서비스요청에대해서사용자헤더를지정할때사용하는옵션이다. 그에반해 - h 옵션은단지 tpforward 방식 (NON 블록킹 ) 에서만사용할수있는옵션이다. TCPGW는사용자헤더가지정되었을경우리모트노드로전송하는데이터중에서처음부터일반서비스는 9 Bytes, tpforward 인경우에는 10 Bytes를보관하고나머지데이터만리모트노드에전송한다.( 위의 config인경우 ) 리모트노드로부터응답을수신받으면보관되어있는사용자헤더와응답데이터를붙여서반환한다. 3.2.2. 사용자헤더사용방법 사용자헤더는여러가지방법으로사용할수있다. 사용자헤더는사용자가임의로사용할수있는데이터이므로여기서는여러사이트에서사용하는일반적인방법을설명한다. tprelay나비동기서비스명지정사용자헤더에 NON 블록형방식으로사용할경우 tprelay될서비스를지정할수있다. 이경우에 -S 옵션으로지정한것보다우선한다. 사용자헤더에도서비스를지정하고, -S 옵션으로서비스를지정하였을경우 TCPGW는먼저사용자헤더에서사용자함수 (get_service_name) 를호출하여서비스를찾고, 서비스를찾지못한경우 -S 옵션으로지정한서비스를사용한다. 제 3 장환경설정 27
비동기형방식 (tpacall 에 TPNOREPLAY) 으로호출하였을경우에도응답데이터에대해서위와동일하 게처리한다. Key 데이터보관 NON 블록킹모드로사용할경우송신과수신서비스로분리되는데송신서비스에서데이터베이스에적절한작업을처리하고리모트노드로데이터를전송하고송신서비스는종료된다. 나중에수신서비스에서송신서비스에서처리한데이터베이스의 Key 정보를알고자하는경우나, 또는수신서비스에리모트노드에서오류가발생한경우데이터베이스를되돌려놓기위한중요한데이터를보관하고자하는경우에많이사용한다. 3.3. E 옵션사용시채널백업설정 "-E" 옵션을사용하여매요청시마다채널을연결하고해제할수있다. 이런경우에도백업채널을지정할수있다. CLOPT 항목에 "-r " 옵션을사용하여메인서버및백업서버의주소와포트번호를지정하여백업채널을설정한다. 환경설정은다음과같다. SERVER 이름 CLOPT=literal ㅇ CLOPT 의사용법은다음과같다. CLOPT= -- -r [ip]:[port]/[backup ip]:[backup port] E NODE 절에 CRYPTPORT 를지정할경우, CRYPTPORT 에지정된포트로접속한클라이언트의데이터 만이암호화된다. 3.4. Ping 메시지체크시데이터전송 set_ping_msg() 함수와 chk_pong_msg() 함수를사용하여 PING 메시지를전송하여채널의장애여부를주기적으로감시할수있다. 이경우에 Ping 메시지는헤더만있기때문에데이터부분을전송할수없다. 다음과같이 CLOPT 항목에 -r 옵션을설정하여 Ping 메시지의데이터를추가하여전송할수있다. 환경설정은다음과같다. [DEFAULT :] SERVER 이름 [,CLOPT = -b] CLOPT 의사용법은다음과같다. CLOPT = -- -r 192.168.1.31 p 5060 n 1 x 1 b 64 선택항목 CLOPT = -b len 28 Tmax Gateway Guide (TCP/IP)
PING 메시지데이터의최대크기를지정한다. set_ping_msg(), chk_pong_msg() 함수대신에 set_extping_msg,() chk_extpong_msg(), reset_extping_msg() 함수를사용한다. 이함수들에대한자세한설명은 4.2. custom.c 수정 을참고한다. 제 3 장환경설정 29
제 4 장사용자프로그램 Tmax의환경을설정하여 TCPGW를등록한후에 TCPGW를사용하기위해해야할일은 custom.h, custom.c 를수정하는일이다. custom.h에서해야할일은 msg_header_t 구조체를 TCPGW를사용하고자하는목적에맞게수정하는일이다. TCP/IP는데이터의끝을알수가없으므로언제데이터수신을종료해야할지모르기때문에가변길이의데이터를처리하기가곤란하다. 그래서 TCPGW는 msg_header_t 구조체를사용하여리모트노드와메시지헤더를설정하여실데이터의길이를구할수있는구조로되어있다. 구조체의정보는 TCPGW 와리모트노드사이에메시지헤더를지정하는구조체이므로해당리모트노드와통신시사용하는메시지헤더를등록해준다. TCPGW는리모트노드로부터데이터를수신할때먼저 msg_header_t의길이만큼데이터를수신받고 msg_header_t의구조체에서실데이터의길이를얻은후에실데이터를수신받는다. msg_header_t는정확하게등록해야만둘사이의통신이원활히이루어진다. 주의 사용자가정의한 msg_header_t 의정보는 TCPGW 와리모트노드의통신에서만사용하고서비스호 출시에는전달되지않는다. custom.h를수정한이후에는 custom.c를적절하게수정해야한다. custom.c에는여러가지사용자정의함수가있는데각각에대해서는아래설명을참고한다. 수정한 custom.h, custom.c와 TCPGW 라이브러리및 register.c를링크하여컴파일하면 TCPGW 가완성된다. 이때생성된실행파일명은 Tmax 환경파일의 SERVER 절에등록된이름과동일해야한다. 4.1. custom.h 수정 custom.h는 TCPGW에서사용되는 msg_info_t 구조체를포함하는파일로서사용자가리모트노드와 TCPGW간에통신해야할기타메시지구조체나헤더들을수정할수있다. 그러나 msg_info_t 구조체는 TCPGW 라이브러리내부와사용자함수사이에사용하므로멤버변수나타입, 길이등을수정해서는안된다. TCPGW에서사용되는 msg_info_t 구조체는다음과같다. typedef struct msg_info char svc[20]; int err; int len; int uid; 제 4 장사용자프로그램 31
int flags; /* flags를설정한다. (TPNOREPLY등) */ int msgtype; int channel_id; msg_info_t; 구조체는 TCPGW 라이브러리내부와사용자가수정해야하는 custom.c 파일의함수에서사용된다. cus tom.c 파일에서는리모트노드로부터메시지를수신한직후불리우는 get_msg_info() 함수에서이구조체에값을적절히설정을해야한다. 또한리모트노드로메시지를송신하기직전에불리우는함수인 put_msg_info() 함수에서구조체의값으로리모트노드로송신한데이터를구성해야한다. get_msg_info() 와 put_msg_info() 의수정사항에대한좀더자세한내용은 4.2. custom.c 수정 에서설명하도록한다. custom.h에는리모트노드와 TCPGW사이에서메시지헤더데이터구조를정의해주어야한다. TCPGW 에서일반적으로사용되는메시지헤더 (msg_header_t) 구조체는다음과같다 typedef struct msg_header int length; msg_header_t; 4.2. custom.c 수정 custom.c는개발자가리모트노드와 TCPGW가통신하기위해구현해야하는것으로 TCPGW 라이브러리 (libtcpgw.a, libtcpgw.so) 와함께컴파일해서사용해야한다. custom.c는정의된형식에맞게구현해야하며그형식은다음과같다. custom.c에는아래와같은변수를정의해주어야한다. 변수명 : msg_header_size 변수는라이브러리내부에서사용자가정의한메시지헤더의사이즈로인식되어사용된다. 따라서이변수는아래의사용법처럼사용자정의메시지헤더사이즈로설정해주어야한다. 사용법 int msg_header_size = sizeof(msg_header_t); 변수명 : comm_header_size msg_header_size가 0으로설정된경우이변수가 msg_header_size와같은용도로쓰이게된다. msg_header_size변수와함께정의가된경우는 msg_header_size값을사용하게된다. 사용법 int comm_header_size = 0; 또한 custom.c 에는아래와같은함수를구현해주어야한다. 32 Tmax Gateway Guide (TCP/IP)
init_remote_info 리모트노드와연결을맺기에앞서호출되는함수이다. TCPGW가자신의초기화작업을마친후에곧바로호출되는함수이며한번만호출된다. Tmax 환경파일의 CLOPT 절에 " k " 옵션으로공유메모리키를설정한경우연결에대한정보등을저장하기위해공유메모리를생성하는로직을구현할수있다. 경우에따라내부로직을구현하지않아도된다. 사용법 int init_remote_info(char *myname, int mynumber, int num_channel, int key) 파라미터 파라미터 myname mynumber num_channel key 설명 TCPGW 서버명이다. 같은 TCPGW가동시에여러개실행될경우에각각의프로세스를구분할수있는 TCPGW 프로세스번호이다. 0 부터시작한다. TCPGW가연결하고있는 max 채널수이다. Tmax 환경파일에 "-n", "-N " 옵션으로설정한값의합이다. Tmax 환경파일에서 " k " 옵션으로설정한공유메모리키값이다. remote_connected 리모트노드와연결을맺은후호출되는함수이다. 리모트노드와연결을맺은후해야할작업이있다면함수에서하도록한다. 채널수만큼호출된다. 또한도중에채널이해제되었다가다시연결될때도호출된다. 사용법 int remote_connected(int index, int addr, int type, int fd) 파라미터 파라미터 index addr type fd 설명 TCPGW가 "-n" 또는 "-N" 옵션으로여러개의채널을연결하고있는경우각각의채널에대한자신의 index값이다. 리모트노드의주소이다. 리모트노드와연결된채널타입이다. IN_CHANNEL 또는 OUT_CHANNEL 인지를나타낸다. 리모트노드와연결된소켓번호이다. 제 4 장사용자프로그램 33
remote_closed 리모트노드와연결을종료한후호출되는함수이다. 리모트노드와연결이끊어진후에해야할작업이있다면함수에서하도록한다. init_remote_info 함수에서 shared memory를생성하는로직을구현한경우이함수에서해제하는작업로직을구현한다. 채널수만큼호출된다. 사용법 int remote_closed(int index, int type) 파라미터 파라미터 index type 설명 TCPGW가 "-n" 또는 " -N" 옵션으로여러개의채널을연결하고있는경우각각의채널에대한자신의 index 값이다. 리모트노드와연결된채널타입이다. IN_CHANNEL 또는 OUT_CHANNEL 인지를나타낸다. get_msg_length 리모트노드로부터요청이나응답이도착하여, 해당채널에서 msg_header_t 부분만을 recv(msg_head er_size또는 comm_header_size에서지정한값만큼을읽는다.) 한후호출하는함수로반환된값만큼, 실데이터를다시 read하게된다. 사용법 int get_msg_length(msg_header_t *hp) 파라미터 파라미터 hp 설명개발자가 custom.h에정의할수있는 msg_header_t 구조체의포인터이다. 일반적으로, 해당채널로부터데이터를읽는경우, 정해진헤더의크기만큼데이터를읽은후에헤더에설정되어있는데이터길이값을얻어서이를바탕으로다음실데이터를읽을수있도록되어있다. hp는 TCPGW가리모트노드로부터읽은헤더데이터를넘겨준다. 반환값 리모트노드로부터실데이터의길이를반환한다. 함수의반환값으로 TCPGW 는실데이터를리모트 노드에서읽게된다. 34 Tmax Gateway Guide (TCP/IP)
get_msg_info 리모트노드으로부터요청이나응답이도착하여데이터를읽은후데이터를 Tmax 서비스프로그램으로다시요청이나응답를전송하기전에해당데이터값을가공하거나, 정보전송을위한여러정보 (uid, len, flags, service명등 ) 들을 TCP/IP 게이트웨이라이브러리와 custom.c와의인터페이스역할을하는 info를참조또는가공하는함수이다. 사용법 int get_msg_info(msg_header_t *hp, char *data,msg_info_t *info) 파라미터 파라미터 hp data info 설명리모트노드로부터읽어온메시지헤더데이터대한포인터이다. get_msg_length에서사용한구조체와동일하다. 리모트노드로부터읽은데이터부분이다. TCP/IP 게이트웨이라이브러리 (libtcpgw.a, libtcpgw.so) 와 custom.c와인터페이스역할을해주는구조체구조이다. 사용자가수신받은데이터를기초로해서 info 구조체의항목에각종정보를함수에서설정한다. 반환값 Tmax 서비스로보낼 type을정의한다. TCPGW는값을바탕으로 Tmax로어떤처리를할것인지를판단한다. 예를들어, REMOTE_REQUEST는리모트노드로부터 Request가발생한것으로판단하며, REMOTE_REPLY는 Tmax 서비스로부터 Request가발생하여리모트노드로부터 Response가오는경우반환하는값이다. REMOTE_REPLY_CONT는 Response 메시지가이어서올경우반환하는값이며, REMOTE_SENDTOCLI는비요청메시지일경우반환하는값이다. 리모트노드로부터응답을수신한경우에는반드시 UID 값을 info 구조체의 uid 항목에지정해주어야한다. 기타다른값들은상황에맞게주어야한다. get_channel_num Tmax 서비스나클라이언트로부터요청한데이터를리모트노드에전송할때사용자가채널을선택할수있도록하는함수이다. 사용자는주어진데이터의특성에따라서전송할채널을지정할수있다. 단여기서지정하는것은리모트노드와연결된소켓번호가아니라단순한채널번호이다. TCPGW는사용자가지정한채널을사용할수없으면오류를반환한다. 사용법 int get_channel_num(char *data) 제 4 장사용자프로그램 35
파라미터 파라미터 data 설명 리모트노드로보내기위한데이터이다. 반환값 채널번호를반환한다. put_msg_info 리모트노드로메시지를전송하고자할때호출되는함수이다. 동기형통신인경우에는사용자가함수에서 UID를메시지에 Save하여야한다. UID는 info 구조체의 uid 항목의값을사용해도되고, 또는사용자가임의의 UID를만들어서사용한후에 info의 uid 항목에넣어주면된다. 사용자는 msg_header_t의구조체의각각의항목에적절한값을저장해야한다. 구조체는사용자가임의로설정할수있는항목이기때문에 TCPGW에서는 msg_header_t의구조체항목에어떤값도저장하지않는다. 사용법 int put_msg_info(msg_header_t *hp, char *data, msg_info_t *info) 파라미터 파라미터 hp data info 설명리모트노드로보낼메시지의헤더이다. 리모트노드로보낼데이터이다. 리모트노드로보낼데이터의정보이다. 반환값 사용자는실제적으로리모트노드에전송할데이터의전체길이를반환해야한다. 메시지헤더와실데 이터를더한길이를반환한다. put_msg_complete 리모트노드로메시지를전송한후에호출되는함수이다. 데이터가완전히리모트노드에전송되었다는것을알려주기위해서호출되는함수이다. 사용법 36 Tmax Gateway Guide (TCP/IP)
int put_msg_complete(msg_header_t *hp, char *data, msg_info_t *info) 파라미터 파라미터 hp data info 설명리모트노드로보낸메시지의헤더이다. 리모트노드로보낸데이터이다. 리모트노드로보낸데이터의정보이다. get_service_name Tmax에서리모트노드로요청을보낼때요청을보내는서버와결과를받는서버를달리하는 NON 블록형이나비동기형 TCPGW를구성하는경우, tpreply() 나 tpacall() 을할서비스의이름을오류코드에따라서설정한다. 사용법 int get_service_name(char *header, int err, char *svc) 파라미터 파라미터 header err svc 설명 "-H" 또는 "-h" 옵션으로설정한, TCPGW에서저장하고있는사용자헤더의포인터이다. 오류코드이다. tpreply() 나 tpacall() 를받는서비스의이름을설정한다. prepare_shutdown TCPGW가종료하기직전에 call되는함수로서, 일반적으로 init_remote_info() 함수에서생성한공유메모리를해제하는일을한다. 사용법 int prepare_shutdown(int code) 파라미터 파라미터 code 설명 shutdown code 로서현재는사용되지않는다. 제 4 장사용자프로그램 37
set_service_timeout 서비스타임아웃이발생하였을경우사용자가호출할수있는함수이다. 사용법 int set_service_time_out(int uid, char *header) 파라미터 파라미터 uid header 설명 서비스타임아웃이발생한거래의 unique ID 이다. 서비스타임아웃이발생한거래의헤더이다. chk_end_msg 리모트노드로부터데이터를수신할때데이터의끝을나타내는특정문자혹은비트스트림이존재할경우사용자가호출할수있는함수이다. 사용법 int chk_end_msg(int len, char *data) 파라미터 파라미터 len data 설명 리모트노드로부터읽은데이터길이이다. 리모트노드로부터읽은데이터부분이다. inmsg_recovery 리모트노드로부터요청을 tpacall(..., TPBLOCK) 로처리했을경우서버가떠있지않으면에러가돌아오게되는데, 이러한때에호출된다. 사용자는함수내에서적당히새로운데이터를만들고, 데이터의크기를반환한다. 사용법 int inmsg_recovery(char *data, msg_info_t *info) 파라미터 38 Tmax Gateway Guide (TCP/IP)
파라미터 data info 설명 리모트노드로부터읽은데이터부분이다. 리모트노드로부터읽은데이터의정보이다. 의미있는값은다음과같다. - info->svc : tpacall() 했었던서비스이름 - info->len : tpacall() 한데이터길이 - info->err : 에러시 - tperrno info->uid : 이전 - get_msg_info() 시에생성되었던 UID 값 반환값사용자는새로운데이터의길이를반환해야한다. 데이터의길이가 0 보다클경우, info->svc 에값이존재하면해당서비스로 tpacall(..., TPNOREPLY) 하고, 그외에는리모트노드로응답을보낸다. 데이터의길이가음수일경우데이터를버린다. outmsg_recovery 리모트노드로요청을보낼때에러가발생할경우호출된다. 사용자는함수내에서적당히새로운데이터를만들고원하는서비스이름및 UID 등을설정하고, 데이터의크기를반환한다. 사용법 int inmsg_recovery(char *data, msg_info_t *info) 파라미터 파라미터 data info 설명 리모트노드로부터읽은데이터부분이다. 리모트노드로부터읽은데이터의정보이다. 의미있는값은다음과같다. - info->svc : tpacall() 했었던서비스이름 - info->len : tpacall() 한데이터길이 - info->err : 에러시 - tperrno info->uid : 이전 - get_msg_info() 시에생성되었던 UID 값 제 4 장사용자프로그램 39
반환값사용자는새로운데이터의길이를반환해야한다. 데이터의길이가 0 보다클경우, info->svc 에값이존재하면해당서비스로 tpacall(..., TPNOREPLY) 하고, 그외에는 info->msgtype 이 1000 이상이면데이터를버리고 info->msgtype 이 1000 미만이면데이터를 call 한쪽으로되돌려준다. get_extmsg_info get_msg_info와기본적으로기능은동일하다. 단, 데이터버퍼를더블포인터형으로넘겨서사용자가버퍼의메모리를재할당 (realloc) 할수있다. 함수는 get_msg_info와동시에사용될수없으며, 사용을위해서는 TCPGW 컴파일시 -D_TCPGW_USE_EXTMSG 플래그를설정해야한다. 사용법 int get_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info) 파라미터 파라미터 hp data asize info 설명리모트노드로부터읽어온메시지헤더데이터대한포인터이다. get_msg_length에서사용한구조체와동일하다. 리모트노드로부터읽은데이터버퍼의주소값이다. 리모트노드로부터읽은데이터버퍼에할당된메모리크기이다. TCP/IP 게이트웨이라이브러리 (libtcpgw.a, libtcpgw.so) 와 custom.c와인터페이스역할을해주는구조체구조이다. 사용자가수신받은데이터를기초로해서 info 구조체의항목에각종정보를설정한다. 반환값 Tmax 서비스로보낼 type을정의한다. TCPGW는값을바탕으로 Tmax로어떤처리를할것인지를판단한다. 예를들어, REMOTE_REQUEST는리모트노드로부터 Request가발생한것으로판단하며, REMOTE_REPLY는 Tmax 서비스로부터 Request가발생하여리모트노드로부터 Response가오는경우반환하는값이다. REMOTE_REPLY_CONT는 Response 메시지가이어서올경우반환하는값이며, REMOTE_SENDTOCLI는비요청메시지일경우반환하는값이다. 리모트노드로부터응답을수신한경우에는반드시 UID 값을 info 구조체의 uid 항목에지정해주어야한다. 그리고기타다른값들상황에맞게주어야한다. 40 Tmax Gateway Guide (TCP/IP)
put_extmsg_info put_msg_info와기본적으로기능은동일하다. 단, 데이터버퍼를더블포인터형으로넘겨서사용자가버퍼의메모리를재할당 (realloc) 할수있다. put_msg_info와동시에사용될수없으며, 사용을위해서는 TCPGW 컴파일시 -D_TCPGW_USE_EXTMSG 플래그를설정해야한다. 사용법 int put_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info) 파라미터 파라미터 hp data asize info 설명리모트노드로보낼메시지의헤더이다. 리모트노드로보낼데이터버퍼의주소값이다. 리모트노드로보낼데이터버퍼에할당된메모리크기이다. 리모트노드로보낼데이터의정보이다. 반환값 사용자는함수에서실제적으로리모트노드에전송할데이터의전체길이를반환해야한다. 메시지헤 더와실데이터를더한길이를반환한다. set_ping_msg 채널장애감시를위해서보내어질메시지설정및주기, 타임아웃등을설정할수있는사용자함수이다. " x" 옵션을지정할경우반드시설정해주어야한다. 사용법 int set_ping_msg(msg_header_t *hp, int *interval, int *binterval, int *timeout, int *mode) 파라미터 파라미터 hp interval binterval 설명채널장애감시를위해서주기적으로보내지는메시지이다. 사용자는이메시지를설정해야한다. 채널장애감시주기이다. ( 단위 : 초 ) 0일경우, 채널장애감지기능은비활성화된다. 백업채널모드일때, 메인채널의상태를체크주기이다. ( 단위 : 초 ) 0 일경우, 메인채널의상태체크기능은비활성화된다. 제 4 장사용자프로그램 41
파라미터 timeout mode 설명채널장애감시타임아웃이다. 타임아웃내에응답이오지않으면채널은끊어진다. ( 단위 : 초 ) 0 일경우, PING 메시지만보내고 PONG 메시지에대해서는신경쓰지않는다. (Half Duplex 장애감지 ) 장애감시할채널종류를지정한다. 0 은OUT 채널, 1 은 IN 채널, 2는모든채널을의미한다. 반환값 에러가발생할때음수값을반환해야하며, 이경우장애감시기능은비활성화된다. chk_pong_msg 채널장애감시응답메시지여부를체크하는사용자함수이다. 사용법 int chk_pong_msg(msg_header_t *hp) 파라미터 파라미터 hp 설명 리모트로부터수신된메시지이다. 반환값채널장애감시응답메시지이면서정상적일경우양수값을반환하며, 비정상적일경우음수값을반환한다. 채널장애감시응답메시지가아닐경우는 0을반환한다. 음수값을반환할경우, 채널은끊어진다. set_extping_msg 서버에채널장애감지시보낼메시지설정하는함수이다. 사용법 int set_extping_msg(msg_header_t *hp, char *data, int len, int *interval, int *binterval, int *timeout, int *mode) 파라미터 42 Tmax Gateway Guide (TCP/IP)
파라미터 hp data len interval binterval timeout mod 설명채널장애감지시보낼메시지헤더이다. 송신할메시지바디이다. 채널장애감지메시지바디의길이이다. 채널감지를위한간격설정값의포인터이다. 백업채널모드로동작중인경우, 메인채널감지를위한간격설정값의포인터, 0으로설정된경우메인채널감지를하지않는다. 초단위, 채널감지를위한제한시간이며이시간까지감지가안된다면함수를실패하게된다. 0인경우, OUTBOUND 채널감지 1인경우, INBOUND 채널감지 2인경우, OUTBOUND / INBOUND 채널을모두감지한다. 반환값 반환값 0 음수값 설명 함수수행성공일경우 함수수행실패일경우 예제 int set_extping_msg(msg_header_t *hp, char *data, int len, int *interval, int *binterval, int *timeout, int *mode) msg_body_t *body; body = (msg_body_t *)data; memset(body->data, 0x00, 52); memcpy(body->data, "tmax50", 7); body->data[51] = 0; printf("set_extping_msg : data = %s\n", body->data); hp->len = 7; *interval = 10; *binterval = 20; *timeout = 100; *mode = 0; /* OUTBOUND CHANNEL */ return 1; 제 4 장사용자프로그램 43
chk_extpong_msg 채널장애감지시서버로부터받은메시지확인하는함수이다. 사용법 int chk_extpong_msg(msg_header_t *hp, char *data, int len) 파라미터 파라미터 hp data len 설명채널장애감지시리모트서버로부터수신된메시지헤더이다. 채널장애감지시리모트서버로부터수신된메시지바디이다. 수신된메시지바디의길이이다. 반환값 반환값 0보다큰값음수값 0 설명함수수행성공일경우함수수행실패일경우 pong 메시지가없는경우 예제 int chk_extpong_msg(msg_header_t *hp, char *data, int len) msg_body_t *body; char data2[15]; body = (msg_body_t *)data; printf("chk_extpong_msg : data = %s\n", body->data); return 1; reset_extping_msg TCP/IP PING( 채널장애감지 ) 메시지의전송주기재설정을위하여주기적으로호출되는함수이다. 사용법 int reset_extping_msg(msg_header_t *hp, char *data, int len) 44 Tmax Gateway Guide (TCP/IP)
파라미터 파라미터 hp data len 설명채널장애감지를위해전송할메시지의헤더이다. 재설정할메시지바디이다. 재설정한메시지바디의길이이다 반환값 반환값 0 보다큰값 음수값 설명 함수수행성공일경우 함수수행실패일경우 예제 int reset_extping_msg(msg_header_t *hp, char *data, int len) hp->len = 10; data = "reset_msg"; printf("reset_extping_msg : data = %s\n", data); return 1; set_error_msg TCP/IP Gateway 를통한리모트노드와의거래도중에러가발생하였을경우 (ex 타임아웃혹은네트워크단절 ) 자동으로호출되는함수로해당함수내에서사용자는사용자헤더또는사용자데이터를수정할수있다 사용법 int set_error_msg(msg_header_t *hp, int err, char *data, int len) 파라미터 파라미터 hp data len 설명에러가발생했을경우전송된메세지의헤더로사용자가수정할수있다. 에러가발생했을경우전송된데이터로사용자가수정할수있다. 메시지바디의길이이다 제 4 장사용자프로그램 45
반환값 반환값반환값 > 0 반환값 = 0 반환값 < 0 설명리턴한길이만큼의데이터를전송. 단이경우 CLOPT="-I" 옵션을설정해야만적용됨사용자헤더부분까지만전송해당메세지를 CLH 로전송하지않음 오류 오류 TPECLOSE TPETIME TPEPROTO TPENOENT TPENOREADY TPEOS TPESYSTEM TPESVCERR 설명리모트노드로전송후응답을받기전에끊어짐리모트노드로전송후타임아웃발생 ASYNC 모드에서 tpforward API 를사용하는경우외클라이언트모드 / 연결을맺을경우 OUT 채널수의부족클라이언트모드 / 연결을맺을경우리모트노드가비정상동작메모리할당등의오류내부적오류 put_msg_info 에서 0 혹은음수를리턴 예제 int set_error_msg(msg_header_t *hp, int err, char *data, int len) msg_body_t * body; body = (msg_body_t *)data; strcpy(body->data, "changed hello data"); /* 에러메시지에는데이터가포함되지않으므로데이터부분까지전달되기위해서는 -I 옵션을사용해야한다. 사용하지않을시사용자헤더까지만 CLH로전달된다. */ /* 사용자헤더가없는경우에 hp와 data의값이같을수있다. */ strcpy(hp->retsvcname, "RECVSVC_CHANGE"); return len; 이절에서설명한함수들의사용예제는 제 4 장사용자프로그램 에서설명한다. 46 Tmax Gateway Guide (TCP/IP)
4.3. register.c 수정 사용자함수등록파일로서, 사용자가등록한함수들만게이트웨이라이브러리에서호출된다. 게이트웨이컴파일할때, 반드시 register.c를포함시켜야한다. 사용하지않는함수는 NULL 등록하면된다. register.c 예제는다음과같다. /* ------------- tcpgw register.c ------------- */ #include <stdio.h> #include "custom.h" extern int init_remote_info(char *myname, int mynumber, int num_channel, int key); extern int prepare_shutdown(int code); extern int remote_connected(int index, int addr, int portno, int type, int fd); extern int remote_closed(int index, int type); extern int get_msg_length(msg_header_t *hp); extern int get_msg_info(msg_header_t *hp, char *data, msg_info_t *info); extern int put_msg_info(msg_header_t *hp, char *data, msg_info_t *info); extern int put_msg_complete(msg_header_t *hp, char *data, msg_info_t *info); extern int get_channel_num(char *data); extern int get_service_name(char *header, int err, char *svc); extern int set_service_timeout(int uid, char *header); extern int get_msg_security(char **data, int asize, int len); extern int put_msg_security(char **data, int asize, int len); extern int chk_end_msg(int len, char *data); extern int get_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info); extern int put_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info); extern int inmsg_recovery(char *data, msg_info_t *info); extern int outmsg_recovery(char *data, msg_info_t *info); extern int set_ping_msg(msg_header_t *hp, int *interval, int *bintrval, int *timeout, int *mode); extern int chk_pong_msg(msg_header_t *hp); extern int set_extping_msg(msg_header_t *hp, char *data, int len, int *interval, int *bintrval, int *timeout, int *mode); extern int chk_extpong_msg(msg_header_t *hp, char *data, int len); /*************************************************************** * int * _register_custom() * * returns no used * [function number] * 1. init_remote_info * 2. prepare_shutdown * 3. remote_connected 제 4 장사용자프로그램 47
* 4. remote_closed * 5. get_msg_length * 6. get_msg_info * 7. put_msg_info * 8. put_msg_complete * 9. get_channel_num * 10. get_service_name * 11. set_service_timeout * 12. get_msg_security * 13. put_msg_security * 14. chk_end_msg * 15. get_extmsg_info * 16. put_extmsg_info * 17. inmsg_recovery * 18. outmsg_recovery * 19. set_ping_msg * 20. chk_pong_msg * 21. set_extping_msg * 22. chk_extpong_msg ***************************************************************/ int _register_custom() _tcpgw_regfn(1, init_remote_info); _tcpgw_regfn(2, prepare_shutdown); _tcpgw_regfn(3, remote_connected); _tcpgw_regfn(4, remote_closed); _tcpgw_regfn(5, get_msg_length); #if defined(_tcpgw_use_extmsg) _tcpgw_regfn(15, get_extmsg_info); _tcpgw_regfn(16, put_extmsg_info); _tcpgw_regfn(6, NULL); _tcpgw_regfn(7, NULL); #else _tcpgw_regfn(6, get_msg_info); _tcpgw_regfn(7, put_msg_info); _tcpgw_regfn(15, NULL); _tcpgw_regfn(16, NULL); #endif _tcpgw_regfn(8, put_msg_complete); _tcpgw_regfn(9, get_channel_num); _tcpgw_regfn(10, get_service_name); _tcpgw_regfn(11, set_service_timeout); #if!defined(_tcpgw_version_old) #if defined(_tcpgw_version_1) defined(_tcpgw_version_2) _tcpgw_regfn(12, get_msg_security); 48 Tmax Gateway Guide (TCP/IP)
#else _tcpgw_regfn(12, NULL); #endif _tcpgw_regfn(14, chk_end_msg); #else _tcpgw_regfn(12, NULL); _tcpgw_regfn(14, NULL); #endif _tcpgw_regfn(13, NULL); #if!defined(_tcpgw_version_old) &&!defined(_tcpgw_version_1) _tcpgw_regfn(17, inmsg_recovery); _tcpgw_regfn(18, outmsg_recovery); #else _tcpgw_regfn(17, NULL); _tcpgw_regfn(18, NULL); #endif #if!defined(_tcpgw_version_old) &&!defined(_tcpgw_version_1) &&!defined(_tcpgw_version_2) #if defined(_tcpgw_use_extping) _tcpgw_regfn(19, NULL); _tcpgw_regfn(20, NULL); _tcpgw_regfn(21, set_extping_msg); _tcpgw_regfn(22, chk_extpong_msg); #else _tcpgw_regfn(19, set_ping_msg); _tcpgw_regfn(20, chk_pong_msg); _tcpgw_regfn(21, NULL); _tcpgw_regfn(22, NULL); #endif #else _tcpgw_regfn(19, NULL); _tcpgw_regfn(20, NULL); _tcpgw_regfn(21, NULL); _tcpgw_regfn(22, NULL); #endif return 1; 제 4 장사용자프로그램 49
제 5 장예제 본장에서는 2 장에서설명한 TCPGW 의각역할에대한예제에대해설명한다. 5.1. OUTBOUND TCPGW 예제 TCPGW가 Tmax boot시기동되어있다가리모트노드의요청이수신되면, 사용자가지정한서비스를호출한후에다시리모트노드로처리결과를주는예제이다. TCPGW의클라이언트 / 서버방식에관계가없다. 그리고리모트노드의상황에맞게 custom.c를수정하여 TCPGW를구성한다. 다음은 OUTBOUND TCP/IP 게이트웨이의흐름이다. [ 그림 5.1] OUTBOUND TCP/IP 게이트웨이 5.1.1. 프로그램구성 프로그램구성은다음과같다. Config file : tcpgw.m TCPGW : custom.c, custom.h Server : svr.c Remote Node : rclient.c, custom.h <tcpgw.m> *DOMAIN res SHMKEY = 88000, 제 5 장예제 51
MINCLH = 1, MAXCLH = 1, TPORTNO = 8888 *NODE node1 TMAXDIR="/home/tmax", APPDIR="/home/tmax/appbin" *SVRGROUP svg1 NODENAME = node1 *SERVER tcpgw svr SVGNAME = svg1, MIN = 1, MAX = 1, CPC = 5, SVRTYPE = CUSTOM_GATEWAY, CLOPT = "-- -P 5050 -N 2 d 0" SVGNAME = svg1, MIN = 1, MAX = 1 *SERVICE TOUPPER SVRNAME = svr <custom.h> #ifndef _CUSTOM_H_ #define _CUSTOM_H_ /* -------------------------------------------------------------------- */ /* Fixed structures and macros */ #define MSG_MAGIC "Tmax" #define REMOTE_REQUEST 0 #define REMOTE_REPLY 1 #define SVC_NAME_LENGTH 20 /* 이 msg_info_t는개발자가재정의하면안되는구조체이다. */ typedef struct msg_info char svc[svc_name_length]; int err; int len; int uid; int flags; int msgtype; int channel_id; msg_info_t; 52 Tmax Gateway Guide (TCP/IP)
/* -------------------------------------------------------------------- */ /* Modifiable structures and macros */ /* 이 msg_header_t와 msg_body_t는개발자가재정의가능한구조체이다. */ typedef struct msg_header int len; msg_header_t; typedef struct msg_body char name[16]; char data[100]; msg_body_t; #endif <custom.c> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/types.h> #include <sys/timeb.h> #include "custom.h" /* msg_header_size와 comm_header_size는 TCPGW 라이브러리내에서사용되기때문에정의해주어야한다. */ int msg_header_size = sizeof(msg_header_t); int comm_header_size = 0; /* 아래의함수들은필요하지않은경우내부로직은구현하지않아도된다. */ /* 그러나 TCPGW 라이브러리내에서사용되기때문에정의는해주어야한다. */ int init_remote_info(char *myname, int mynumber, int num_channel, int key) return 1; int remote_connected(int index, int addr, int type, int fd) return 1; int get_msg_length(msg_header_t *hp) if (hp == NULL hp->len <= 0) return -1; /* 실제데이터의길이를반환한다. */ /* 여기서반환하는값으로리모트노드에서오는데이터를읽는다. */ 제 5 장예제 53
return ntohl(hp->len); int get_msg_info(msg_header_t *hp, char *data, msg_info_t *info) msg_body_t *body; if ((info == NULL) (hp == NULL) (data == NULL)) return -1; body = (msg_body_t *)data; info->len = ntohl(hp->len); info->err = 0; info->flags = 0; memset(info->svc, 0x00, SVC_NAME_LENGTH); strncpy(info->svc, body->name, 8); /* 리모트노드에서요청이들어오므로 REMOTE_REQUEST 를반환한다. */ return REMOTE_REQUEST; int get_service_name(char *header, int err, char *svc) return -1; int put_msg_info(msg_header_t *hp, char *data, msg_info_t *info) msg_body_t *body; if ((info == NULL) (hp == NULL) (data == NULL)) return -1; hp->len = htonl(info->len); body = (msg_body_t *)data; /* body->name을이용하여에러유무전송 */ if (info->err) /* error */ strcpy(body->name, "Fail"); else strcpy(body->name, "Success"); /* 리모트노드로요청에대한결과를전송하기위한데이터길이를반환한다. */ return (info->len + sizeof(msg_header_t)); 54 Tmax Gateway Guide (TCP/IP)
int get_channel_num(char *data) return -1; int put_msg_complete(char *hp, char *data, msg_info_t *info) return 1; int remote_closed(int index, int type) return 1; int prepare_shutdown(int code) return 1; int set_service_timeout(int uid, char *header) return 1; int chk_end_msg(int len, char *data) return len; int outmsg_recovery(char *data, msg_info_t *info) return -1; int inmsg_recovery(char *data, msg_info_t *info) return -1; <Makefile> # 이 Makefile은 ibm 32bit 용이다. #TARGET은 Tmax 환경파일에서정의한 SERVER이름과같아야한다. TARGET = tcpgw APOBJS = $(TARGET).o 제 5 장예제 55
#TCPGW를생성하기위해서는 libtcpgw.a혹은 libtcpgw.so를링크시켜야한다. LIBS = -ltcpgw -ltmaxgw OBJS = custom.o register.o CFLAGS = -q32 -O -I$(TMAXDIR) -D_DBG LDFLAGS = -brtl APPDIR = $(TMAXDIR)/appbin LIBDIR = $(TMAXDIR)/lib.SUFFIXES :.c.c.o: $(CC) $(CFLAGS) $(LDFLAGS) -c $< $(TARGET): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -L$(LIBDIR) -o $(TARGET) $(OBJS) $(LIBS) mv $(TARGET) $(APPDIR)/. rm -f $(OBJS) $(APOBJS): $(TARGET).c $(CC) $(CFLAGS) $(LDFLAGS) -c $(TARGET).c <svr.c> #include <stdio.h> #include <string.h> #include <usrinc/atmi.h> TOUPPER(TPSVCINFO *msg) int i; printf("toupper service is started!\n"); printf("input : len=%d, data='%s'\n", msg->len, msg->data); for (i = 0; i < msg->len; i++) msg->data[i] = toupper(msg->data[i]); printf("output: len=%d, data='%s'\n", strlen(msg->data), msg->data); tpreturn(tpsuccess,0,(char *)msg->data, msg->len, 0); 56 Tmax Gateway Guide (TCP/IP)
<rclient.c> 다음의예제프로그램은테스트를위한리모트노드의클라이언트프로그램이다. 테스트를위해서는 TCPGW 가기동된후프로그램을기동시켜야한다. #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include "custom.h" #define SERV_ADDR "168.126.185.132" #define SERV_PORT 5050 int main(int argc, char *argv[]) int n, i, fd, ilen, olen; msg_header_t *header; msg_body_t *body, *result; /* 1 TCPGW로연결을맺는다. */ if ( (fd = network_connect()) < 0 ) perror("network connect error:"); return -1; /* 2 전문을구성한다. */ /* Message Header */ header = (msg_header_t *)malloc(sizeof(msg_header_t)); memset(header, 0x00, sizeof(msg_header_t)); header->len = sizeof(msg_body_t); /* Message Body */ body = (msg_body_t *)malloc(sizeof(msg_body_t)); memset(body, 0x00, sizeof(msg_body_t)); strncpy(body->name,"toupper", 16); for (i = 0; i < 1; i++) /* 3 TCPGW로데이터를송신한다. */ if ( (n = send(fd, (char *)header, sizeof(msg_header_t), 0)) < 0 ) perror("network write error:"); close(fd); return -1; printf("msg header send!\n"); 제 5 장예제 57
/* Message Body */ strncpy(body->data, argv[1], 100); if ( (n = send(fd, (char *)body, sizeof(msg_body_t), 0)) <= 0 ) perror("network write error:"); close(fd); return -1; /* 4 TCPGW로데이터를수신한다. */ if ( (n = recv(fd, (char *)&olen, 4, 0)) < 0 ) perror("network read error:"); close(fd); return -1; result = (msg_body_t *)malloc(olen); memset((char *)result, 0x00, olen); if ( (n = recv(fd, (char *)result, olen, 0)) <= 0 ) perror("network read error:"); close(fd); return -1; /* 5 TCPGW 와연결을끊는다. */ close(fd); return 1; int network_connect() struct sockaddr_in serv_addr; int fd; memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(serv_addr); serv_addr.sin_port = htons((unsigned short)serv_port); if ((fd = socket(af_inet, SOCK_STREAM, 0)) < 0) return -1; 58 Tmax Gateway Guide (TCP/IP)
if (connect(fd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) >= 0) return fd; close(fd); return -1; 5.2. 동기 INBOUND TCPGW 예제 Tmax 클라이언트에서 ( 또는 Tmax 서비스에서 ) TCPGW의서비스인 TCPGW 를 tpcall하면 TCPGW는리모트노드로데이터를전송한다. 리모트노드에서처리결과가수신되면해당클라이언트에게결과를반환한다. Tmax 클라이언트에서리모트노드로서비스를요청할때중요한점은 UID를설정하는일이다. UID는 TCPGW 라이브러리내부에서지정하는값 (info->uid) 을 put_msg_info에서전문내용에저장하거나또는사용자가 UID를만들어서전문내용에저장한후에 UID 값을 uid 항목에넣어주면된다. 이렇게 UID를전문에저장하고리모트노드로요청을보내면리모트노드에서는해당 UID를변경하지말고그대로되돌려주어야한다. TCPGW는응답을수신한후에 get_msg_info 함수를호출하여 UID값을가져와누가 TCPGW를호출했는지를판단하여응답을반환한다. 아래의예제는 TCPGW가클라이언트로기동되는것이므로 Tmax 환경파일의 CLOPT 절에 "-r", "-p", "-n" 옵션을설정해준다. 그리고리모트노드의상황에맞게 custom.c를수정하여 TCPGW를구성한다. [ 그림 5.2] 동기 INBOUND TCP/IP 게이트웨이 제 5 장예제 59
5.2.1. 프로그램구성 프로그램구성은다음과같다. Config file : tcpgw.m TCPGW : custom.c, custom.h Remote Node : rserver.c, network.c, custom.h Client : cli_tcpgw.c, custom.h <tcpgw.m> *DOMAIN res SHMKEY = 88000, MINCLH = 1, MAXCLH = 1, TPORTNO = 8888 *NODE node1 TMAXDIR="/home/tmax", APPDIR="/home/tmax/appbin" *SVRGROUP svg1 NODENAME = node1 *SERVER tcpgw SVGNAME = svg1, MIN = 1, MAX = 1, CPC = 5, SVRTYPE = CUSTOM_GATEWAY, CLOPT = "-- -r 168.126.185.131 -p 5060 -n 2" *SERVICE TCPGW SVRNAME = tcpgw <custom.h> #ifndef _CUSTOM_H_ #define _CUSTOM_H_ /* -------------------------------------------------------------------- */ /* Fixed structures and macros */ #define MSG_MAGIC "Tmax" 60 Tmax Gateway Guide (TCP/IP)
#define REMOTE_REQUEST 0 #define REMOTE_REPLY 1 #define SVC_NAME_LENGTH 20 /* 이 msg_info_t는개발자가재정의하면안되는구조체이다. */ typedef struct msg_info char svc[svc_name_length]; int err; int len; int uid; int flags; int msgtype; int channel_id; msg_info_t; /* -------------------------------------------------------------------- */ /* Modifiable structures and macros */ /* 이 msg_header_t 와 msg_body_t 는개발자가재정의가능한구조체이다. */ #define UID_FIELD 98 #define SVC_NAME_FIELD 92 #define UID_LENGTH 4 #define SVC_LENGTH 6 typedef struct msg_header int len; msg_header_t; typedef struct msg_body char data[92]; char name[6]; char uid[4]; msg_body_t; #endif /* _CUSTOM_H_ */ <custom.c> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/types.h> #include <sys/timeb.h> #include "custom.h" /* msg_header_size 와 comm_header_size 는 TCPGW 라이브러리내에서사용되기때문에 제 5 장예제 61
정의해주어야한다. */ int msg_header_size = sizeof(msg_header_t); int comm_header_size = 0; /* 아래의함수들은필요하지않은경우내부로직은구현하지않아도된다. */ /* 그러나 TCPGW 라이브러리내에서사용되기때문에정의해주어야한다. */ int get_channel_num(char *data) return -1; int put_msg_complete(char *hp, char *data, msg_info_t *info) return 1; int get_service_name(char *header, int err, char *svc) return -1; int init_remote_info(char *myname, int mynumber, int num_channel, int key) return 1; int remote_connected(int index, int addr, int type, int fd) return 1; int get_msg_length(msg_header_t *hp) if (hp == NULL hp->len == 0) return -1; return ntohl(hp->len); int get_msg_info(msg_header_t *hp, char *data, msg_info_t *info) info->flags = 0; if ((info == NULL) (hp == NULL) (data == NULL)) return -1; info->len = ntohl(hp->len); 62 Tmax Gateway Guide (TCP/IP)
info->err = 0; info->flags = 0; /* info->uid 를설정한다. */ memcpy((char *)&(info->uid), (char *)&data[uid_field], UID_LENGTH); strncpy(info->svc, (char *)&data[svc_name_field], SVC_LENGTH); info->svc[svc_length] = 0; if (info->uid == 0) return REMOTE_REQUEST; else return REMOTE_REPLY; int put_msg_info(msg_header_t *hp, char *data, msg_info_t *info) int nsize = 0; if ((info == NULL) (hp == NULL) (data == NULL)) return -1; /* hp->len 에들어가는값은실제데이터의길이이다. */ hp->len = htonl(info->len); if (info->err) printf("info->err = %d\n", info->err); return -1; else /* 리모트노드로 REQUEST를하는경우는반드시이 uid를 */ /* 라이브러리내부에서설정한값으로설정해주어야한다.*/ memcpy((char *)&data[uid_field], (char *)&(info->uid), UID_LENGTH); memcpy((char *)&data[svc_name_field], info->svc, SVC_LENGTH); return (info->len + msg_header_size); int remote_closed(int index, int type) return 1; int prepare_shutdown(int code) 제 5 장예제 63
return 1; int set_service_timeout(int uid, char *header) return 1; int chk_end_msg(int len, char *data) return len; int outmsg_recovery(char *data, msg_info_t *info) return -1; int inmsg_recovery(char *data, msg_info_t *info) return -1; <Makefile> # 이 Makefile은 ibm 32bit 용이다. #TARGET은 Tmax 환경파일에서정의한 SERVER이름과같아야한다. TARGET = tcpgw APOBJS = $(TARGET).o #TCPGW를생성하기위해서는 libtcpgw.a혹은 libtcpgw.so를링크시켜야한다. LIBS = -ltcpgw -ltmaxgw OBJS = custom.o register.o CFLAGS = -q32 -O -I$(TMAXDIR) -D_DBG LDFLAGS = -brtl APPDIR = $(TMAXDIR)/appbin LIBDIR = $(TMAXDIR)/lib.SUFFIXES :.c.c.o: $(CC) $(CFLAGS) $(LDFLAGS) -c $< $(TARGET): $(OBJS) 64 Tmax Gateway Guide (TCP/IP)
$(CC) $(CFLAGS) $(LDFLAGS) -L$(LIBDIR) -o $(TARGET) $(OBJS) $(LIBS) mv $(TARGET) $(APPDIR)/. rm -f $(OBJS) $(APOBJS): $(TARGET).c $(CC) $(CFLAGS) $(LDFLAGS) -c $(TARGET).c <rserver.c> 다음의예제프로그램은 TCPGW 의접속을받고, 전문을수신 / 송신하는기능의데몬형태의프로그램이 다. 테스트를위해서는프로그램이먼저기동되어있는상태에서 TCPGW 가기동되어야한다. #include <stdio.h> #include <unistd.h> #include <sys/time.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #include "custom.h" #define SERV_PORT 5060 void doit(int fd); int main(int argc, char *argv[]) int ret, i, len; int fd, childfd; pid_t childpid; ret = network_listen(serv_port); if (ret < 0) return -1; else fd = ret; for (;;) childfd = network_accept(fd); if (childfd < 0) return -1; if ( (childpid = fork()) == 0) close(fd); 제 5 장예제 65
doit(childfd); exit(0); close(childfd); void doit(int fd) ssize_t n; int ret, i; msg_header_t *header; msg_body_t *body; header = (msg_header_t *)malloc(sizeof(msg_header_t)); memset((char *)header, 0x00, sizeof(msg_header_t)); body = (msg_body_t *)malloc(sizeof(msg_body_t)); memset((char *)body, 0x00, sizeof(msg_body_t)); readn2(fd, (char *)header, sizeof(msg_header_t)); readn2(fd, (char *)body, ntohl(header->len)); if (body->uid == 0) printf("it's reply message\n"); else printf("it's request message\n"); for (i = 0; i < sizeof(body->data); i++) body->data[i] = toupper(body->data[i]); header->len = htonl(sizeof(msg_body_t)); writen2(fd, (char *)header, sizeof(msg_header_t)); writen2(fd, (char *)body, sizeof(msg_body_t)); <network.c> #include <stdio.h> #include <unistd.h> #include <sys/time.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> 66 Tmax Gateway Guide (TCP/IP)
#include <fcntl.h> #include <sys/stat.h> #include <errno.h> #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff /* should be in <netinet/in.h> */ #endif /* ----------------------- extern global variable ------------------- */ extern int errno; extern char _svrname[30]; int network_listen(int portno) int fd, on; struct sockaddr_in serv_addr; if ((fd = socket(af_inet, SOCK_STREAM, 0)) < 0) return(-1); on = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) printf("setsockopt error for SO_REUSEADDR"); #ifdef SO_KEEPALIVE on = 1; if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) printf("setsockopt error for SO_KEEPALIVE"); #endif memset((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(inaddr_any); serv_addr.sin_port = htons(portno); if (bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 제 5 장예제 67
close(fd); return(-2); if (listen(fd, 250) < 0) close(fd); return(-3); return(fd); /* ------------------- server : client accept --------------------- */ int network_accept(int listenfd) int fd, len; struct sockaddr_in cli_addr; len = sizeof(cli_addr); fd = accept(listenfd, (struct sockaddr *)&cli_addr, if (fd < 0) &len); return(-1); /* often errno=eintr, if signal caught */ return(fd); int readn2(int fd, char *ptr, int nbytes) int nleft, nread; nleft = nbytes; while (nleft > 0) nread = recv(fd, ptr, nleft, 0); if (nread < 0) if (errno == EINTR) continue; else if (errno == EWOULDBLOCK) return (nbytes - nleft); return(nread); /* error, return < 0 */ else if (nread == 0) break; /* EOF */ 68 Tmax Gateway Guide (TCP/IP)
nleft -= nread; ptr += nread; return (nbytes - nleft); /* return >= 0 */ int writen2(int fd, char *ptr, int nbytes) int nleft, nwritten; nleft = nbytes; while (nleft > 0) nwritten = send(fd, ptr, nleft, 0); if (nwritten <= 0) return(nwritten); /* error */ nleft -= nwritten; ptr += nwritten; return(nbytes - nleft); <Makefile>(rServer 용 ) # 이 Makefile 은 compac 용이다. TARGET = rserver APOBJS = $(TARGET).o OBJS = $(APOBJS) network.o CFLAGS = -D_DBG.c.o: $(CC) $(CFLAGS) -c $< all : $(TARGET) $(TARGET):$(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS) rm -f $(OBJS) <cli_tcpgw.c> 다음의예제프로그램은 TCPGW 에서비스를요청하는 Tmax 클라이언트이다. TCPGW 와리모트노드와 의연결이완료된후프로그램을실행한다. 제 5 장예제 69
#include <stdio.h> #include <usrinc/atmi.h> #include "custom.h" int main(int argc, char **argv) int ret; msg_body_t *body; char *buf; long rlen; ret = tmaxreadenv("tmax.env", "TMAX"); if (ret < 0) printf("tmaxreadenv fail...[%s]\n", tpstrerror(tperrno)); ret = tpstart((tpstart_t *)NULL); if (ret < 0) printf("tpstart fail...[%s]\n", tpstrerror(tperrno)); return -1; buf = tpalloc("string", 0, 0); if (buf == NULL) printf("buf tpalloc fail..[%s]\n", tpstrerror(tperrno)); tpend(); return -1; body = (msg_body_t *)buf; memcpy(body->data, argv[1], strlen(argv[1])); body->data[51] = 0; /* TCPGW 서비스를호출한다. */ ret = tpcall("tcpgw", buf, sizeof(msg_body_t), &buf, &rlen, 0); if (ret < 0) printf("tpcall fail...[%s]\n", tpstrerror(tperrno)); tpfree((char *)buf); tpend(); return -1; body = (msg_body_t *)buf; printf("return value = %s\n", body->data); tpfree((char *)buf); tpend(); 70 Tmax Gateway Guide (TCP/IP)
5.3. NON 블록킹 TCPGW 예제 NON 블록킹 TCPGW 방식은보통대외계와통신하는경우에많이사용한다. 적은프로세스수로도시스템이부하를적게주면서보다많을일을처리할수있기때문이다. 블록형방식은 Tmax 클라이언트나서비스에서직접 TCPGW를호출하여응답을받았으나이방식은송신프로세스와 TCPGW로부터응답을처리하는수신프로세스를분리하여처리한다. TCPGW를호출하고자하는모든프로세스는먼저송신프로세스를호출하면, 송신프로세스는 TCPGW 를호출하기전에사전작업을완료하고 TCPGW로서비스컨트롤을넘긴다.(tpforward) 다음에 TCPGW 는넘겨받은서비스처리를하기전에 Tmax 엔진과연결되어있는채널의블록상태를해제하고리모트노드로서비스를송신하다. 리모트노드로부터응답을수신받으면 TCPGW는수신메시지를처리할수신서비스를서비스를찾는순서에따라서서비스를찾아수신프로세스에게서비스컨트롤을넘긴다. 수신프로세스는응답을처리한후에최초로서비스를호출한프로세스에게결과를전달한다. 위와같은원리로서비스되므로실제 TCPGW를호출하는서비스나 tprelay받는서비스는비동기적으로작동하므로수행시간에대한부하를거의가지지않는다. 단, 최초로송신서비스를호출하는프로세스는응답이올때까지기다리므로블록되어있는상태이다. 다음의그림은리모트노드가서버가되고 TCPGW가클라이언트로서연결을맺는구조이다. [ 그림 5.3] NON BLOCKING TCPGW 예제 5.3.1. 프로그램구성 프로그램구성은다음과같다. Config file : tcpgw.m TCPGW : custom.c, custom.h Remote Node : rserver.c, network.c, custom.h Server : sndsvr.c, rcvsvr.c 제 5 장예제 71