제6장 RDP 사용 예제

내용 목차

6.1. 클라이언트 대 서버 프로그램

본 장에서는 RDP 프로그램 사용 예제에 대해 설명한다.

다음은 간단한 RDP 예제 프로그램이다.

클라이언트에서 REAL 서비스를 호출하면 클라이언트의 ID를 공유 메모리에 저장한다. RDP에서는 공유 메모리에 저장된 모든 클라이언트에 메시지를 보낸다. 이후 클라이언트가 UNREAL이라는 서비스를 호출하면 해당 클라이언트의 ID를 삭제하고 더 이상 해당하는 클라이언트에 메시지를 보내지 않는다.

설정 파일

*DOMAIN        
tmax1                SHMKEY=73060, MINCLH=2, MAXCLH=2, TPORTNO=8800

*NODE                
tmaxs1               TMAXDIR ="/home/tmax ",
                     APPDIR = "/home/tmax/appbin",
                     PATHDIR = "/home/tmax/path",
                     TLOGDIR = "/home/tmax/log/tlog",
                     ULOGDIR = "/home/tmax/log/ulog",
                     SLOGDIR = "/home/tmax/log/slog",
                     REALSVR="realtest",
                     RSCPC = 16

*SVRGROUP        
svg1                 NODENAME = "tmaxs1"

*SERVER        
realsvr              SVGNAME = svg1
realtest             SVGNAME = svg1,
                     MIN = 2,
                     MAX = 2,
                     SVRTYPE = REALSVR,
                     MAXRSTART = 0

*SERVICE        
# UCS에서 제공하는 TCS Type의 Service
REAL                 SVRNAME = ucssvr
UNREAL               SVRNAME = ucssvr

클라이언트 프로그램

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

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

        if(tpstart((TPSTART_T *)NULL) == -1)
        {
                error processing…
        }

        tpsetunsol_flag(TPUNSOL_POLL);

        if((sndbuf = (char *)tpalloc("CARRAY", NULL, 1024)) == NULL)
        {
                error processing…
        }

        if((rcvbuf = (char *)tpalloc("CARRAY", NULL, 1024)) == NULL)
        {
                error processing…
        }

        if(tpcall("REAL", sndbuf, 1024, &rcvbuf, &rcvlen, 0) == -1)
        {
                error processing…
        }

        while(1)
        {
                ret = tpgetunsol(UNSOL_TPSENDTOCLI, &rcvbuf, &rcvlen, TPBLOCK);
                printf("Loop Count : %d\n", RecvCnt);
                if(ret > 0)
                {
                        printf("ret message..[%s]\n”, rcvbuf);
                        RecvCnt ++;
                }
                if (RecvCnt == 10) break;
        }

        if(tpcall("UNREAL", sndbuf, 1024, &rcvbuf, &rcvlen, 0) == -1)
        {
                error processing…
        }

        RecvCnt = 0;
        while(1)
        {
                ret = tpgetunsol(UNSOL_TPSENDTOCLI, &rcvbuf, &rcvlen, TPBLOCK);
                printf("Loop Count : %d\n", RecvCnt);
                if(ret > 0)
                {
                        printf("ret message..[%s]\n”, rcvbuf);
                        RecvCnt ++;
                }
                if (RecvCnt == 10) break;
        }
        tpfree((char *)sndbuf);
        tpfree((char *)rcvbuf);
        tpend();
}

서버 프로그램

<realsvr.c>

#include        <stdio.h>
#include        <sys/types.h>
#include        <sys/ipc.h>
#include        <sys/shm.h>
#include        <sys/time.h>
#include        <usrinc/tmaxapi.h>
#include        <usrinc/ucs.h>

int shm_creator = 0;
int *shm;
int id;

#define TABLE_SIZE      (FD_SETSIZE * 10)

tpsvrinit(int argc, char *argv[])
{
        int i;

        id = shmget(0x12345, TABLE_SIZE * sizeof(int),
                IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
        if (id < 0) {
            id = shmget(0x12345, TABLE_SIZE * sizeof(int), 0);
            if (id < 0) {
                error processing…
            }
        } else {
            shm_creator = 1;
        }

        shm = (int *)shmat(id, 0, 0);
        if (shm == (void*)-1) {
            error processing…
        }

        if (shm_creator) {
            for (i = 0; i < TABLE_SIZE; i++) {
                shm[i] = -1;
            }
        }

        printf("svr20 started\n");
        return 1;
}

tpsvrdone()
{
        shmdt((char *)shm);
        if (shm_creator) {
            shmctl(id, IPC_RMID, (struct shmid_ds *) 0);
        }
        printf("svr20 closed\n");
}

REAL(TPSVCINFO *rqst)
{
        int i, clid;

        clid = tpgetclid();
        for (i = 0; i < TABLE_SIZE; i++) {
            if (shm[i] == clid) {
                shm[i] = -1;
            }
        }
        for (i = 0; i < TABLE_SIZE; i++) {
            if (shm[i] == -1) {
                shm[i] = clid;
                break;
            }
        }

        tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
}

UNREAL(TPSVCINFO *rqst)
{
        int i, clid;

        clid = tpgetclid();
        for (i = 0; i < TABLE_SIZE; i++) {
            if (shm[i] == clid) {
                shm[i] = -1;
            }
        }

        usleep(10000);

        tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
}

<realtest.c>

#include        <stdio.h>
#include        <sys/types.h>
#include        <sys/ipc.h>
#include        <sys/shm.h>
#include        <sys/time.h>
#include        <sys/timeb.h>
#include        <usrinc/tmaxapi.h>
#include        <usrinc/ucs.h>

int shm_creator = 0;
int *shm;
int id;

#define TABLE_SIZE      (FD_SETSIZE * 10)
#define MSG_LEN         (1024 - 20)
#define SEND_INTERVAL   (100000)

long time_diff(struct timeval *a, struct timeval *b)
{
        long    sec, usec;

        sec = a->tv_sec - b->tv_sec;
        usec = a->tv_usec - b->tv_usec;

        return (sec * 1000000 + usec);
}

tpsvrinit(int argc, char *argv[])
{
        int i;

        id = shmget(0x12345, TABLE_SIZE * sizeof(int),
                IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
        if (id < 0) {
            id = shmget(0x12345, TABLE_SIZE * sizeof(int), 0);
            if (id < 0) {
                error processing…
            }
        } else {
            shm_creator = 1;
        }

        shm = (int *)shmat(id, 0, 0);
        if (shm == (void*)-1) {
            error processing…
        }

        if (shm_creator) {
            for (i = 0; i < TABLE_SIZE; i++) {
                shm[i] = -1;
            }
        }

        printf("RealSvr started\n");
        return 1;
}

tpsvrdone()
{
        shmdt((char *)shm);
        if (shm_creator) {
            shmctl(id, IPC_RMID, (struct shmid_ds *) 0);
        }
        printf("RealSvr closed\n");
}

usermain(int argc, char *argv[])
{
        char    *sndbuf;
        long    sndlen;
        int     i, n, msgid, previd, clid;
        int     fail, delay, loop;
        long    diff;
        struct timeval cur, prev, prev_stat;
        int     max, mine;

        max = tpgetminsvr();
        mine = tpgetsvrseqno();

        if ((sndbuf = (char *)tpalloc("CARRAY",NULL, 2048)) == NULL) {
            error processing…
        }

        msgid = previd = fail = delay = 0;
        gettimeofday(&prev, NULL);
        prev_stat = prev;
        while(1) {
            gettimeofday(&cur, NULL);

            if (mine == (max - 1)) {
                diff = time_diff(&cur, &prev_stat);
                if (diff >= 3975000) {
                    printf("RealSvr: Sent = %d, fail = %d, delay = %d, "
                        "int = %d:%06d\n",
                        msgid - previd, fail, delay,
                        diff / 1000000, diff % 1000000);
                    previd = msgid;
                    delay = fail = 0;
                    prev_stat = cur;
                }
            }

            diff = time_diff(&cur, &prev);
            if (diff < SEND_INTERVAL)
                tpuschedule(SEND_INTERVAL - diff);
            else
                delay++;

            if (diff >= (SEND_INTERVAL * 2))
                printf("Long Schedule delay %d\n", diff);

            gettimeofday(&prev, NULL);

            for (i = 0; i < TABLE_SIZE; i++) {
                clid = shm[i];

                if (tpchkclid(clid) < 0) {
                    continue;
                }

                sprintf(sndbuf, "Msg(%d) sent to clid = %#x", msgid++, clid);
                n = tpsendtocli(clid, sndbuf, MSG_LEN, TPFLOWCONTROL);
                if (n < 0) {
                    fail++;
                }
            }
        }
}