Chapter 6. RDP Usage Example

Table of Contents

6.1. Client vs. Server Program

This chapter describes RDP program with usage examples.

6.1. Client vs. Server Program

If a client calls a REAL service, the client ID will be stored in shared memory. RDP will then send a message to all clients stored in the shared memory. After that, If a client calls the service UNREAL, the client ID will be deleted and messages will not be sent to the client anymore.

The following is a simple RDP example program:

Configuration File

*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        
# TCS Type Service provided by UCS
REAL                 SVRNAME = ucssvr
UNREAL               SVRNAME = ucssvr

Client Program

#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();
}

Server Program

<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++;
                }
            }
        }
}