RDP 사용 예제
본 장에서는 RDP 프로그램 사용 예제에 대해 설명한다.
1. 클라이언트 대 서버 프로그램
다음은 간단한 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++; } } } }