예제

본 장에서는 SVCGW의 서비스 유형별 예제에 대해 설명한다.

1. NOREPLY 서비스 호출

Tmax의 서비스나 클라이언트에서 SVCGW로 tpacall로 서비스를 요청하고 결과에 관계없이 처리하는 예제이다.

프로그램 구성은 다음과 같다.

구분 파일명

환경 파일

tmax.m, tcpsvcgw.cfg

리모트 노드

remote.c

1.1. 환경 파일

<tmax.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
tcpsvcgw        SVGNAME = svg1, MIN=1, MAX=1,
                CPC=10, SVRTYPE=CUSTOM_GATEWAY,
                CLOPT=”-- -P 8090 -F /home/tmax/config/tcpsvcgw.cfg –N 20”

svr             SVGNAME = svg1, MIN=1, MAX=1

*SERVICE
TCPSVC1         SVRNAME = tcpsvcgw
TOUPPER         SVRNAME = svr

<tcpsvcgw.cfg>

#######################################################
#              TCP/IP Service Gateway Config          #
#######################################################
# gwno  ipaddr  Tmaxsvc
# 0     1.1.1.1  SVC
#######################################################
# line start with "#" is comment line
# gwno must start at 0 and be increased by 1
# ipaddr: remote node ipaddr
# svc:  tmax service name
#######################################################
0       1.1.1.1    TCPSVC1

1.2. 리모트 노드

<toupper.c>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <usrinc/atmi.h>

main(int argc, char *argv[])
{
    char    *sndbuf, *rcvbuf;
    long    rcvlen;

    if (argc != 2) {
        printf("Usage: toupper string\n");
        exit(1);
    }

    if (tpstart((TPSTART_T *)NULL) == -1){
        printf("Tpstart failed\n");
        exit(1);
    }

    if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("Sendbuf alloc failed !\n");
        tpend();
        exit(1);
    }

    if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("Recvbuf alloc failed !\n");
        tpfree((char *)sndbuf);
        tpend();
        exit(1);
    }

    strcpy(sndbuf, argv[1]);

    if(tpcall("TOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){
        printf("Can't send request to service TOUPPER\n");
        tpfree((char *)sndbuf);
        tpfree((char *)rcvbuf);
        tpend();
        exit(1);
    }
    printf("Sendbuf data: %s\n", sndbuf);
    printf("Recvbuf data: %s\n", rcvbuf);

    tpfree((char *)sndbuf);
    tpfree((char *)rcvbuf);
    tpend();
}

<svr.c>

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

TOUPPER(TPSVCINFO *msg)
{
    char    *sndbuf;
    long    sndlen;

    if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("sendbuf alloc failed !\n");
        tpreturn(TPFAIL, -1, NULL, 0, 0);
    }

    strcpy(sndbuf, msg->data);
    sndlen = msg->len;

    /* 리모트 TCPSVC1 서비스 호출 */
    if(tpacall("TCPSVC1", sndbuf, sndlen, TPNOREPLY)==-1){
        printf("Can't send request to service TCPSVC1\n");
        tpfree((char *)sndbuf);
        tpreturn(TPFAIL, -1, NULL, 0, 0 );
    }

    tpfree((char *)sndbuf);
    tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}

<remote.c>

#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>
#define SVR_PORT   "1.1.1.1:8090"
int main(int argc, char *argv[])
{
    int   n, msgtype;
    long  ilen, olen;
    char  buffer[1024];
    char  svcname[24];

    /* Gateway에 리모트 노드를 등록한다 */
    printf("Remote Service Start...\n\n");
    n = ComOpen(TCPIP, NULL, SVR_PORT );
    if (n < 0) {
        perror("Gateway register error:");
        return -1;
    }

    while(1) {
        memset(svcname, 0x00, sizeof(svcname));
        memset(buffer, 0x00, sizeof(buffer));

        /* 데이터를 수신한다. */
        n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
        if (n < 0) {
            perror("Data Receive error:");
            ComClose();
            return -1;
        }
        printf("REMOTE RECV : svcname = [%s]\n", svcname);
        printf("REMOTE RECV : len = %d\n",olen);
        printf("REMOTE RECV : data= [%s]\n\n", buffer);
    }

    /* Gateway와 연결을 해제한다 */
    ComClose( );
}

2. REPLY 서비스 호출

Tmax의 서비스나 클라이언트에서 SVCGW로 tpacall로 서비스를 요청하고 결과에 관계없이 처리하고, 리모트 노드에서 서비스 요청에 대한 처리 결과를 Tmax의 다른 서비스에서 처리할 수 있도록 “TOLOWER”를 호출하는 예제이다.

프로그램 구성은 다음과 같다.

구분 파일명

환경 파일

tmax.m, tcpsvcgw.cfg

리모트 노드

remote.c

2.1. 환경 파일

<tmax.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
tcpsvcgw    SVGNAME = svg1,
            MIN=1,
            MAX=1,
            CPC=10,
            SVRTYPE=CUSTOM_GATEWAY,
            CLOPT=”-- -P 8090 -F /home/tmax/config/tcpsvcgw.cfg –N 20”

svr     SVGNAME = svg1,
        MIN=1,
        MAX=1,

*SERVICE
TCPSVC1     SVRNAME = tcpsvcgw
TOUPPER     SVRNAME = svr
TOLOWER     SVRNAME = svr

<tcpsvcgw.cfg>

#######################################################
#              TCP/IP Service Gateway Config          #
#######################################################
# gwno  ipaddr  Tmaxsvc
# 0     1.1.1.1  SVC
#######################################################
# line start with "#" is comment line
# gwno must start at 0 and be increased by 1
# ipaddr: remote node ipaddr
# svc:  tmax service name
#######################################################
0       1.1.1.1    TCPSVC1

2.2. 리모트 노드

<toupper.c>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <usrinc/atmi.h>

main(int argc, char *argv[])
{
    char    *sndbuf, *rcvbuf;
    long    rcvlen;

    if (argc != 2) {
        printf("Usage: toupper string\n");
        exit(1);
    }

    if (tpstart((TPSTART_T *)NULL) == -1){
        printf("Tpstart failed\n");
        exit(1);
    }

    if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("Sendbuf alloc failed !\n");
        tpend();
        exit(1);
    }

    if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("Recvbuf alloc failed !\n");
        tpfree((char *)sndbuf);
        tpend();
        exit(1);
    }

    strcpy(sndbuf, argv[1]);

    if(tpcall("TOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){
        printf("Can't send request to service TOUPPER\n");
        tpfree((char *)sndbuf);
        tpfree((char *)rcvbuf);
        tpend();
        exit(1);
    }

    printf("Sendbuf data: %s\n", sndbuf);
    printf("Recvbuf data: %s\n", rcvbuf);

    tpfree((char *)sndbuf);
    tpfree((char *)rcvbuf);
    tpend();
}

<svr.c>

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

TOUPPER(TPSVCINFO *msg)
{
    char    *sndbuf;
    long    sndlen;

    if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("sendbuf alloc failed !\n");
        tpreturn(TPFAIL, -1, NULL, 0, 0);
    }

    strcpy(sndbuf, msg->data);
    sndlen = msg->len;

    if(tpacall("TCPSVC1", sndbuf, sndlen, TPNOREPLY)==-1){
        printf("Can't send request to service TCPSVC1\n");
        tpfree((char *)sndbuf);
        tpreturn(TPFAIL, -1, NULL, 0, 0 );
    }

    tpfree((char *)sndbuf);
    tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}

TOLOWER(TPSVCINFO *msg)
{
    int        i;

    printf("TOLOWER service is started!\n");
    printf("INPUT : data=%s\n", msg->data);

    for (i = 0; i < msg->len; i++)
        msg->data[i] = tolower(msg->data[i]);

    printf("OUTPUT: data=%s\n\n", msg->data);

    tpreturn(TPSUCCESS,0,(char *)msg->data, 0,0);
}

<remote.c>

#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>

#define SVR_PORT   "1.1.1.1:8090"

int main(int argc, char *argv[])
{
    int   n, msgtype;
    long  ilen, olen;
    char  buffer[1024];
    char  svcname[24];

    /* Gateway에 리모트 노드를 등록한다 */
    printf("Remote Service Start...\n\n");
    n = ComOpen(TCPIP, "TCPSVC1", SVR_PORT );
    if (n < 0) {
        perror("Gateway register error:");
        return -1;
    }

    while(1) {
        memset(svcname, 0x00, sizeof(svcname));
        memset(buffer, 0x00, sizeof(buffer));

        /* 데이터를 수신한다. */
        n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
        if (n < 0) {
            perror("Data Receive error:");
            ComClose();
            return -1;
        }
        printf("REMOTE RECV : svcname = [%s]\n", svcname);
        printf("REMOTE RECV : len = %d\n",olen);
        printf("REMOTE RECV : data= [%s]\n\n", buffer);

        /* 응답 데이터를 전송한다. */
        strcpy(buffer,"I'M REMOTE SERVICE.");
        ilen = strlen(buffer) + 1;
        n = ComSend("TOLOWER", COMMDATA, buffer, ilen, COMMNOREPLY);
        if (n < 0) {
            perror("Data send error:");
            ComClose();
            return -1;
        }
    }
    /* Gateway와 연결을 해제한다 */
    ComClose( );
}

3. 리모트 노드 동기형 호출

SVCGW가 Tmax boot할 때 기동되어 있다가 리모트 노드의 요청이 수신되면, 사용자가 지정한 서비스를 호출한 후에 다시 리모트 노드로 처리 결과를 주는 예제이다.

프로그램 구성은 다음과 같다.

구분 파일명

환경 파일

tmax.m, tcpsvcgw.cfg

리모트 노드

remote.c

3.1. 환경 파일

<tmax.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
tcpsvcgw    SVGNAME = svg1,
            MIN=1,
            MAX=1,
            CPC=10,
            SVRTYPE=CUSTOM_GATEWAY,
            CLOPT=”-- -P 8090 -F /home/tmax/config/tcpsvcgw.cfg –N 20”

svr     SVGNAME = svg1, MIN=1, MAX=1

*SERVICE
TCPSVC1     SVRNAME = tcpsvcgw
TOUPPER     SVRNAME = svr

<tcpsvcgw.cfg>

#######################################################
#              TCP/IP Service Gateway Config          #
#######################################################
# gwno  ipaddr  Tmaxsvc
# 0     1.1.1.1  SVC
#######################################################
# line start with "#" is comment line
# gwno must start at 0 and be increased by 1
# ipaddr: remote node ipaddr
# svc:  tmax service name
#######################################################
0       1.1.1.1    TCPSVC1

3.2. 리모트 노드

<svr.c>

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

TOUPPER(TPSVCINFO *msg)
{
    int    i;
    char    *sndbuf;

    printf("TOUPPER service is started!\n");
    printf("INPUT : data=%s, len = %d\n", msg->data, msg->len);

    for (i = 0; i < msg->len; i++)
        msg->data[i] = toupper(msg->data[i]);

    printf("OUTPUT: data=%s, len = %d\n", msg->data, msg->len);

    tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}

<remote.c>

#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>

#define SVR_PORT   "1.1.1.1:8090"

int main(int argc, char *argv[])
{

    int   n, msgtype;
    long  ilen, olen;
    char  buffer[1024];
    char  svcname[20];
    char *ptr;


    /* Gateway에 리모트 노드를 등록한다 */
    printf("Remote Service Start...\n\n");
    n = ComOpen(TCPIP,"TCPSVC1", SVR_PORT);
    if (n < 0) {
        perror("Gateway register error:");
        return -1;
    }

    ptr = argv[1];
    ilen = strlen(argv[1]) + 1;
    printf("Send Data = [%s], len = %d\n",ptr,ilen);

    n = ComSend("TOUPPER", COMMDATA, ptr, ilen, COMMNOFLAG);
    if (n < 0) {
        perror("Data send error:");
        ComClose();
        return -1;
    }

    memset(svcname, 0x00, sizeof(svcname));
    memset(buffer, 0x00, sizeof(buffer));

    /* 응답 데이터를 수신한다. */
    n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
    if (n < 0) {
        perror("Data Receive error:");
        ComClose();
        return -1;
    }

    printf("REMOTE RECV : svcname = [%s]\n", svcname);
    printf("REMOTE RECV : len = %d\n",olen);
    printf("REMOTE RECV : data= [%s]\n\n", buffer);

    /* Gateway와 연결을 해제한다 */
    ComClose( );
}

4. ACK/NAK 통신 방식

SVCGW가 Tmax boot할 때 기동되어 있다가 리모트 노드의 요청이 수신되면, 사용자가 지정한 서비스를 호출한 후에 다시 리모트 노드로 처리 결과를 주는 예제이다. 이 경우에 송수신 데이터에 대해서 ACK/NAK를 처리하는 예제이다.

프로그램 구성은 다음과 같다.

구분 파일명

환경 파일

tmax.m, tcpsvcgw.cfg

리모트 노드

remote.c

4.1. 환경 파일

<tmax.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
tcpsvcgw    SVGNAME = svg1,
            MIN=1,
            MAX=1,
            CPC=10,
            SVRTYPE=CUSTOM_GATEWAY,
            CLOPT=”-- -P 8090 -F /home/tmax/config/tcpsvcgw.cfg –N 20 -A”

svr     SVGNAME = svg1, MIN=1, MAX=1

*SERVICE
COM1        SVRNAME = tcpsvcgw
TOUPPER     SVRNAME = svr

<tcpsvcgw.cfg>

#######################################################
#              TCP/IP Service Gateway Config          #
#######################################################
# gwno  ipaddr  Tmaxsvc
# 0     1.1.1.1  SVC
#######################################################
# line start with "#" is comment line
# gwno must start at 0 and be increased by 1
# ipaddr: remote node ipaddr
# svc:  tmax service name
#######################################################
0       1.1.1.1    TCPSVC1

4.2. 리모트 노드

< svr.c >

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

TOUPPER(TPSVCINFO *msg)
{
    int     i;
    char    *sndbuf;

    printf("TOUPPER service is started!\n");
    printf("INPUT : data=%s, len = %d\n", msg->data, msg->len);

    for (i = 0; i < msg->len; i++)
        msg->data[i] = toupper(msg->data[i]);

    printf("OUTPUT: data=%s, len = %d\n", msg->data, msg->len);

    tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}

<remote.c>

#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>

#define SVR_PORT   "1.1.1.1:8090"

int main(int argc, char *argv[])
{

    int   n, msgtype;
    long  ilen, olen;
    char  buffer[1024];
    char  svcname[20];
    char *ptr;

    /* Gateway에 리모트 노드를 등록한다 */
    printf("Remote Service Start...\n\n");
    n = ComOpen(TCPIP,"TCPSVC1", SVR_PORT);
    if (n < 0) {
        perror("Gateway register error:");
        return -1;
    }

    while(1) {
        ptr = argv[1];
        ilen = strlen(argv[1]) + 1;
        printf("Send Data = [%s], len = %d\n",ptr,ilen);

        n = ComSend("TOUPPER", COMMDATA, ptr, ilen, COMMNOFLAG);
        if (n < 0) {
            perror("Data send error:");
            ComClose();
            return -1;
        }

        memset(svcname, 0x00, sizeof(svcname));
        memset(buffer, 0x00, sizeof(buffer));

        /* ACK/NAK 수신. */
        n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
        if (n < 0) {
            perror("Data Receive error:");
            ComClose();
            return -1;
        }
        if (msgtype == COMMACK)
            break;
    }
    printf("REMOTE RECV : msgtype = %d\n\n",msgtype);

    memset(svcname, 0x00, sizeof(svcname));
    memset(buffer, 0x00, sizeof(buffer));

    /* 응답 데이터를 수신한다. */
    n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
    if (n < 0) {
        perror("Data Receive error:");
        ComClose();
        return -1;
    }

    /* ACK/NAK 송신. */
    n = ComSend("TOUPPER", COMMACK, NULL, 0, COMMNOFLAG);
    if (n < 0) {
        perror("Data send error:");
        ComClose();
        return -1;
    }
    printf("REMOTE RECV : svcname = [%s]\n", svcname);
    printf("REMOTE RECV : len = %d\n",olen);
    printf("REMOTE RECV : data= [%s]\n\n", buffer);

    /* Gateway와 연결을 해제한다 */
    ComClose( );
}