Snap1.pngSnap2.pngSnap3.pngSnap4.pngSnap5.pngSnap6.pngSnap7.png

'Programming > 이것저것' 카테고리의 다른 글

MTU  (0) 2010.03.18
ICMP  (0) 2010.03.18
OSI 7Layer  (0) 2010.03.18
광역 변수  (0) 2010.03.18
Virtual Function  (0) 2010.03.18

프로토콜은 한마디로 통신규약입니다.

예를 들자면:

SERIAL , 페러렐 (예전 프린터에서 많이 사용하던 방식), IEEE방식,USB,ETHERNET등

다양하지요.

그리고 프로토콜군이라 함은

각각의 통신에도 세분화가 많이 되어 있는데 (SERIAL도 RS-232,RS-422,RS-485등,

USB 1.0, 1.1, 2.0등) 이걸 세분화 하지 않고 집단으로 총칭하는 것을 프로토콜군이라고 표현하는 듯 하네요.


장비나 컴퓨터를 만드는 회사들은 세계에 수도 없이 많은데 서로 통신함에 있어서 규칙을 만들어서 범용화를 시키고 발전시키면서 오늘날에 도달한것입니다.

컴퓨터 발전에도 이 프로토콜이 없었다면 훨씬 뒤쳐진 발전을 했으리라 생각됩니다.


다 타이핑하자면 기니까 아래 기술 문서를 퍼왔으니 참조하시기 바랍니다.



그리고  OSI7계층에 대한 설명도 아래에 있으니 참조바랍니다.


프로토콜의 정의:


정보기기 사이 즉 컴퓨터끼리 또는 컴퓨터와 단말기 사이 등에서 정보교환이 필요한 경우, 이를 원활하게 하기 위하여 정한 여러 가지 통신규칙과 방법에 대한 약속 즉, 통신의 규약을 의미한다.

통신규약이라 함은 상호간의 접속이나 절단방식, 통신방식, 주고받을 자료의 형식, 오류검출방식, 코드변환방식,전송속도 등에 대하여 정하는 것을 말한다. 일반적으로 기종()이 다른 컴퓨터는 통신규약도 다르기 때문에, 기종이 다른 컴퓨터간에 정보통신을 하려면 표준 프로토콜을 설정하여 각각 이를 채택하여 통신망을 구축해야 한다. 대표적인 표준 프로토콜의 예를 든다면 인터넷에서 사용하고 있는 TCP/IP가 이에 해당된다.

정보통신의 상대방은 일반적으로 원격지에 있다. 따라서 정보를 전송하기 위해서는 정보를 전기적인 신호의 형태로 변환하고 그 변환된 신호가 통신망을 통해 흐르도록 하는데, 통신망에는 정상적인 신호의 흐름을 훼방하는 여러 가지 현상이 존재하게 된다. 이러한 현상은 정확한 정보의 전송을 방해하여 도중에 오류가 발생되는 원인이 된다.

프로토콜이라는 규약의 집합 속에는 이러한 오류에 대응하기 위한 약속이 대단히 중요하다. 또한 정보를 정확하고 효율적으로 전송하기 위해서는 송수신 개체 간에 서로 정보의 전송 시점과 수신 시점을 맞추는 일(동기화)도 수행해야 하고, 정보 흐름의 양을 조절하는 흐름 제어방법도 역시 사전에 약속하여 프로토콜 속에 포함해야 한다.

이러한 오류제어, 동기, 흐름제어, 코드변환, 전송속도 등에 대한 약속 이외에도 통신하는 상대방의 위치에 따라 통신 개체가 어느 OSI 계층에 있는 가와 효율적인 정보전송을 위한 기법, 정보의 안전성(보안)에 관한 약속들도 프로토콜의 범주에 포함되어야 한다.


OSI


네트워크는 수많은 컴퓨터와 장비로 이뤄져 있다. 신기한 것은 이들 구성요소들이 모두 말이 통한다는 것. 장비의 개발업체도 다르고 사용하는 운영체제도 다르지만, 네트워크를 통해 서로 통신을 할 수 있는 것은 바로 프로토콜 때문이다. 때문에 프로토콜은 네트워크가 성립되기 위한 가장 기본적이 요소 중 하나다.
이제 일반명사라고 해도 과언이 아닐 정도로 많이 사용되는 프로토콜은 원래 외교협약같은 좀더 고상한 용어다. 즉 말이 통하지 않는 두 장비가 의사소통을 하기 위한 절차나 규칙 등을 체계적으로 정리해 놓은 것이다.


OSI 참조모델에 대한 오해
초기의 네트워크 역시 프로토콜에 따라 통신을 했다. 하지만 OSI 7계층 참조모델(Open System Interconnection Reference Model)이 등장하기 전까지의 네트워크 프로토콜은 IBM의 SNA나 DEC의 DECNet처럼 특정 업체가 자사의 장비들을 연결하기 위해 만든 것들이었다. 따라서 서로 다른 네트워크 간에는 호환되지 않는다는 한계를 갖고 있었다.
OSI 7계층 참조모델은 이런 문제를 해결하기 위해 ISO가 제정한 것이다. OSI 참조모델은 네트워크 통신의 전 과정을 7계층으로 나누고, 각 계층마다 일정한 역할을 수행하도록 해 하나의 네트워크 통신이 완성되는 과정을 나타낸 것이다. 말 그대로 “이런 식으로 프로토콜을 만들면 서로 호환될 수 있으니, 프로토콜들은 이것을 참조하라”는 것이다. 
OSI 참조모델에 대한 가장 큰 오해는 바로 모든 네트워크 프로토콜이 OSI 참조모델에 따라 7계층 구조를 갖고 있을 것이라고 생각하는 것이다. 
네트워크는 목적에 따라 두세 단계의 프로토콜만으로도 원하는 통신을 할 수 있다. 따라서 억지로 7단계로 통신 절차를 나눌 필요는 없다. 실제로 우리가 사용하는 네트워크 프로토콜과 OSI 참조모델이 직접적으로 대응되는 경우는 그리 많지 않으며, 많은 프로토콜이 OSI 참조모델의 여러 계층에 걸친 기능을 제공한다. “이 프로토콜은 3~4계층에서 동작한다”는 말을 많이 듣게 되는 것도 이 때문이다. 
이런 특징 때문에 OSI 참조모델은 초보자가 네트워크를 이해하는 데 더없이 훌륭한 교재가 되고 있다. OSI 참조 모델은 실제 네트워크 프로토콜을 이해하기 쉽도록 만들어, 네트워크 프로토콜의 역할과 구조, 나아가 네트워크의 동작 방식을 쉽게 이해할 수 있도록 해준다.


계층화된 프로토콜의 역할
(표 1)은 OSI 참조 모델을 정리한 것이다. 여기서 가장 아래 부분인 물리 계층부터 각각의 계층마다 고유의 작업들이 정의돼 있다. 
또한 각 계층은 반드시 자신의 영역에서 운영되는 하위 계층을 통해 서비스를 받고, 상위 계층으로 서비스를 제공하도록 규정돼 있다. 예를 들면 3계층의 네트워크 계층은 2계층인 데이터링크 계층을 통해 서비스를 받고, 상위 계층인 전송 계층에 작업한 내용을 서비스하는 식이다.
한편 각 계층은 전송 데이터에 각 계층에서의 요구 조건과 처리 정보를 포함한 헤더라는 고유의 제어 정보를 전달 메시지에 추가해 다음 계층으로 보내며, 수신측의 동일 계층에 의해 해석돼 처리된다. 예를 들면 송신측 컴퓨터의 5계층에서 추가된 헤더는 수신측 컴퓨터의 5계층에서 해석되며, 해석된 헤더는 지정된 작업을 수행한 다음 제거된 상태로 다음 계층으로 넘어가, 최종적으로 수신측 컴퓨터에는 데이터만 전송된다.
이때 각 계층 간에 전달되는 데이터의 단위는 계층에 따라 서로 다른 이름으로 불리며, 이를 ‘서비스 데이터 단위’라고 한다.
프로토콜이 데이터를 전송하기 위해 사용하는 기본 단위를 PDU(Protocol Data Unit)라고 한다. 즉, 물건을 운반할 때 상자 단위로 포장해 운반하는 것과 같이 프로토콜은 정보의 운반을 위해 PDU라는 상자를 이용하는 것이다. 
상자 단위로 물건을 포장해서 운반할 때 상자마다 물품의 내용이나 발송처, 수신처 등을 표기하는 것과 마찬가지로 PDU에도 사용자 정보뿐만 아니라 데이터의 발신처와 수신처에 대한 주소 정보와 전송 중에 에러가 발생했는지 확인하기 위한 패리티, 그밖에 흐름 제어 등을 위한 각종 정보가 함께 들어간다.
계층화된 프로토콜에서는 계층마다 PDU 이름을 독특하게 붙여 사용하는 경우가 있다(표 2). 2계층 PDU는 프레임(Frame), 3계층 PDU는 패킷(Packet), 4계층 PDU는 세그먼트(Segment) 등으로 부르는 것이 일반적이다. 그리고 특별한 이름이 없는 경우에는 그냥 몇 계층의 PDU라고 부른다. 특히 세그먼트라고 불리는 4계층 PDU는 TCP에서 사용하는 경우가 많다.



TCP/IP와 OSI 참조 모델
일반적으로 가장 많이 사용되는 TCP/IP를 통해 OSI 참조 모델과 프로토콜에 대해 알아보자.
TCP/IP는 좁은 의미로는 1969년 미국방부가 제시한 ARPNET (Advanced Research Projects Agency NETwork)에서 제안한 프로토콜의 집합 중 인터네트워킹에 대한 핵심적 기능을 제공하는 TCP와 IP만을 지칭한다. 하지만 OSI의 3계층에서 7계층까지 해당 소프트웨어나 서비스 관련 프로토콜을 통틀어 얘기할 때도 사용한다.
TCP/IP는 3계층 프로토콜인 IP와 4계층 프로토콜인 TCP가 합쳐진 용어다(그림 2). 네트워크 계층에 해당하는 IP는 네트워크 환경에 흩어져있는 여러 노드 중에서 지정된 목적지를 찾아가는 경로를 설정하는 작업을 수행하고, TCP는 안정된 데이터 전송을 위해 흐름과 오류를 제어하는 역할을 맡는다.
TCP 외에 또 다른 4계층 프로토콜 중 하나인 UDP(User Datagram Protocol)는 TCP와는 달리 데이터의 신뢰성있는 전송을 보장하지는 않는다. 그러나 신뢰성이 매우 높은 회선을 사용하거나 데이터의 확실한 전송을 요하지 않는 통신, 또는 한번에 많은 상대에게 메시지를 전송할 경우에는 보다 효율적이다.
일반적인 고속 이더넷 환경에서 FTP를 통해 서버에 접속하는 경우를 OSI 참조 모델을 통해 생각해 보자. 우선 클라이언트의 FTP 클라이언트는 애플리케이션 계층의 프로토콜인 FTP 규격에 맞춰 데이터에 헤더를 붙여 하위 계층으로 전송하고, 4계층 TCP 프로토콜이 수신측 서버의 4계층과 통신을 통해 데이터의 정합성을 테스트하고 오류가 있을 경우 재전송을 하는 등의 일을 처리한다. 또한 3계층에서는 IP 어드레스를 통해 송신측이 특정 수신측을 지정하고 경로를 설정한다.
그 아래의 2계층과 1계층에서는 두 노드 사이의 물리적인 연결과 디지털 데이터를 전기적인 신호로 변환해 전송하고 신호가 약할 경우에는 증폭하는 등의 일을 처리한다.



OSI 참조모델의 계층별 이해


물리 계층
OSI 7계층 참조 모델의 1계층은 물리 계층이다. 이 계층에서 담당하는 것은 네트워크 케이블과 신호에 대한 것으로, 물리적 신호(bit)의 전송 규칙을 조정하는 역할을 한다.
물리 계층은 전송 매체에 대한 규정은 정하지 않지만, 이를 구현하는 방법적인 면에서는 전송 매체와 깊은 관계를 맺고 있다. 참고로 물리 계층과 관련된 네트워크 연결 장비들은 다음과 같다.


- 허브나 리피터 등의 전기적 신호를 재발생시키는 장비
- 각종 커넥터와 같은 전송 매체 연결 소자 등의 기계적인 연결 장치
- MODEM, CODEC 등 디지털/아날로그 신호 변환기


기본적으로 네트워크는 일대일 또는 멀티 포인트 방식으로 연결된다. 잘 알고 있듯이 일대일 방식은 두 통신 장비들이 직접 연결된 상태를 말한다. 이런 식으로 연결하면 회선을 전용으로 사용할 수 있으므로, 장비간 정해진 전송 용량과 대역폭을 보장받을 수 있다. 한편 멀티 포인트 연결은 3대 이상의 장비를 연결하는 방식을 말한다. 이 방식은 같은 주파수대를 공유하며, 전송 매체에 연결된 모든 장비가 전체 기능을 공유할 수 있다. 일반적으로 대규모 네트워크를 구축할 경우에는 일대일 연결과 다중점 방식을 적절히 혼합하는 방식으로 설계한다.
이 같이 다양하게 연결된 네트워크의 형태를 토폴로지라고 부른다. 즉, 어떤 형태나 구조로 연결된 것을 네트워크 토폴로지(Network Topology)라고 이해하면 된다. 단, 눈으로 보이는 물리적인 토폴로지 형태가 논리적으로는 동일하지 않을 수도 있다. 일반적인 토폴로지에는 버스형(Bus), 링형(Ring), 스타형(Star), 메시형(Mesh), 셀룰러형(Cellular) 등이 있다.
1계층에서는 이외에도 전기적인 펄스나 광학적인 방법 또는 전자기적 파동을 통해 신호를 전달하는 방법에 대한 정의도 수행하며, 동기화 방식, 대역폭 등에 대한 개념을 정의한다.


데이터 링크 계층
OSI 참조 모델의 두 번째 계층인 데이터링크 계층은 데이터 패킷을 생성하고 전송하는 방법을 규정하는 프로토콜에 대한 계층이다. 이 계층이 하는 일은 물리 계층에서 넘어오는 데이터의 오류를 검사하고 복구 기능을 담당할 뿐 아니라, 시스템 간 전송 속도 차에 의한 오류나 흐름 제어까지 도맡아 처리한다. 쉽게 얘기하자면 화물을 트럭에 싣고, 각 트럭을 고속도로로 보내며 화물이 무사히 목적지에 도착하도록 관리하는 역할을 담당한다.
다른 모든 계층과 마찬가지로 데이터링크 계층 또한 고유의 식별 정보를 전송 데이터 앞에 붙이고 있다. 이 정보에는 수신자와 송신자(물리적 또는 하드웨어적인)의 어드레스와 프레임 길이, 그리고 상위 계층의 정보가 포함돼 있다. 이 계층에 속하는 네트워크 연결 장비로는 브리지, 지능형 허브 등을 들 수 있다.
데이터 링크 계층의 여러 기능은 대개 MAC(Media Access Control)과 LLC(Logical Link Control)의 두 가지 계층으로 다시 세분화할 수 있다. MAC 계층은 동일 채널을 공유하는 통신 방법을 제어하기 위한 것이고, LLC 계층은 데이터 전송을 위해 각 장비들을 논리적으로 연결하고, 연결을 유지하는 역할을 담당한다.


네트워크 계층
네트워크 계층은 여러 개의 독립적인 네트워크 사이에서 데이터 전송에 관한 계층이다. 앞서 설명한 데이터링크 계층의 데이터 전송은 물리적인 장치의 어드레스 지정을 통해 단일 네트워크로 연결된 모든 장치에 데이터를 브로드캐스팅하며, 수신측 장비에서 확인해 자신에게 오는 데이터를 수신받는 방식이다. 
그러나 네트워크 계층에서는 네트워크와 네트워크를 연결하는 인터네트워킹 환경에서 특정 경로를 선택해 권한이 없는 네트워크에 데이터를 전송하는 것을 미연에 방지할 수 있다. 또한 서로 다른 네트워크로 구성된 인터네트워킹을 통해 올바른 데이터 경로를 보장할 수도 있다. 네트워크 계층에서는 기본적으로 다음과 같은 사항을 수행한다.


- 논리적으로 분리된 모든 네트워크에 고유한 네트워크 어드레스를 부여한다.
- 인터네트워크를 통해 컴퓨터와 라우터가 최적의 데이터 경로를 결정하도록 라우팅을 구현한다.
- 네트워크는 인터네트워크 내에서 예상되는 오류의 개수에 따라 서로 다른 단계의 연결 서비스를 구현한다.


전송 계층
전송 계층은 복잡한 하위 계층 구조를 상위 계층이 알 필요가 없도록 감추기 위한 계층이다. 여기서는 상위 계층의 메시지를 세그먼트화한 후, 이 세그먼트를 세션 계층이나 상위 계층 프로세스에게 신뢰성 있게 전달하는 역할을 한다. 전송 계층은 하위 계층에서의 신뢰성이 모자라는 연결 서비스나 연결 지향 연결 서비스가 갖는 미비점을 해소하기 위한 역할을 수행한다. 여기서 신뢰성이 보장된다는 말은 데이터가 항상 전달된다는 것을 의미하지는 않는다. 
예를 들어 케이블이 끊어졌을 경우에는 데이터의 전달을 보장할 수 없다. 만일 어떤 데이터가 수신측 장치에게 올바르게 전달되지 않은 경우, 전송 계층은 재전송을 개시하거나 상위 계층에게 이 사실을 통보할 수 있으며, 이에 근거해 상위 계층에서는 필요한 조치를 취하거나 사용자에게 옵션을 제공하게 된다.


세션 계층
세션 계층은 상위 계층에서 필요로 하는 서버 이름과 어드레스를 하위 계층에서 제공되는 논리 어드레스 정보를 사용해 식별할 뿐 아니라, 서비스 제공자와 요청자 간을 연결하고 대화를 개시하는 역할을 담당한다. 이 기능을 수행하는 경우 세션 계층은 각 네트워크 구성 요소를 소개하거나 식별해내며 액세스 권한을 조정하기도 한다.


프리젠테이션 계층
프리젠테이션 계층은 변환과 암호화를 통해 데이터를 주고받는 서로 다른 환경의 컴퓨터와 애플리케이션이 데이터를 이해할 수 있도록 돕는 기능을 수행한다.


애플리케이션 계층
사용자로부터 데이터를 받아 하위 계층으로 전달하고, 하위 계층에서 전달하는 데이터를 사용자에게 전달하는 애플리케이션 계층은 여러 가지 실제적인 네트워크 서비스를 제공하는 계층이다.
애플리케이션 계층에는 각각의 네트워크 서비스에 대한 특정한 주제와 기능이 포함된다. 다시 말해, 이 계층 하부에 있는 여섯 계층이 일반적으로 네트워크 서비스를 지원하는 기술과 작업을 포함하는데 반해, 애플리케이션 계층에서는 특정 네트워크 서비스 기능을 수행하는데 필요한 프로토콜을 지원한다.
애플리케이션 계층 프로토콜이 지원하는 서비스로는 네트워크 서비스에 해당하는 파일, 프린트, 메시지, 애플리케이션, 데이터베이스 서비스 등이 포함된다. 
OSI 7계층을 만든 이유는 프로토콜을 체계적으로 연구하기 위한 목적 외에도, 공용으로 사용할 수 있는 공개된 프로토콜을 만들기 위한 것도 있었다. 그러나 7계층이 발표된 시점에 이미 많은 프로토콜이 사용되고 있었고, 특히 WAN에서는 TCP/IP가 표준으로 자리잡아 독보적인 위치를 확보하고 있었다. 
그 이후, 1계층과 2계층에서는 이더넷, 3계층과 4계층에서는 TCP/IP, NetBEUI, IPX 등이 업계 표준으로 자리잡았다.
한편 5, 6, 7계층은 각각이 별도로 구현되기보다는 통합된 형태의 서비스라는 이름으로 제공된다. 텔넷, FTP, 전자우편(SMTP, POP), HTTP, 뉴스그룹(NNTP), NetBIOS 등이 이와 같은 서비스에 해당한다.

'Programming > 이것저것' 카테고리의 다른 글

ICMP  (0) 2010.03.18
TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18
광역 변수  (0) 2010.03.18
Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18

프로젝트명.sln 파일을 텍스트 에디터로 연후.


------------------------------------------------------------------------------------


Microsoft Visual Studio Solution File, Format Version 10.00 <- Microsoft Visual Studio Solution File, Format Version   9.00 으로 변경


# Visual Studio 2008 <- # Visual Studio 2005 으로 변경


------------------------------------------------------------------------------------


프로젝트명.csproj 파일을 동일하게 텍스트 에디터로 연후


<Reference Include="System.Core">
   <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>


삭제


하단에 Project="$(MSBuildToolsPath) -> Project="$(MSBuildBinPath) 으로 변경


------------------------------------------------------------------------------------

'Programming > tool' 카테고리의 다른 글

01) XP에 DNS 설치  (0) 2010.03.19
IIS, FTP 설치  (0) 2010.03.19
Visual Studio 2008 설정  (0) 2010.03.18
NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18

헐... 예전에 설정 더 해놨었는디..... 어디 간겨ㅠㅠㅠㅠ

이것밖에 없어....ㅋㅋㅋㅋㅋㅋㅋ;;;;;;;;;


1. download the Professor Irvine's assembly source file

2. project.sln open in the \Irvine\Examples\Project_sample

3. 'F7' push compile to Irvine's assembly sourcve



IrvineExamplesVS2008.exe

usertype.dat


syntax highlighting

1. download the "usertype.dat"

2. copy to "\Program Files\Microsoft Visual Studio 9.0\Common7\IDE"

3. visual studio restart


reference

http://kipirvine.com/asm/gettingStarted/index.htm

'Programming > tool' 카테고리의 다른 글

IIS, FTP 설치  (0) 2010.03.19
VS2008로 작성한 프로젝트를 VS2005열기  (0) 2010.03.18
NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18

netioapi.h의 #include <ntddndis.h> 이 부분을


#include "ntddndis.h" 로 바꾼다

'Programming > __etc' 카테고리의 다른 글

고수님들..  (0) 2011.12.15
옴니아 햅틱(진동) 프로그램  (0) 2010.04.05
패킷 만들기  (0) 2010.03.18
  1. #include "stdafx.h"
  2. #include <pcap.h>
  3. /* Ethernet Header Structure */
  4. #define  ETHER_ADDR_LEN 6
  5. typedefstruct ether_header {  
  6.     unsigned char   ether_dhost[ETHER_ADDR_LEN];  
  7.     unsigned char   ether_shost[ETHER_ADDR_LEN];  
  8.     unsigned short  ether_type;  
  9. } ETHER_HDR;  
  10. #define ETHERTYPE_IP            0x0800   /* IP Protocol */
  11. #define ETHERTYPE_ARP           0x0806   /* Address Resolution Protocol */
  12. #define ETHERTYPE_REVARP        0x8035   /* reverse Address Resolution Protocol */
  13. /* IP Header Structure */
  14. typedefstruct ip_hdr  
  15. {  
  16.     unsigned char  ip_header_len:4;  // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
  17.     unsigned char  ip_version   :4;  // 4-bit IPv4 version
  18.     unsigned char  ip_tos;           // IP type of service
  19.     unsigned short ip_total_length;  // Total length
  20.     unsigned short ip_id;            // Unique identifier 
  21.     unsigned char  ip_frag_offset   :5;        // Fragment offset field
  22.     unsigned char  ip_more_fragment :1;  
  23.     unsigned char  ip_dont_fragment :1;  
  24.     unsigned char  ip_reserved_zero :1;  
  25.     unsigned char  ip_frag_offset1;    //fragment offset
  26.     unsigned char  ip_ttl;           // Time to live
  27.     unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
  28.     unsigned short ip_checksum;      // IP checksum
  29.     unsigned int   ip_srcaddr;       // Source address
  30.     unsigned int   ip_destaddr;      // Source address
  31. } IPV4_HDR;  
  32. int _tmain(int argc, _TCHAR* argv[])  
  33. {  
  34.     pcap_if_t *alldevs;  
  35.     pcap_if_t *d;  
  36.     int inum;  
  37.     int i=0;  
  38.     pcap_t *fp;  
  39.     char errbuf[PCAP_ERRBUF_SIZE];  
  40.     unsigned char  packet[1500];  
  41.     /* Retrieve the device list on the local machine */
  42.     if (pcap_findalldevs(&alldevs, errbuf) == -1)  
  43.     {  
  44.         fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);  
  45.         exit(1);  
  46.     }  
  47.     /* Print the list */
  48.     for(d=alldevs; d; d=d->next)  
  49.     {  
  50.         printf("%d. %s", ++i, d->name);  
  51.         if (d->description)  
  52.             printf(" (%s)\n", d->description);  
  53.         else
  54.             printf(" (No description available)\n");  
  55.     }  
  56.     if(i==0)  
  57.     {  
  58.         printf("\nNo interfaces found! Make sure WinPcap is installed.\n");  
  59.         return -1;  
  60.     }  
  61.     printf("Enter the interface number (1-%d):",i);  
  62.     scanf("%d", &inum);  
  63.     if(inum < 1 || inum > i)  
  64.     {  
  65.         printf("\nInterface number out of range.\n");  
  66.         /* Free the device list */
  67.         pcap_freealldevs(alldevs);  
  68.         return -1;  
  69.     }  
  70.     /* Jump to the selected adapter */
  71.     for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);  
  72.     /* Open the output device */
  73.     if ( (fp= pcap_open_live(d->name,            // name of the device
  74.         65536,                              // portion of the packet to capture (only the first 100 bytes)
  75.         0,  // promiscuous mode
  76.         1000,               // read timeout
  77.         errbuf              // error buffer
  78.         ) ) == NULL)  
  79.     {  
  80.         fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]);  
  81.         return -1;  
  82.     }  
  83.     /**************************************************************************************************
  84.     **   윗 부분은 http://heestory.kr/220 을 참조하기 바람                                          **
  85.     **************************************************************************************************/
  86.     memset(packet, 0, sizeof(packet));      // 전송할 패킷을 저장할 버퍼의 초기화
  87.     ETHER_HDR eth;                          // Ethernet Header의 구성을 위한 구조체 선언
  88.     IPV4_HDR ip;                            // IP Header의 구성을 위한 구조체 선언
  89.     int length = 0;                         // 생성된 Packet의 Length를 
  90.     ////////////////////// 2계층인 Ethernet Header를 구성
  91.     // 지금은 테스트를 못해봐서 ... 확인하기는 힘들지만..
  92.     // 예전에 테스트 할 때.. ethernet header의 source mac address가
  93.     // 자신의 mac address와 다를 경우
  94.     // 전송이 막혔던 기억이 있음..(보안상?)
  95.     // 하지만 wireshark 같은 프로그램에서는 캡쳐됨....
  96.     eth.ether_dhost[0] = 0x00;  
  97.     eth.ether_dhost[1] = 0x01;  
  98.     eth.ether_dhost[2] = 0x02;  
  99.     eth.ether_dhost[3] = 0x03;  
  100.     eth.ether_dhost[4] = 0x04;  
  101.     eth.ether_dhost[5] = 0x05;  
  102.     eth.ether_shost[0] = 0x10;  
  103.     eth.ether_shost[1] = 0x11;  
  104.     eth.ether_shost[2] = 0x12;  
  105.     eth.ether_shost[3] = 0x13;  
  106.     eth.ether_shost[4] = 0x14;  
  107.     eth.ether_shost[5] = 0x15;  
  108.     eth.ether_type = htons(ETHERTYPE_IP);               // 3계층의 프로토콜을 지정..
  109.     memcpy(packet, eth, sizeof(eth));                 // 패킷 버퍼에 저장한다.
  110.     length += sizeof(eth);                            
  111.     memset(&ip,0x01,sizeof(ip));            // 귀찮아서 다 0x01로 채움...;;하하하..
  112.     ip.ip_header_len = sizeof(ip)/4;        // wireshark에서 안보여서 header length만 설정
  113.                                             // sizeof(ip)/4 인 이유는
  114.                                             // 1당 4 바이트를 의미하기 때문. 즉 20/4 = 5
  115.     memcpy(packet+length, &ip, sizeof(ip));  
  116.     length += sizeof(ip);  
  117.     if ( length < 64 ) {        // ethernet packet의 최소 size는 64 이다.
  118.         for( i = length ; i < 64 ;i++)  
  119.         {  
  120.             packet[i]=0;  
  121.         }  
  122.     }  
  123.     /**************************************************************************************************
  124.     **   실제 패킷을 전송하는 부분                                                                 **
  125.     **   같은 패킷을 두번 보낸다.(이유 없음..그냥!                                                 **
  126.     **************************************************************************************************/
  127.     /* Send down the packet */
  128.     if (pcap_sendpacket(fp, packet, length /* size */) != 0)  
  129.     {  
  130.         fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));  
  131.         return -1;  
  132.     }  
  133.     /* Send down the packet */
  134.     if (pcap_sendpacket(fp, packet, length /* size */) != 0)  
  135.     {  
  136.         fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));  
  137.         return -1;  
  138.     }  
  139.     return 0;  
  140. }  

'Programming > __etc' 카테고리의 다른 글

고수님들..  (0) 2011.12.15
옴니아 햅틱(진동) 프로그램  (0) 2010.04.05
C2146 구문오류  (0) 2010.03.18

InstallOptions 는 지정한 값을 읽을때 READ 매크로와 WRITE 매크로를 제공합니다.

문법 -

!insertmacro MUI_INSTALLOPTIONS_READ $VAR "ioFile.ini" "Field #" "Name" !insertmacro MUI_INSTALLOPTIONS_WRITE "ioFile.ini" "Field #" "Name" "Value"

아래의 스크립트는 ffdshow.ini 에서 Field 1 값의 state 값을 읽어옵니다. state 값에는 Field 1 컨트롤의 여러 상태가 저장됩니다(컨트롤이 선택되었는지 여부등). 이 값을 1(선택됨) 과 비교하여 같으면 레지스트리를 입력하고 다르면 2번째 명령으로 내려가 레지스트리 쓰기를 건너뛰게 합니다.

!insertmacro MUI_INSTALLOPTIONS_READ $R0 "ffdshow.ini" "Field 1" "State" ; XviD

StrCmp $R0 "1"  0 +2

WriteRegDWORD HKCU SoftwareGNUffdshow xvid 0x00000001

이정도면 InstallOptions 를 이용해 페이지를 추가하는데 별 문제가 없을 듯 합니다.

더 궁금한 사항이 있으시면 글 남겨주세요.


Function .onInstSuccess

!insertmacro MUI_INSTALLOPTIONS_READ $R0 "test01.ini" "Field 3" "State"

WriteRegStr HKLM "${PRODUCT_PRIMARY_KEY}" "text" "$R0"

FunctionEnd

'Programming > tool' 카테고리의 다른 글

VS2008로 작성한 프로젝트를 VS2005열기  (0) 2010.03.18
Visual Studio 2008 설정  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18
라디오버튼 컴포넌트 선택 기능 구현  (0) 2010.03.18

NSIS의 장점 :

파일크기가 작다.

거의대부분의 윈도와 호환된다.

특수한 압축방식으로 최소한의 오버헤드와 따로 자동압축풀림 기능을 사용할 필요가 없습니다.

스크립트 방식으로 인스톨러의 모든 동작을 직접 제어할 수 있습니다.

다국어를 지원합니다.

인터페이스나 대화상자를 편집할 수 있습니다.

필요한 기능은 플러그인으로 추가할 수 있습니다.

웹을 통한 설치, 패치를 지원합니다.

NSIS는 쉽게 하나의 설치마법사에 여러 프로젝트를 통합하거나 라이트, 풀 버전등을 만듭니다.


간단한 NSIS 문법:

NSIS는 기본적으로 간단한 텍스트 파일입니다.

주석 :

";", "#" 이후의 문장은 주석입니다.

/* 와 */ 사이의 문장은 주석입니다.

명령:

명령 (인자)입니다.

예) File "myfile.exe"

플러그인 : 플러그인 이름::명령 (인자)

숫자 :

10진수 - 일반적인 수

16진수 - 앞에0x를 붙입니다.

8진수 - 앞에 0를 붙입니다.

색표현 - HTML 표현방식을 따르지만 앞에 #를 붙이지 않습니다.

문자열 :

'' 와 " 를 모두 사용할 수 있습니다.

"Hi There" -> Hi There

"I''ll be happy" -> I''ll be happy

`And he said to me "I''ll be fucked!"` -> And he said to "I''ll be fucked"

NSIS는 제어문자로 $ 를 사용합니다.

변수 : 변수명 앞에 $를 붙입니다.

- 명령이 긴 경우 명령의 끝에 를 붙인 후 다음 줄에 이어서 적으면 됩니다.



NSIS - Section 이란?

NSIS에 있어서 섹션이란 매우 중요합니다.

섹션은 보통, 다른 설치마법사 제작기에서 다른 이름으로 많이 있습니다.

컴포넌트, 기능(Feature), 구성요소 등으로 말이죠.

이름만 다르고 이들과 하는 일은 같습니다.

즉, 제작자가 어떤 프로그램을 설치하려고 할때 그 프로그램을 구성하는 하나의 구성요소 라고 할 수 있습니다.

파일이 모여서 섹션이 되고 섹션이 모여서 프로그램이 되는거죠.


NSIS - Page 에 대해서...

NSIS로 만들 수 있는 설치마법사 중 대개는 화면에 뭔가 보여주면서 선택을 하게 됩니다. 당연한가요? Page에 관련된 일련의 명령들은 바로 이러한 화면을 제어합니다. 순서, 보여지는 형태, 언어, 동작 등 많은 것들을 제어합니다. 또한, NSIS에서는 NSIS에서 내장해서 자체적으로 제공하는 화면 말고 CustomPage 라고 하여 사용자가 원하는 화면을 만들어서 보여줄 수 있습니다. (InstallOptions 라는 플러그인이 있고, Codec xPack에서 ffdshow 옵션을 설정하는 화면에서 쓰였습니다.)

페이지를 다룰때는 일단 기본적으로 Page, UninstPage(설치제거용) 두가지 명령을 쓰며 Page나 UninstPage의 확장판으로 PageEx라는 명령이 있습니다.

일단 페이지를 만든다고 치면 각 페이지들의 순서를 정해야 할 것입니다. 여기서 NSIS스크립트만의 편리성이 드러납니다. NSIS 스크립트는 위에서 아래로 차례로 순차적으로 실행된다고 언급한 적이 있습니다. 즉, 배열하려는 Page 순서대로 스크립트에서 한줄씩 차례대로 적어주기만 하면 됩니다.

ex) Page license;

Page components

이렇게 적으면 NSIS는 라이센스 화면을 보여주고 다음에 컴포넌트 선택 화면을 보여줍니다.

NSIS에서 자체적으로 제공하는 페이지들.. (license, components, directory, instfiles, uninstConfirm) 입니다. instfiles는 설치/제거 모두에 쓰입니다.

또한 이렇게 순서만 정하면 재미가 없을겁니다. NSIS에서는 이렇게 순서를 정하면서 동시에 간단한 동작이나 형태를 지정해 줄 수 있습니다. 물론, 이렇게 하기위해서는 NSIS의 함수에 대해서 알아야합니다. 또한, Page, UninstPage 의 인자에 대해서도 알아야겠죠.


Page

custom [creator_function] [leave_function] [caption]OR (license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function]

UninstPage

custom [creator_function] [leave_function] [caption]OR (license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function]

입니다.~

질문은 밑에 적어주세요~


Sections

섹션이란 앞에서도 언급했듯이 NSIS란 설치관리자의 핵심을 이루는 것입니다. NSIS는 반드시 하나 이상의 섹션을 포함해야하며 이 섹션들은 아래와 같은 규칙하에 그 밑의 명령들로 관리됩니다.

. 각 섹션은 0개 이상의 명령을 포함합니다. (하나도 없을 수도 있습니다).

. 섹션은 설치마법사에의해 순서대로 실행되며 ComponentText 가 설정되어 있다면 사용자는 각 보이는 섹션을 선택하거나 해제할 수 있습니다.

. 만약 섹션의 이름이 ''Uninstall'' 이거나 섹션 이름앞에 ''un.'' 이라는 접두어를 붙이면 이것은 설치제거때에만 쓰입니다.



- Section Commands

AddSize size_kb

설치관리자에게 현재 섹션이 추가로 ''size_kb'' 키로바이트 만큼 필요하다고 알려줍니다. 이 명령은 오직 섹션에서만 유효합니다.

Section AddSize 500 SectionEnd


Section

[/o] [([!]|[-])section_name] [section index output]

새로운 섹션을 시작합니다. 만약 섹션이름이 빈공간이거나 - 로 시작하면 이 섹션은 숨김 속성을 가져서 사용자에게 보이지 않습니다. 만약 섹션이름이 ''Uninstall'' 이거나 ''un.''으로 시작하면 설치제거 섹션으로 사용됩니다. 섹션 인덱스 출력 변수가 설정되면 이 매개변수는 !defined 매크로에 의해 섹션 인덱스 값이 설정되고 SectionSetText 등의 관리명령에서 사용됩니다. 섹션이름이 !로 시작하면 굵은 글씨로 보이고 /o 를 설정하면 기본적으로 선택해제된 상태가 됩니다.

Section "-hidden section"

SectionEnd


Section # hidden section

SectionEnd


Section "!bold section"

SectionEnd


Section /o "optional"

SectionEnd


Section "install something" SEC_IDX

SectionEnd


SectionEnd

현재 열린 섹션을 닫습니다.


SectionIn

insttype_index [insttype_index] [RO]

이 명령은 현재 섹션이 기본적으로 속하게 될 설치유형을 설정합니다.복합적인 SectionIn 명령은 모두 합해져서 나타납니다. 만약 RO 매개변수를 지정하면 이 섹션은 읽기전용으로 사용자는 상태를 변경할 수 없습니다. 최로 설치 유형은 InstType 명령에 의해 최초 1부터 차례대로 붙어나갑니다.

InstType "full"

InstType "minimal"


Section "a section"

SectionIn 1 2

SectionEnd


Section "another section"

SectionIn 1

SectionEnd


SectionGroup

[/e] Caption [section_group_name index output]

섹셕 그룹이란 섹션들을 포함하는 섹션으로 섹션들을 보기좋게 모아서 나타날 때 사용합니다.섹션 그룹을 설정하며 반드시 SectionGroupEnd 명령으로 닫아야 합니다. 또한 반드시 하나 이상의 섹션을 포함해야 합니다. !로 이름이 시작하면 굵은 글씨체로 나타납니다. /e 를 설정하면 섹션그룹은 펼쳐져서 나타납니다. 만약 섹션이름이 ''un.''으로 시작하면 설치제거 섹션으로 사용됩니다. 섹션 인덱스 출력 변수가 설정되면 이 매개변수는 !defined 매크로에 의해 섹션 인덱스 값이 설정되고 SectionSetText 등의 관리명령에서 사용됩니다.

SectionGroup "some stuff"

Section "a section"

SectionEnd

Section "another section"

SectionEnd

SectionGroupEnd


SectionGroupEnd

섹션그룹을 닫습니다.


Uninstall Section

''Uninstall'' 이라는 특별한 섹션은 설치제거마법사를 생성하기 위해 반드시 만들어야합니다. 이 섹션에서 설치했던 파일, 레지스트리 등을 삭제합니다.

Section "Uninstall"Delete $INSTDIRUninst.exe ; delete self (see explanation below why this works)Delete $INSTDIRmyApp.exeRMDir $INSTDIRDeleteRegKey HKLM SOFTWAREmyApp SectionEnd

제일먼저 Delete 명령으로 설치제거마법사를 삭제합니다. 왜냐하면 설치제거마법사는 윈도 임시 디렉토리로 복사되어 그곳에서 실행되기 때문입니다.설치제거때 $INSTDIR 값은 설치제거마법사가 있는 곳입니다. 반드시 설치마법사가 있는 곳과 같지는 않습니다.

'Programming > tool' 카테고리의 다른 글

Visual Studio 2008 설정  (0) 2010.03.18
NSIS 값 읽어오기  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18
라디오버튼 컴포넌트 선택 기능 구현  (0) 2010.03.18
사용자 페이지 추가하기  (0) 2010.03.18

ps. 같은 페이지에 계속 머무르기

이러한페이지체제는기본적으로지정한 함수에 진입해서 MUI_INSTALLOPTIONS_DISPLAY 를 호출하는 순간 화면에 페이지가 나타나고 그 함수안에서 MUI_INSTALLOPTIONS_DISPLAY 다음에 있는 명령들이 끝나면 다음 페이지로 넘어갑니다. 즉 어떤 조건이 되었을때 다시 MUI_INSTALLTOPTIONS_DISPLAY를 호출해주면 됩니다.


예)

${Do}

  MUI_INSTALLOPTIONS_DISPLAY_RETURN

pop $R0

${While} $R0 != "success"

이런식으로 하면 $R0 의 값이 "success" 가 아닌동안 게속 돕니다



원본 위치 <http://jgh0721.tistory.com/entry/InstallOptions-2-를-이용하여-사용자-페이지-추가하기

'Programming > tool' 카테고리의 다른 글

NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
라디오버튼 컴포넌트 선택 기능 구현  (0) 2010.03.18
사용자 페이지 추가하기  (0) 2010.03.18
실행순서  (0) 2010.03.18

NSIS - Section을 선택할 때 라디오버튼 기능을 넣자!

라디오 버튼 기능을 하려면 몇 가지 순서가 있습니다.

1. Sections.nsh 라는 NSIS에서 제공하는 섹션 관리 헤더파일 참조.

2. 섹션에 섹션인덱스 값을 부여한다.

3. .onInit 함수에 섹션의 선택값을 특정 변수에 저장한다. (주로 $1같은 변수..)

4. .selOnChange 에서 매크로를 이용하여 구현한다.



1.일단 기본적으로 Section 관련 내용을 선언해둔 파일을 집어넣어야 합니다.

!include "Sections.nsh"

이걸로 자신의 스크립트안에 섹션 관리 헤더파일을 집어넣습니다.


2.이제 섹션에 섹션 인덱스 값을 부여해야죠

예) Section "fsfds" abc

이렇게 하면 fsfds라는 섹션에 abc라는 섹션인덱스 변수를 설정한 것 입니다.

NSIS는 abc라는 섹션인덱스 변수를 통해 fsfds에 접근하는거죠

abc는 NSIS에서 쓸때는 ${abc}라고 적습니다.


3. 이제 .onInit 함수를 만듭니다.

예)

Function .onInit

StrCpy $1 ${g1o1}

FunctionEnd

만약, Section "fsfds" abc

Section "qwrqweq" qew

이렇게 두 개의 섹션을 라디오 버튼으로 만들려고 하고 이중에 abc를 기본선택으로 두려면 위와 같이 함수를 만들면 됩니다.


4. .onSelChange 함수를 만듭니다.

Function .onSelChange

!insertmacro StartRadioButtons $1

!insertmacro RadioButton ${abc}

!insertmacro RadioButton ${qew}

!insertmacro EndRadioButtons


FunctionEnd

abc와 qew라는 섹션 인덱스가 어디에 쓰였는지만 보면 쉽게 적용가능합니다.

'Programming > tool' 카테고리의 다른 글

NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18
사용자 페이지 추가하기  (0) 2010.03.18
실행순서  (0) 2010.03.18

이번엔 InstallOptions 플러그인을 사용해 인스톨러에 사용자 페이지를 추가하는 법을 알아보겠습니다.

준비물 : NSIS, HM NIS Edit

NSIS는 당연히 필요하겠구요, HM NIS Edit는 추가할 사용자 페이지를 쉽게 만들어줍니다. 그렇지 않으면 일일이 ini 파일을 직접 수정해서 좌표값 입력해 가며 만들어야합니다. OTL... 굉장한 노가다 입니다.

제가 만든 NSIS 한글 배포본에 HM Nis Edit 가 포함되어 있으니 이걸 사용하시면 됩니다.


일단 추가할 사용자 페이지를 만들어야하니 HM Nis Edit를 실행합니다.

그리고 파일 메뉴에서 인스톨옵션 파일 만들기를 선택하면 아래와 같은 화면이 나타납니다.


이제 위 화면에서 추가할 페이지의 컨트롤등을 넣어주면 됩니다.

작성하면 이제 ini 파일을 저장하고 스크립트에 페이지를 추가하는 명령을 넣으면 됩니다.


페이지를 추가하려면 세가지 과정이 필요합니다.

일단 인스톨러 초기화 콜백함수인 .onInit 함수 에서 ini파일을 임시디렉토리에 풀어줍니다.

두번째로 page 명령으로 페이지를 추가합니다.

세번째로 사용자페이지에서 사용할 함수를 작성합니다.


여기서는 예제로 저의 코덱팩 스크립트를 발췌했습니다.


1) 아래처럼 .onInit 함수에서 ini 파일을 풀어주는 매크로를 추가합니다.

(첫번째 매개변수) ${Codec}ffdshow.ini 파일은 ini파일이 있는 디렉토리이고 (두번째 매개변수) ffdshow.ini 파일은 임시디렉토리에 풀때 사용할 파일명 입니다.

Function .onInit

!insertmacro MUI_INSTALLOPTIONS_EXTRACT_AS "${Codec}ffdshow.ini" "ffdshow.ini"

FunctionEnd


2) Page 명령으로 추가합니다.

아래와 같이 Page custom 명령으로 추가할 페이지를 삽입합니다. 페이지는 순서대로 나타납니다.

여기서는 ffdshow 디코더 설정화면이 컴포넌트 선택화면 다음에 나타나게 됩니다.

custom - 사용자 페이지를 추가한다는 뜻

ffdshow - 사용자 페이지를 나타내는 등의 역할을 하는 함수 이름. 다음에 작성합니다.

!insertmacro MUI_PAGE_COMPONENTS

Page custom ffdshow ; ffdshow 디코더 설정 화면

!insertmacro MUI_PAGE_INSTFILES


3) 이제 마지막으로 ffdshow 함수를 작성합니다.

아래와 같은 형식으로 함수를 작성합니다. 함수이름은 물론 page 명령에서 지정한 이름으로 만들어야합니다. 아래 스크립트에서는 ffdshow 디코더 설정화면이기때문에 ffdshow를 설치할 때만 나타나야 합니다. 그래서 앞의 세개의 명령이 섹션 정보를 얻고 ffdshow 섹션이 선택되었을때만 페이지를 보여줍니다.


매크로 - MUI_HEADER_TEXT - 사용자 페이지의 제목입니다. 자세한 설명은 한글화한 도움말을 참조하세요.

매크로 - MUI_INSTALLOPTIONS_DISPLAY - 이 매크로를 넣지 않으면 ffdshow 함수가 호출되어도 페이지는 보여지지 않습니다. 즉, 보여줄려고 메모리상에 페이지만 만들어놓고 끝나게 되어버리지요. 이때 보여줄 페이지는 아까 MUI_INSTALLTOPTIONS_EXTRACT_AS 매크로에서 두번째 매개변수로 지정한 이름을 적습니다.

Function ffdshow

SectionGetFlags ${ffdshow} $2

IntCmp $2 ${SF_SELECTED} start end end

start:

!insertmacro MUI_HEADER_TEXT 'ffdshow decoder' 'ffdshow decoder 를 사용할 확장자를 선택하세요'

!insertmacro MUI_INSTALLOPTIONS_DISPLAY "ffdshow.ini"

end:

FunctionEnd


이렇게 하면 페이지 추가가 끝납니다.

이제 컴파일하면 페이지가 나타납니다.

이후 페이지에서 지정한 값을 받는 법등은 도움말에 나타나있습니다.


예) 위에서 사용한 ffdshow 에서 사용자 선택한 값을 읽어오는 스크립트 입니다.

'Programming > tool' 카테고리의 다른 글

NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18
라디오버튼 컴포넌트 선택 기능 구현  (0) 2010.03.18
실행순서  (0) 2010.03.18

NSIS 스크립트는 기본적으로 위에서 아래로 순서대로 실행이 된다지만 약간 헷갈리기도 합니다.

컴파일타임명령과 특히 이곳저곳에 섞이는 인스톨러 속성 명령때문이 아닌가 합니다.


--------------

컴파일 타임 명령 - 컴파일되면서 그때 그때 실행되면서 실행 인스톨러에는 영향을 미치지 않습니다.


예로 (현재 디렉토리 c: est est 이고 압축할 파일은 C: est est.exe일때)


Section -PrePare

!cd ..

File 'test.exe'

SectionEnd


이렇게 하면 컴파일러가 컴파일하면서 디렉토리를 한번 상위 디렉으로 이동해서 test.exe 를 압축합니다.


Section -PrePare

File '.. est.exe'

SectionEnd


과 같은 결과입니다. 사실상 거의 쓸일이 없습니다만...

컴파일 타임 명령은 주로 !define 명령이 사용됩니다. 컴파일 타임 명령은 인스톨 속성 명령과 달리 실행 순서가 되야 실행됩니다.


인스톨러 속성 명령

인스톨러를 초기화합니다. 컴파일러는 인스톨 속성 명령을 스크립트 전체를 분석해서 한번에 모아서 적용시킵니다. 즉, 섹션등에 포함되거나 하지만 않으면 스크립트 위치에 상관이 없습니다.

즉, 스크립트 맨위에 Name 명령있거나 맨 뒤에 Name 명령이 있거나 전혀 상관없습니다.


콜백 함수


Function .onInit

인스톨러가 실행되어 초기화가 막 끝난 시점. 보통 인스톨러가 시작되기 전 조건 검사 등을 여기서 검사합니다. (특정 프로그램을 종료시킨다거나. 등등..)


Function .onGUIInit

인스톨러 화면을 메모리에 불러들이고 보여주기 직전


섹션 또는 사용자 함수

섹션이 순서대로 진행되며 섹션에서 함수들을 호출합니다.


Function .onInstSuccess

설치가 끝나고 윈도가 닫히기 직전에 호출

대개 위와 같은 순서를 거칩니다. 중간 중간에 이벤트에 따라 아래와 같은 콜백 함수가 호출되기도 합니다.

-----------


Function .onInstFailed

인스톨 과정 중 언제든지 실패하면 호출됨


Function .GUIEnd

설치화면이 닫힌 직후에 호출됩니다. 설치 성공여부등에 전혀 상관 없습니다. 즉, 컴포넌트 페이지에서 컴포넌트 선택하다가 그냥 취소 눌러서 종료시켜도 화면이 사라질때 호출됩니다.


Function .onMouseOverSection

컴포넌트 선택화면에서 마우스 커서가 섹션위에 위치할 때 호출됩니다.


Function .onRebootFailed

인스톨 중에 Reboot 명령으로 재부팅을 시도했지만 실패하면 호출됩니다.


Function .onSelChange

컴포넌트 페이지에서 선택한 섹션이 변경되면 호출됩니다.

... 등등의 콜백함수가 있습니다. (^^)

'Programming > tool' 카테고리의 다른 글

NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18
같은 페이지에 계속 머무르기  (0) 2010.03.18
라디오버튼 컴포넌트 선택 기능 구현  (0) 2010.03.18
사용자 페이지 추가하기  (0) 2010.03.18

WDK에서는 드라이버에서 사용하기 위한 리스트를 제공한다. 리스트 뿐만아니라

KQUEUE, KDVICE_QUEUE, IO_REMOVE_LOCK, MDL 을 제공하고 있다.

아래는 LIST_ENTRY의 사용 예이다.

Snap2.bmp


참고 사이트: http://groups.google.co.kr/group/endless-creation/web/드라이버에서+링크드+리스트+구현시+참고사항

http://www.pyrasis.com/blog/17

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

Heap 관리자는 메모리 블럭의 크기가 무작위로 결정되기 때문에 인접한 free 블럭을 합치기 위해 많은 CPU 시간을 요구하게 됩니다.


항상 고정된 크기의 메모리 블럭만을 사용한다면 heap을 관리하는데 있어 훨씬 효율적인 방식으로 사용이 가능한데 예를 들면

큰 메모리 블럭을 미리 할당하여, 이를 주어진 크기로 조각냅니다. 블럭이 heap에 리턴되면 실제로 해제하는 것이 아니라 사용이

끝남으로 표시하면서 사용하게 되는데, 이에 대한 몇가지 문제점이 있습니다.


너무 많은 메모리를 할당할 경우는 메모리 낭비를 가져올 수 있고, 너무 적게 할당할 경우는 알고리즘이 동작하지 않거나 더 많은 블럭을 얻으려고 heap 관리자를 너무 자주 사용하게 되는 것입니다.


Microsoft에서는 이러한 단점을 극복하기 위해 lookaside list 객체를 제공합니다.


lookaside list

  1. lookaside list 객체 초기화시 시스템에게 작업할 단위 메모리 블럭의 크기를 알립니다. ( 용량은 운영체제가 탄력적으로 감지합니다. )
  2. 메모리 블럭을 할당하기 위해서 시스템은 일단 하나의 블럭의 제거를 시도합니다.
    1. 더 이상 남은 블럭이 없다면 메모리 pool에서 빼옵니다.
  3. 메모리 블럭을 반환하려면, 시스템은 리스트에 되돌리기를 시도하게 되며, 리스트가 꽉 차면 일반 heap 관리 루틴을 사용해서 pool에 블럭을 되돌립니다.

시스템은 실제 사용에 따라 모든 lookaside list의 depth를 정기적으로 조작합니다.

  • 시스템에 최근 접근하지 않았거나, 총 시간에서 5% 이상 액세스 하지 않은 lookaside list에 대해 depth를 감소 시킵니다.
  • 처음의 새 리스트 값인 4 이하로는 줄어들지 않습니다.
  • driver verifier 실행시는 모든 lookaside list의 depth는 모두 0으로 바뀝니다. ( 메모리 오류와 관련된 드라이버 문제를 발견하기 쉽게 하기 위해서 입니다. )

Lookaside list 지원 함수

Lookaside list를 지원하는 함수는 paged / non-paged 두 분류로 나뉘게 됩니다.

  • ExInitializeNPagedLookasideList  / ExInitializePagedLookasideList : Lookaside list를 초기화 한다.
  • ExAllocateFromNPagedLookasideList / ExAllocateFromPagedLookasideList : 고정된 크기의 블럭을 할당한다.  
  • ExFreeToNPagedLookasideList / ExFreeToPagedLookasideList : 해제해서 lookaside list로 다시 돌려준다.
  • ExDeleteNPagedLookasideList / ExDeletePagedLookasideList : Lookaside list를 삭제한다.


lookaside list 객체를 위해 메모리를 확보하고 나서 적절한 초기화 루틴을 호출합니다.


각 함수에서 첫 번째 인수는 이미 공간을 확보해둔 (N)PAGED_LOOKASIDE_LIST 객체에 대한 포인터입니다. Allocate와 Free는 heap에서 메모리를 할당하거나 해제할 수 있는 루틴들에 대한 포인터 입니다. ExAllocatePoolWithTag와 ExFreePool을 쓸 시에는 이 인수들을 NULL로 하면 됩니다. blocksize 인수는 리스트에서 할당하는 메모리 블럭의 크기를 나타냅니다. tag는 이러한 각 블럭의 앞에 붙은 32비트 태그 값입니다.


리스트에서 메모리 블럭을 할당하려면 적절한 AllocateFrom 함수를 호출한다.

PVOID p = ExAllocateFromPagedLookasideList(pagelist);

PVOID p = ExAllocateFromNPagedLookasideList(nonpagedlist);

블럭을 리스트로 다시 돌리려면 적절한 FreeTo 함수를 호출하면 됩니다.

ExFreeToPagedLookasideList(pagedlist, p);

ExFreeToNPagedLookasideList(nonpagedlist, p);

마지막으로 리스트를 제거하려면 적절한 Delete 함수를 호출하면 됩니다.

ExDeletePagedLookasideList(pagedlist);

ExDeleteNPagedLookasideList(nonpagedlist);

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Fast I/O  (0) 2010.03.18

2006/10/31 19:10


복사http://blog.naver.com/dbtalk/110010329621


Fast I/O는 Cached file을 read/write함에 있어서 IRP를 만들지 않고 가능하게 해줍니다.
 
ReadFile를 예로 들어 Fast I/O의 흐름을 설명하면 다음과 같습니다.


순서1. NtReadFile에서 요청된 data가 Cached data인지 또는 Synchronous I/O인지를 판단하여

         Yes이면 File system driver를 호출합니다.
 
순서2. File system Driver에서는 Fast I/O가 가능한지를 판단하여 가능하면 Cache manager로

          제어를 넘긴다.


순서3. Cache Manager가 실제 Data를 I/O를 요청한 Process buffer로 복사한다.
 
순서4. 만약 순서1 또는 순서2에서 조건이 만족하지 않으면 IRP를 만들어서 I/O를 수행한다.


-- 부가 설명 --


일반적으로 File system에서의 I/O 요청은 
(1) File system driver(FSD)
(2) Cache Manager
(3) Memory Manager
(4) File system driver 재 진입
(5) DISK I/O 순으로 IRP 가 처리됩니다.
 
이 과정에서 Synchronous, buffered I/O 인 경우 I/O 요청은 결국 Cache Manager가 처리하게 된다. FSD는 단지 IRP를 Cache Manger에게 전달하는 역할 뿐이다.
따라서 Fast I/O는 IRP를 생성하고 FSD를 호출하는 부담을 줄이고 막바로 Cache Manger의 service를 호출 하는 방식이다.
fast의 원래 목적인 Synchronous, Buffered I/O read/write를 지원하면서 좀 더 확장되어 여러가지 FSD 함수들도 Fast I/O로 서비스 되고 있다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18

광역 변수를 사용할 때는 꼭 초기화를 해 주어야 한다. 초기화 해주는 부분은 main.cpp 에서 하는 것과 같이 해 주면 된다.

 // head.h

extern int a;

extern int b;


// main.cpp

#include "head.h"


int a = 10;

int b = 20;


void main()

{

a = 1;

b = 2;

}


// sub.cpp

#include "head.h"


void sub()

{

a = 2;

b = 3;

}

'Programming > 이것저것' 카테고리의 다른 글

TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18
OSI 7Layer  (0) 2010.03.18
Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18

상속에서 중요한 것 중 하나는 부모가 자식을 가리킬 수 있다는 것이다.

다음 소스를 보자.

Snap4.png

내 기대는 p->fucntion(); 문장이 "Derived"를  호출하는 것이었지만 결과는 "Base"를 호출한다.

왜 그럴까?


위 이유는 포인터의 형이 정해진 시점에서 이미 호출되어질 함수가 정해지기 때문이다.

포인터 p함수는 Base로 형이 선언되어 있기 때문에 자신의 함수 밖에 호출할 수 가 없다.

즉, 포인터가 무엇을 가리키든지 간에 Base로 형이 선언되어 있어서 호출 할 수 있는 함수도 정해져 있다는 것이다.


위의 결과를 제대로 보이게 해주는 것이 virtual 키워드 이다.

함수의 리턴타입 앞에 virtual이라는 키워드를 붙여주면 가상함수가 된다.


부모 클래스에만 virtual을 붙여주면 되지만, 보통은 자식 클래스에도 붙여서 명시한다.

virtual 키워드를 붙여주면 우리가 원하는데로 값이 출력되는 것을 볼 수 있다.

가상함수는 정적 결합(많이 들어본 용어일 것이다. 정확히는 링킹시에 결합이다.)을 하지 않고 동적 결합(실행 중에 결정된다.)을 사용한다.


Snap5.png


문장을 위와 같이 고치면 원하는 결과가 출력되는 것을 볼 수 있다.


'Programming > 이것저것' 카테고리의 다른 글

OSI 7Layer  (0) 2010.03.18
광역 변수  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18
C++ Style Type Casting  (0) 2010.03.18

왜 가상 파괴자가 필요한지 예를 통해서 보도록 하자.

아래는 우리가 일반적으로 사용하는 상속의 사용 예이다.

Snap1.png


우리는 Derived 클래스가 Base를 상속받게 하고 Base 클래스를 포인터로 선언해

Derived를 생성해주고 있다.

우리는 생성과 파괴가 아래처럼 되기를 원할 것이다.

Snap2.png


하지만 결과는 아래와 같이 나온다.

Snap3.png

왜 그럴까..??


위 이유는 포인터의 형이 정해진 시점에서 이미 호출되어질 함수가 정해지기 때문이다.

포인터 p함수는 Base로 형이 선언되어 있기 때문에 자신의 함수 밖에 호출할 수 가 없다.

즉, 포인터가 무엇을 가리키든지 간에 Base로 형이 선언되어 있어서 호출 할 수 있는 함수도 정해져 있다는 것이다.


생성자의 경우는 소스에서 보듯이 new Derived를 했기 때문에 우리가 명시적으로 호출을 해주고 있지만.

파괴자의 경우는 Base의 파괴자만 호출이 되는 것이 맞다. 왜냐면 p함수는 Base 형이기 때문에.


그렇기 때문에 아래와 같은 소스로 바꿔야 한다.

Snap4.png

위 소스와 같이 Base의 파괴자를 가상함수로 선언하게 되면 p의 파괴자가 동적바인딩이 되게 된다.

virtual 함수는 정적인 함수 호출을 동적 호출로 바꿀 수 있게 해주는 것이다.

위으 Base는 가상함수가 되며 동적 바인딩이 가능해진다. 동적바인딩이 되어 Base 형의 파괴자가

실행되는 것이 아니라 Derived의 파괴자가 실행되며 그 후 Base의 파괴자가 실행되어 완전한 메모리

해제가 이루어 진다.


'Programming > 이것저것' 카테고리의 다른 글

광역 변수  (0) 2010.03.18
Virtual Function  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18
C++ Style Type Casting  (0) 2010.03.18
#pragma pack  (0) 2010.03.18

try와 if는 장단점이 존재하고 있었습니다. 일단 둘의 차이점은 try 구문에서 예외가 발생하면 그 즉시 블록이 종료가 되고 catch 블록으로 제어가 이동된다고 합니다. 그리고 try/catch는 블럭if/else 는 구문이라는 점이 다릅니다.


if/else 로 에러를 처리한다면 에러가 발생한 객체에 대해서 수명이 유지되기 때문에 에러를 처리하는 동안에도 에러가 발생한 객체를 참조하는 코드가 정상적으로 컴파일 된다. 어떤 예외가 발생했을 경우 try/catch 안의 모든 객체는 스코프를 벗어나 참조 할 수 없게 되지만 if/else 문은 스코프가 벗어 나지 않게 되므로 try/catch 보다 더 위험합니다. 또한 활성 스택에서 생성되는 지역객체들의 자동 소멸을 위해 그것의 정보들을 유지합니다. 따라서 if문의 예외처리와는 달리 지역 객체들의 소멸자가 자동으로 호출되므로 메모리 등 리소스 누수의 문제를 조금이나마 해결할 수 있습니다.


하지만 try/catch 의 단점도 존재하게 됩니다. try/catch 블록은 유지해야 할 정보도 많고 또 실제 예외가 발생 했을 때도 해주어야 할 일이 많기 때문에 당연히 코드 크기나 예외 발생시 처리 속도는if/else의 전통적인 반환 값을 통한 오류처리와는 비교하기 힘듭니다.

 

하지만 try/catch는 자동으로 해주는 일이 많으며 당연히 더 느립니다. 하지만 우리가 만들어낸 코드가 컴파일러가 자동으로 만들어준 코드보다 더 안전하다고 말하기는 힘들겠네요.

Snap1.png


예외를 던질 때 단순히 기본형을 넘기는 것이 아니라, 예외 처리를 위해 미리 만들어진 클래스의 임시 객체를 넘기면 보다 자세한 정보를 catch 핸들러가 얻을 수 있습니다.


하지만 try/catch 를 사용하는 것은 검사코드가 포함되고 stack unwinding을 위한 코드가 추가되기 때문에 실행 파일의 크기를 약간 증가시키고 실행 속도를 약간 감소시킵니다.
예외 처리의 이러한 단점 때문에, 예외 처리는 사용되어야 할 곳에만 사용하는 것이 바람직합니다. (어떤 프로그래머는 DirectX로 개발하는 게임 프로그램의 렌더링 루프에서는 try/catch를 사용하지 않는다고 한다.)

'Programming > 이것저것' 카테고리의 다른 글

Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
C++ Style Type Casting  (0) 2010.03.18
#pragma pack  (0) 2010.03.18
#define swap  (0) 2010.03.18

C++에서는 static_cast, const_cast, dynamic_cast, reinterpret_cast의 4가지 casting이 지원된다. 사용 형식은 다음과 같다.

xxxxx_cast<type>(value)

  • const_cast : 상수 객체나 상수 포인터의 상수성을 제거하려는 목적을 갖는다.
  • dynamic_cast : 상위 클래스의 포인터에서 하위 클래스의 포인터로 변환하는 것을 뜻한다. 이 때, 변환에 성공한 경우(즉, 원래의 포인터가 조상 클래스의 포인터인 경우)에는 유효한 포인터가 제대로 리턴되고, 실패한 경우(두 포인터 타입 간에 연관이 없는 경우)에는 NULL이 리턴된다. dynamic_cast보다는 virtual 함수를 사용하는 것이 원래는 더 깔끔한 방법이지만, 라이브러리 안에 들어있는 클래스들이라서 직접 소스 수정이 불가능하다거나한 경우에는 이것을 사용한다(static_cast보다는 안전하다). - Effective C++ 항목 39 참조.
  • reinterpret_cast : 함수 포인터 타입을 형변환하는 것과 같이 구현에 따라 달라지는 결과를 위한 형변환을 목적으로 사용된다. 또한, 포인터 형변환 시에 static_cast로는 불가능한 경우에 사용할 수 있다(예 : void*를 Student*로 바꾼다거나..)
  • static_cast : 일종의 잡동사니 형변환이다. 어떤 형변환도 적합치 않을 때 사용할 수 있다. 의미상으로 볼 때는 기존 C의 형변환에 해당한다.

기존의 형변환도 그대로 사용되지만 새로운 형태의 형변환을 사용하는 것이 좋다. 코드에서 찾아보기도 쉽고 (사람뿐만 아니라 grep 같은 툴에게도 쉽다.) 보다 전문화된 목적의 형변환 형태가 컴파일러가 사용 에러를 진단하는 것을 가능하게도 해주기 때문이다.

'Programming > 이것저것' 카테고리의 다른 글

Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18
#pragma pack  (0) 2010.03.18
#define swap  (0) 2010.03.18

 #pragma pack은 구조체의 저장 크기를 결정하는 명령어입니다.

 BYTE 의 멤버 변수를 1바이트로 실제 저장하는가 아니면 2, 4바이트로 저장하는가를 설정합니다.


#pragma pack(push,2) <---- gcc, vs에서 이렇게 사용합니다.

    struct KBITMAPFILEHEADER

    {

        WORD bfType;

        DWORD bfSize;

        WORD bfReserved1;

        WORD bfReserved2;

        DWORD bfOffBits;

    };

#pragma pack(pop)

'Programming > 이것저것' 카테고리의 다른 글

Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18
C++ Style Type Casting  (0) 2010.03.18
#define swap  (0) 2010.03.18

멤버십에서 배운 어청 깜놀한 SWAP 입니다. 신기했던 기억이...

#define SWAP( a, b ) a^=b^=a^=b


이것은 세 숫자 중 가장 큰 수를 찾는 한줄 코드.

( nA > nB ) ? ( ( nA > nC )? nA: nC ) : ( ( nB > nC )? nB: nC ); 

'Programming > 이것저것' 카테고리의 다른 글

Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18
try/catch와 if/else의 차이점  (0) 2010.03.18
C++ Style Type Casting  (0) 2010.03.18
#pragma pack  (0) 2010.03.18

+ Recent posts