1 / 32

18 장 Practical Network Project

18 장 Practical Network Project. Database Lab 조 성 훈. 목 차. Quote Service Quote Server Program 검토하기 get_tickinfo() 를 통한 시황 정보 얻기 broadcast() 를 통한 시황 정보 브로드케스팅 Client Program 검토하기 데모의 컴파일과 실행 Summary . Quote Service [1]. 문제 같은 정보를 위해 quote server 에 별개의 TCP/IP connection 을 이용

tieve
Download Presentation

18 장 Practical Network Project

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 18장 Practical Network Project Database Lab 조 성 훈

  2. 목 차 • Quote Service • Quote Server Program 검토하기 • get_tickinfo()를 통한 시황 정보 얻기 • broadcast()를 통한 시황 정보 브로드케스팅 • Client Program 검토하기 • 데모의 컴파일과 실행 • Summary

  3. Quote Service [1] • 문제 • 같은 정보를 위해 quote server에 별개의 TCP/IP connection을 이용 • 대역폭 소진의 문제 • 해결책 • 한 로컬 서버 프로그램은 주식 시장 시황을 지속적으로 불러올 수 있음 • 관련된 정보를 로컬 네트워크로 브로드케스트

  4. Quote Service [2] • 주식 시장 시세표 얻기 http://finance.yahoo.com http://finance.yahoo.com 검색 후 페이지

  5. Quote Service [3] • telnet으로 스프레드시트 레코드 얻기 • Spreadsheet data중 한 라인을 얻어옴 • Quote fetch procedure • Finance.yahoo.com에 80 포트로 접속 • GET과 경로명을 입력 • Response로 spreadsheet data의 한 라인을 소켓을 통해 반환 • 소켓을 닫음

  6. Makefile 프로젝트 make 파일 Bcast.c LAN에 시황을 브로드케스팅하는 기능 구현 Connect.c 원격지 인터넷 시황 서버에 연결하는 기능을 구현함 Csvparse.c 반환되는 시황 데이터에 대한 파서 Gettick.c 원격지 인터넷 시황 서버로부터 시황 정보를 불러옴 Load.c Tickers.rc 파일로부터 주식 시장 ticker 심볼을 로드 Misc.c 잡다한 기능들이 구현되어 있음 Mkaddr.c Internet address convenience 기능 Mktwatch.c 시세를 보는 클라이언트 프로그램 Msgf.c Syslog 로깅 기능에 서버 메시지를 기록하는 모듈 Qserve.c 로컬 시황 서버 프로그램을 구현한 모듈 Quotes.h 모든 소스 모듈에 공통되는 헤더 파일 Tickers.h Ticker 심볼들의 목록에 대해 조사되는 파일 Quote Service [4] • 소스 파일 리스트

  7. Quote Server Program 검토하기[1] • Qserve.c 소스 모듈 • Quote server 자체에 main 프로그램 형성 • 주식 시장 시황을 얻는 역할 수행 • Local Area Network에 시황 정보 브로드케스팅

  8. Quote Server Program 검토하기[2] • 순서도 시작 getopt()호출 옵션 해석 Tickers[]에 Tickers.rc 로드 load()호출 브로드케스트 어드레스 생성 mkaddr()호출 socket()호출 UDP 소켓 생성 서버 루프 Ctrl+C 소켓에 특성 부여 종료

  9. Quote Server Program 검토하기[3] • 강조 사항 • 옵션 –a, -b 채용 • 변수 cmdopt_a과 cmdopt_b에 저장됨 • static char *cmdopt_a = DFLT_SERVER; //10라인 • static char *cmdopt_b = DFLT_BCAST; //13라인 • 모니터되는 주식 시세표는 tickers[]에 유지됨 • ntick: entry의 수 • static TickReq tickers[MAX_TICKERS]; //18라인 • static int ntick = 0; //19라인

  10. Quote Server Program 검토하기[4] TickReq 구조체 typedef struct { char ticker[TICKLEN+1]; /* Symbol */ double last_trade; /* Last Price */ char *date; /* Date */ char *time; /* Time of Last Trade */ double change; /* +/- Change */ double open_price; /* Opening Price */ double high; /* High Price */ double low; /* Low Price */ double volume; /* Volume of Trades */ int flags; /* Server flags */ time_t next_samp; /* Time of next evt */ } TickReq;

  11. Quote Server Program 검토하기[5] • Usage() • -h 옵션일 때 request에 대한 사용 정보를 제공함 //24~36라인 static void usage(void) { printf("Usage: %s [-h] [-a address:port]\n" "where:\n\t-h\t\tRequests usage info.\n" "\t-a address:port\tSpecify the server\n" "\t\t\taddress and port number.\n" "\t-b bcast:port\tSpecify the broadcast\n" "\t\t\taddress and port number.\n", command); }

  12. Quote Server Program 검토하기[6] • 서버 루프 단계(1) • Next time(tn): 0으로 초기화(현재 시간: td) • tn=0; time(&td); //144 ~ 145라인 • Ticker[]의 처음부터 끝까지 반복 • for ( x=0; x<ntick; ++x ) //151라인 • tm: ticker를 갱신하는 동안 잠시 멈출 시간 표시 • 5초씩 5분 미만까지 증가 • If(tm < (time_t) 5 * 60) tm+=5; //209 ~ 210라인 • 이벤트 시간이 tn에서 발견될 경우 • 비활성 시간 계산 후 변수 zzz에 배정 • sleep()호출 If(!tn) tn =td +tm; // 218 ~ 223라인 If(tn>=td) if ((zzz=tn-td)) sleep(zzz);

  13. Quote Server Program 검토하기[7] • 서버 루프 단계(2-1) • Ticker[] 엔트리들은 flag들을 멤버로 포함함 • Flag FLG_UNKNOWN이 설정  ticker가 알려지지 않음 • Flag FLG_ERROR가 설정  에러 발생 • if ( tickers[x].flags & FLG_UNKNOWN || tickers[x].flags & FLG_ERROR ) continue; //157라인 • td의 현재 시간과 ticker[x]의 다음 이벤트 시간과 비교됨 • 같다면, ticker에 새로운 시황을 가져올 시간 의미 • if ( td >= tickers[x].next_samp ) { z = get_tickinfo(&tickers[x],cmdopt_a); • Get_tickinfo() • ticker 심볼에 대한 ticker 정보를 얻기 위해 호출됨

  14. Quote Server Program 검토하기[8] • 서버 루프 단계(2-2) • 다음 이벤트 시간은 현재 시간과 추가한 시간 주기 tm으로 계산됨(5분을 최대로 해서 증가) • time(&tickers[x].next_samp); //184 라인 • tickers[x].next_samp += tm; //185 라인 • 시황 정보 fetch가 성공했는지 알아보는 테스트 • 성공했다면, 정보들을 local area network의 클라이언트에 전송함 • if ( !z ) //191 ~ 195 라인 broadcast(s,&tickers[x],(struct sockaddr *)&bc_addr, bc_len); • Ticker[]에 있는 모든 시황 정보 표시 심볼들이 처리될 때까지 x를 증가시켜 2-1, 2-2단계 반복

  15. Get_tickinfo()를 통한 시황 정보 가져오기[1] • Quote.h • 매크로 알아보기 • DFLT_SERVER • Default hostname과 시황에 대한 접속 port 정의 • #define DFLT_SERVER “finance.yahoo.com:80” //25 라인 • DFLT_BCAST • Default broadcast address 정의(loopback 허용) • #define DFLT_BCAST “127.255.255.255:9777” //30 라인 • Parm 구조 • C 데이터 타입으로 해석한 정보를 조정하여 형 정의 • Typedef struct { char type; void * parm; } Parm; //35~38 라인

  16. Get_tickinfo()를 통한 시황 정보 가져오기[2] • TIMEOUT_SECS • 10초로 설정 • 응답 전에 시황 정보에 대한 wait time을 정의 • #define TIMEOUT_SECS 10 • MAX_TICKERS • Qserve.c 모듈에 있는 tickers[]의 크기 정의 • #define MAX_TICKERS 256 // 53 라인 • TickReq • 서버에 대한 ticker 심볼 entry 정의 • 클라이언트 프로그램에서 사용됨 • FLG_UNKNOWN & FLG_ERROR • Unknown과 에러에 해당하는 flag

  17. Get_tickinfo()를 통한 시황 정보 가져오기[3] • Gettick.c의 주요 컴포넌트 정의 • Timeout FLAG f • TRUE  request가 timeout • Static int f = FALSE; • 신호 캐처 함수(sig_ALRM()) • 시간이 만료되었을 때 SIGALRM 신호를 받음 • f를 설정함 • Static void sig_ALRM(int signo) { f=TRUE; }

  18. Get_tickinfo()를 통한 시황 정보 가져오기[4] • Get_tickinfo() • 매개변수 : TickReq 포인터와 server address • 매개변수 테이블이 parms[]에 형성됨 //52 ~ 69 라인 parms[0].type = 'S'; /* String */ parms[0].parm = &tkr; /* Ticker name */ … parms[8].type = 'D'; parms[8].parm = &req->volume; • SIGALRM에 대한 신호 처리 초기화 //74 ~ 77 라인 sa_new.sa_handler = sig_ALRM; sigemptyset(&sa_new.sa_mask); sa_new.sa_flags = 0; sigaction(SIGALRM,&sa_new,&sa_old);

  19. Get_tickinfo()를 통한 시황 정보 가져오기[5] • f가 FALSE로 초기화되어 타이머가 시작됨 • 연결 request • quotation server의 주소로 connect()를 호출하여 생성 • s = Connect(addr); • if ( s == -1 ) goto errxit; • GET request 지정 • sprintf(buf,"GET /d/quotes. csv?s=%s&f=sl1d1t1c1ohgvs=%s&f=sl1d1t1c1ohgv&e=.csv\r\n“, req->ticker); // 96 ~ 100 라인 • GET request가 quotation server에 입력 • write(s,buf,strlen(buf));

  20. Get_tickinfo()를 통한 시황 정보 가져오기[6] • Spreadsheet 레코드를 기다리고 읽음 do { z = read(s,buf,sizeof buf); } while ( !f && z == -1 && errno == EINTR ); //108~110 • Error 발생했을 경우 er 변수에 errno 값을 저장 er = errno; // 112 라인 • 타이머를 취소하고 소켓을 닫음 • Close(s); • SIGALRM 신호에 대한 신호 처리를 되돌림 sigaction(SIGALRM,&sa_old,NULL); //117 라인 • Timeout이나 에러 처리 • Msgf() 호출이나 syslog 로깅 기능 통해 error 기록

  21. Get_tickinfo()를 통한 시황 정보 가져오기[7] • 캐리지 리턴이나 라인피드 제거 • Spreadsheet 레코드에서 제거됨 • Ticker 심볼이 unknown일 때의 시퀀스 테스트 if ( strstr(buf,"N/A,N/A,N/A,N/A,N/A") ) { msgf('e',"Unknown Ticker: '%s'", req->ticker); req->flags |= FLG_UNKNOWN; errno = EBADMSG; /* For caller */ return -1; /* Failed */ }

  22. Get_tickinfo()를 통한 시황 정보 가져오기[8] • Ticker 심볼이 known일 때의 시퀀스 테스트 • Spreadsheet 레코드 해석 if ( (z = extract_parms(parms,9,buf)) < 0 ) { /* Report failed parse of data */ msgf('e',"Field # %d: '%s'",z,buf); req->flags |= FLG_ERROR; errno = EBADMSG; /* For caller */ return -1; /* Failed */ } // 152 ~ 158 라인 • Ticker 심볼 자체가 req->ticker 엔트리에 복사 strncpy(req->ticker,tkr,TICKLEN)[TICKLEN] = 0; //161 라인 • Req 멤버가 새로운 ticker 정보로 갱신됨 의미 Return 0; // 166 라인

  23. broadcast()를 통한 시황 정보 브로드케스팅[1] • Server의 broadcasting • broadcast() • 관련 클라이언트에 정보 공유를 위해 호출함 • Broadcast()의 기본 단계 • buf[2048] • 브로드케스트 데이터그램을 지정하기 위해 사용 • char buf[2048]; /* Buffer */ • char *cp = buf; /* Buf. ptr */ • buf[]에 null로 끝나는 ticker 심볼을 복사하여 데이터그램 생성 • strcpy(buf,quote->ticker); // 21 라인 • Cp에 새로운 포인터 지정 • cp = buf + strlen(buf) + 1; // 22 라인

  24. broadcast()를 통한 시황 정보 브로드케스팅[2] • Last_trade값 지정 • sprintf(cp,"%E",quote->last_trade); //23 라인 • Cp의 위치 지정 • cp += strlen(cp) + 1; // 24 라인 • 다른 데이터 컴포넌트에 위의 단계 반복 • 각각의 컴포넌트는 null로 끝나는 문자열 • 데이터그램의 길이 계산 • msglen = cp - buf; //40 라인 • Sendto() • 소켓 s에 데이터그램을 브로드케스트하기 위해 호출 • z = sendto(s,buf,msglen,0,bc_addr,bc_len); // 45 라인

  25. Client Program 검토하기[1] • Client program • Mktwatch • 브로드케스트 어드레스로 바인드되야만 함 • 브로드케스트된 주식 시황을 수신 • 특성 • 커멘드라인 옵션 해석 (81 ~ 100 라인) • 브로드케스트 어드레스 생성 ( 105 ~ 118 라인) • UDP 소켓 생성 (123 ~ 129 라인) • SO_REUSEADDR 옵션이 enable됨(135 ~ 146 라인) • 하나 이상의 클라이언트에서 같은 호스트의 정보를 수신할 경우 설정

  26. Client Program 검토하기[2] • 브로드케스트 어드레스로 연결됨(151 ~ 160 라인) • 루프에 대한 클라이언트 listening 시작 • Ctrl+C를 할 때까지 반복 • 클라이언트의 listening 시작 뒤의 단계 • 도착할 데이터그램 기다림 • 수신 데이터그램은 qserve server 브로드케스트 메시지 • Extract() • 데이터그램에 포함된 모든 문자열 데이터 추출 • Tkr에 변환된 데이터 저장 • if ( !extract(dgram,&tkr) ) // 188 라인 • 종료까지 반복 수행

  27. 데모 컴파일과 실행[1] • 컴파일 • 2개의 실행 파일 • Qserve: quotation server program • Mktwatch: broadcast listener client

  28. 데모 컴파일과 실행[2] • Qserve quotation server 시작하기 • 디폴트 루프백 파라메터를 통한 서버 프로그램 실행 • 127.255.255.255:9777 • 디폴트 브로드케스트 어드레스와 port 번호 • 인터페이스 브로드케스트 어드레스를 통한 실행 • 두 경우 모두 finance.yahoo.com에 접속 후 브로드케스팅 시작함

  29. 데모 컴파일과 실행[3] • 에러 보기 • /var/log/messages 로그 파일에 서버 에러 기록됨 • 34 ticker 심볼이 tickers.rc로부터 로드됨

  30. 데모 컴파일과 실행[4] • Mktwatch client 시작하기 • Qserve 디폴트 사용시 • $ ./mktwatch • Qserve에 브로드케스트 어드레스 지정했을 경우 • $ ./mkwatch –b 192.168.0.255:9777

  31. 데모 컴파일과 실행[5] • Finance.yahoo.com 서비스 변경 시 • 새로운 server 어드레스를 쓰기 위해 –a 이용 $ ./qserve –a new.server.com:80 & [1] 821 • Port 번호 80 : 필수

  32. Summary

More Related