페이지

2016년 3월 15일 화요일

pvserver 프로그램 구조 및 프로젝트 폴더 내용

서론

 Qt 에 친숙한 프로그래머라면 project 파일의 내용이 Qt 와 거의 동일하다는 것을 단번에 알아챘을 것이다. Qt에 기초한 개발환경이니까. 당연한 이야기 인가?
 pvbrowser 에 나타나는 GUI 화면은 pvdevelop의 mask, slot에서 코드를 이용하여 실시간으로 처리된다. GUI 화면(UI 와 동일한 개념인가?) 에 있는 버튼을 누르거나. text를 입력하는 것과 같은 동작은 mask에서 실시간으로 처리된다. mask 소스를 살펴보면 showmask 함수 내부에 pvPollEvent 함수를 이용하여 발생한 이벤트를 처리하고 slot 소스에서 사용할 값을 넘겨 주는 구조인 것을 알 수 있다.
 GUI 화면에 대응하는 mask 소스는 디자이너 모드 편집을 완료하면 자동으로 갱신되므로 가능하면 수정하지 말자. 거의 수정할 필요가 없다. 괜히 잘못 수정하면 문제만 발생한다. 말은 이렇게 해도 가끔, 진짜 아주 가금 디자이너 위젯 속성 항목의 수정 사항이 제대로 반영되지 않으면 mask 코드를 아주 살짝 손보아야 할 경우가 있기는 하다.
%위젯 속성의 색상 관련 항목이 잘 반영이 되지 않아 mask에서 직접 수정을 한다. 수정을 할 경우 연관된 부분을 모두 수정하여야 한다. 주의 하자...

그림 1.pvsexample 프로젝트

 그림 1의 왼편에 Masknr. 밑에 있는 스핀 박스를 눌러보면 mask넘버가 1 ~11까지 있으니까. 11개의 GUI 화면이 있을 것이라고 짐작하면 된다.(메인 GUI 화면이 아닌 Dialog 창이나 팝업 창도 mask 형태로 만들어 진다.)
mask 와 slot은 1:1 대응관계이다. mask 는 design 화면 구성 및 클라이언트의 event 처리용이며 slot은 발생한 event를 상황에 맞게 처리하는 소스코드 개념으로 생각하면 이해하기 쉬울수도 있다. 우리가 많은 시간을 할애하여야 하는 것은 바로 slot 소스이다.slot 소스는 slotInit, slotNullEvent 와 event 관련 함수들이 들어 있다. 이 함수들을 상황에 맞게 편집하면 원하는 것을 얻을 수 있다.

프로그램 구조

굳이 분류하자면 project 파일, main (source + header), UI(mask + slot)의 세부류로 나눌 수 있다.

PROJECT 파일

 파일명 :  ****.pro

이 파일은 pvserver 프로그램의 소스, 라이브러리, 빌드 방법과 같은 qmake를 사용하여 Makefile을 만들기 위한 내용들이 포함되어 있다. 사용되는 라이브러리는 OS의 종류에 따라 자동 선택되게 되어 있으며, 추가적인 라이브러리를 사용한다면 이 파일에 정의하여야 한다.
project 파일은 자동으로 갱신되므로 가능하면 손대지 않는 것이 좋다.
Qt Creator를 사용해 본 경험이 많으면 알아서 편집하시길...

Main 파일

 파일 : main.cpp, pvapp.h

main.cpp 파일을 간단히 살펴보면 일반적으로 많이 보아온 main() 함수와 pvMain()함수로 간단하게 구성되어 있다.

main() 함수는 서버 프로그램에 새로운 클라이언트가 접속해오면 어떤한 방식으로 클라이언트의 요청을 처리할 지 결정하는 것이 주 내용, 아니 모든 내용이다. 이것은 사용하는 OS의 지원 유무와 밀접한 상관관계가 있다.
 말이 두서없는 것 같은데 간단히 얘기하면 새로운 클라이언트가 서버에 접속하면 새로운 클라이언트의 요청을 처리하기 위해 멀티스레딩 방식으로 할지 새로운 데몬을 실행할지 선택하는 것이다. 새로운 데몬이 일반적으로 더 효과적이지만 데몬 방식을 선택하기 위해서는 사용하는 OS가 inetd(internet service daemon)을 지원하여야 한다. 리눅스는 기본적으로 지원하지만 윈도우는(?)... 윈도우에서 새로운 프로젝트를 생성하면 multithread가 기본이다. 따라서 기본적으로 윈도우는 ineted 방식을 지원하지 않는다.

inetd 방식의 경우 새로운 클라이언트가 접속하면 새로운 daemon 이 실행된다.
multithread 방식의 경우 새로운 클라이언트가 접속하면 새로운 thread를 만들어 준다.

어떤 방식을 선택할지는 project 파일의 DEFINES += USE_INETD (project 마지막에서 2번째 줄)이 선택된 경우 INETD 방식, 선택되지 않은 경우 Multithread 방식이다. ineted 방식을 사용하고자 할 경우 #DEFINES += ~ 앞에 있는 # 을 제거하기 바란다.

pvMain() 함수는 서버에 접속하는 클라이언트를 관리하는 프로그램 영역으로 클라이언트 마다 개별로 만들어 진다. 만들어지는 방식은 스레드 혹은 데몬이다.
접속하는 클라이언트의 URL 확인한 후 창크기, 캡션과 같은 내용을 클라이언트로 보내준 후 클라이언트에서 GUI 화면 전환(Mask 전환)에 대응하기 위한 무한 루프에 들어간다. 클라이언트에서 다른 GUI 화면을 요구하면 무한 루프 내부의 switch 함수를 이용하여 필요한 mask를 보여준다. 서버의 마스크 숫자와 case 숫자가 동일한 것을 확인해 보자. 이 구문은 pvdevelop 프로그램이 자동으로 수정해 주므로 프로그래머가 더 손댈 필요는 없다.
클라이언트와 연결이 끊어지면 생성된 thread(or daemon)은 자동적으로 종료된다.

 pvapp 헤더파일



기본적으로 라이브러리 관련 include 항목이 주석처리 되어 있다. 수동으로 주석을 제거하거나, Rlib 메뉴에서 필요한 라이브러리를 사용할 수 있다. 헤더파일 하부에 보면 int show_mask1(PARAM *p) 항목이 있다. mask를 추가하면 mask의 인덱스 넘버가 순차적으로 증가하면서 추가된다. 자동으로 추가되므로 개별적으로 수정할 필요가 없다.
action 메뉴 팝업창을 보면 mask를 추가하는 항목은 있지만 제거하는 항목은 없다. 필요할 경우 제거할려고 하면 할 수 도 있겠지만, 별의미는 없다. 그냥 사용하지 않으면 된다. 컴파일된 프로그램 용량만 늘어날 뿐....

Mask 파일

Mask 파일은 UI와 연관될 뿐만 아니라 클라이언트에서 요구하는 내용을 처리하는 소스코드다. 개별 Mask 파일은 mask_*.cpp, mask*_slot.h 두개로 구성된다.
mask 추가 후 디자이너 모드에서 위젯을 추가하여 UI 화면을 구성한 후 에디터 모드로 변경하면 수정된 내용이 자동으로 반영된 mask_*.cpp, mask*_slot.h 두개의 화일이 만들어진다.

mask_*.cpp 

UI 화면의 위젯에 대응하는 내용들이 자동으로 만들어 진다. 가능하면 이 파일들은 손대지 않는 것이 신상에 이롭다.

mask*_slot.h

일반적인 헤더 파일 처럼 보이지만, 이 곳에 있는 함수들의 내용을 편집하여야 내가 원하는 동작을 얻을 수 있다.
예를 들면 UI 화면이 맨처음 실행될 때 처리할 내용은 slotInit 함수의 내용을 편집, UI 화면의 이벤트가 발생하지 않으면서 특정 동작을 수행하여야 하는 경우에는 slotNullEvent 함수를,... 기타 필요한 event 함수를 편집하면 원하는 동작을 수행할 수 있다. 만약 추가적인 함수를 정의하고 싶은 경우에는 mask 헤더파일에 새로운 함수를 정의한 후 사용하면 된다.



파일이 만들어진 김에 간단하게 컴파일을 수행해 폴더의 내용이 어떻게 변하는지 확인해 보자.

Make (컴파일)


그림 2. 프로젝트 폴더

현재 작업 중인 프로젝트 폴더를 살펴 보면 그림 2와 같다. 마스크가 2개 이며 아직 컴파일되지 않은 상태이다.
  • pvs.pvproject
    프로젝트를 읽어 들일 때 사용하는 파일
    target, xmax, ymax 값만 지정되어 있다.
  • pvs.pro
    프로젝트 파일, 기본적으로Qt pro 파일과 동일하다.
  • main.cpp
    모듈 Main 선택시 표시되는 파일
  • pvapp.h
    모듈header 선택시 표시되는 파일
  • mask1.cpp, mask2.cpp
    모듈 Masks를 선택할 때 표시되는 파일
  • mask1_slots.h, mask2_slots.h
    모듈 Slots를 선택할 때 표시되는 파일
mask가 추가되면 인덱스넘버가 순차적으로 부여된 .cpp, .h 파일 두 개가 추가적으로 생성된다. 생성된 mask는 pvapp.h 및main.cpp의 필요 부위에 자동으로 추가된다.

그림 3. 프로젝트 폴더 컴파일 후
 그림 3은 컴파일 후 폴더의 내용이다. debug, release 폴더가 새로 생성되었고, Makefile.win, Makefile.win_Debug, Makefiel.win_Release 파일이 만들어져 있다. Action 메뉴의 Make를 누르면 qmake가 실행되며 자동으로 만들어지는 내용이다. 컴파일이 에러 없이 수행되면 release 폴더에 실행파일이 만들어진다.


그림 4. 프로젝트 폴더 MODBUS 데몬 컴파일 후

 그림 4는MODBUS 데몬을 컴파일 한 후 변경된 프로젝트 폴더 내용이다. 데몬을 추가하면 별도의 실행파일과 연관 파일이 생성되는 것을 알 수 있다.
  • modbusdaemon.cpp
  • modbusdaemon.h
  • modbusdaemon.exe
  • modbusdaemon.mkmodbus
 Modbus 통신 프로그램에 관심이 있다면 소스파일(modbusdaemon.cpp, modbusdaemon.h)를 살펴보는 것도 좋을 것이다. 소켓 방식까지 지원된다. modbusdaemon.mkmodbus는 모드버스 설정파일이다. 통신 속도, 통신 방식과 같은 것들을 지정할 수 있다. 만약 설정파일을 변경하였다면 다시 컴파일 하여야 한다. 컴파일 후 생성된 modbusdaemon.exe 가 모드버스 데이터 통신용 데몬 프로그램이다. 서버 프로그램과 별도로 실행 파일이 존재한다.

그림 5.release 폴더
그림 5는 컴파일 후 생성된 release 폴더의 내용이다. main 및 개별 mask* 의 obj 파일과 실행 파일이 만들어져 있다. 이 실행파일을 실행하면 서버가 작동한다.


이상이 대강 둘러본 내용인가...

댓글 없음:

댓글 쓰기