'2010/01'에 해당되는 글 22건

  1. 2010.01.24 Dll이란?
  2. 2010.01.20 파이프 추가내용
  3. 2010.01.18 소켓통신(함수정리) 1
  4. 2010.01.18 OSI 모델 And Ip계층
  5. 2010.01.15 Hooking
  6. 2010.01.13 서비스
  7. 2010.01.12 IPC란?
  8. 2010.01.12 동기화
  9. 2010.01.04 디폴트 함수
  10. 2010.01.04 API (원 가지고 놀기)

  라이브러리

라이브러리(Library)란 함수,데이터,타입 등 여러가지 프로그래밍 요소들의 집합이며 보통 LIB확장자를 가진다. (DLL사용시 h,dll파일 필요) 자주 사용되는 표준적인 함수를 매번 직접 작성해서 사용하는 것은 지나치게 시간 소모적이므로 표준화할 수 있는 함수를 미리 만들어서 모아 놓은 것이 라이브러리이다. 라이브러리를 한 번 구축해 놓기만 하면 다시 만들 필요없이 불러서 사용할 수 있으므로 개발 속도도 빨라지고 신뢰성도 확보할 수 있다.

 

한글 입출력을 하는 라이브러리를 생각해 보자. 한글은 무척 복잡한 언어이기 때문에 한글을 사용하는 모든 프로그램에서 한글 입출력 함수를 일일이 만들어 사용하기 어렵다. 그래서 누군가가 한 번만 한글 입출력 함수를 만들어 라이브러리로 배포하면 나머지 사람들은 이 라이브러리에 있는 함수를 불러 한글을 출력하기도 하고 입력받기도 한다.

 

  STATIC LINK

 

ProA.exe를 만드는 사람은 자신의 고유 코드만 ProA.cpp에 작성하고 HAN.LIB와 연결하면 한글 입출력 기능을 가진 ProA.exe. 실행 파일을 만들 수 있다. HAN.LIB에 있는 함수와 데이터는 링커에 의해 실행 파일에 그대로 옮겨지면 실행 파일의 일부분이 된다.

 이런 전통적인 라이브러리 연결 방법을 정적 링크(Static Link)라고 하면 컴파일시에 라이브러리에 코드를 실행파일에 복사한다.

 

 

  DLL

DLL은 동적 링크(Dynamic Link)를 사용한다. 동적 링크란 컴파일시에 함수의 코드가 실행 파일에 복사되는 것이 아니라 실행 중에 라이브러리에 있는 함수를 호출하는 방법을 말한다.

ProA.exe를 만드는 사람은 자신의 고유 코드만 ProA.cpp에 작성하고 이 소스를 컴파일하여 ProA.exe를 만든다. ProA.cpp에서는 한글 입출력 함수를 호출하지만 ProA.exe파일에는 한글 입출력 함수가 포함되어 있지 않다. 대신 ProA.exe는 한글 입출력 함수의 위치에 대한 정보를 가지고 있으며 이 프로그램이 실행될 때 HAN.DLL이 메모리에 같이 로드되며 ProA.exe에서 HAN.DLL에 있는 함수를 호출한다.

 

  DLL의 장점

     한 코드를 여러 프로그램이 동시에 사용하기 때문에 메모리가 절약된다.

     정적링크를 사용하는 경우 실행 파일에 라이브러리의 함수가 모두 포함되어 실행파일이 커지지만 DLL을 사용하는 프로그램은 크기가 작다.

     DLL을 교체하여 프로그램의 성능을 향상시키기 쉽다.

     리소스의 교체가 가능하다.

     코드의 양이 적어지므로 디버깅이 용이해진다

     혼합 프로그래밍이 가능해 진다

     프로그래머끼리 분담 작업이 용이하며 재사용성도 뛰어나다.

 

 

  정적링크와 동적 링크

정적 링크

컴파일 시에 함수가 실행 파일에 연결된다. 실행 파일에 함수의 코드가 복사되기 때문에 실행 파일의 크기가 커지는 단점이 있지만 실행 파일은 완전한 단독 실행 파일이 된다. 실행파일에 함수의 코드가 포함되어 있기 때문에 컴파일이 끝나면 라이브러라 파일(LIB)이 없어도 프로그램을 실행할 수 있다.

동적 링크

실행시에 함수가 실행 파일에 연결된다. 실행 파일에는 호출할 함수의 정보만 포함되고 실제 함수 코드는 복사되지 않ㅇ므로 실행 파일의 크기가 작아진다. 하지만 실행 파일은 함수에 대한 정보만 가지고 있을 뿐 실제 코드를 가지고 있지는 않으므로 프로그램 실행시에 DLL이 꼭 있어야 한다.

 

*  DLL관리

 윈도우가 DLL을 어떻게 관리하는지를 상상해 보자. 클라이언트 프로그램인 ProA.exe가 실행되면 이 프로그램의 실행에 필요한 HAN.DLL함수도 메모리로 같이 로드될 것이다. DLL은 자신을 로드한 프로세스의 가상 주소 공간에 맵핑되면 따라서 DLL은 메모리,스택,핸들을 프로세스와 공유하게 된다.

 

 두 번째 클라이언트인 ProB.exe가 실행될 때는 HAN.DLL이 이미 메모리에 올라와 있으면 HAN.DLL은 읽어올 필요가 없으며 ProB.exe만 읽어온다. 대신 윈도우는 ProB.exe의 주소 영역에 HAN.DLL이 로드된 메로리를 맵핑시켜 ProB.exe에서도 HAN.DLL의 함수를 자유롭게 호출할 수 있도록 한다. 세번째 클라이언트인 ProC.exe가 실행될 때도 마찬가지로 같은절차를 거칠 것이며 이 상태에서는 세 개의 클라이언트 프로그램이 하나의 DLL을 공유한다.

 

 

 DLL은 가상 메모리에 한 번 로드되면 다시 로드되지 않는다. 단 코드의 경우만 드렇지 DLL의 고유 변수는 클라이언트 프로그램이 실행될 때마다 매번 다시 메모리를 할당받아야 한다. 클라이언트 프로그램끼리 코드는 공유하지만 데이터는 공유할 수 없기 때문이다. C++클래스의 멤버 함수는 이 클래스로부터 만들어지는 모든 객체가 가 공유하지만 멤버 변수는 개별적으로 가지는 것과 마찬가지이다.

 

 예를 들어 HAN.DLL에 현재 입력 상태가 한글 모드인지 영문 모드인지를 기억하는 변수가 있다고 하자. 이 변수의 값은 클라이언트 프로그램별로 다를 수 있기 때문에 프로그램끼리 공유할 수 없다. 만약 이 변수를 공유한 상태에서 ProA.exe에서 한글 입력 상태로 바꾸면 ProB.exe ProC.exe도 같이 한글 입력 상태로 바뀌어 버릴 것이며 이는 논리적으로 바람직하지 못한 결과를 가져온다. 이런 식으로 DLL내부의 값을 기억하는 변수는 공유가 불가능하기 때문에 클라이언트 프로그램이 실행될 때마다 다시 메모리를 할당받아야 한다.

 

DLL이 메모리에서 지워지는 시기는 언제 쯤일까? 필요가 없어진 DLL은 당연히 메모리에서 사라져야 하지만 DLL은 사용자가 직접 사용하는 것이 아니기 때문에 종료시기를 쉽게 판단할 수 없다. DLL을 처음 메모리로 올린 ProA.exe가 종료될 때 HAN.DLL을 종료하는 방법이 가장 쉽게 떠올릴 수 있는 방법이다. 그러나 최초 DLL을 로드한 ProA.exe가 종료되어도 ProB.exe ProC.exe가 이 DLL을 계속 사용하고 있을 수도 있기 때문이다. DLL이 메모리에서 삭제되어야 할 시기는 DLL을 사용하는 모든 클라이언트 프로그램이 종료되었을 때이다.

 

윈도우는 DLL별로 사용 카운트라는 것을 유지하고 있으며 클라이언트 프로그램이 실행될 때마다 카운트를 1씩 증가시키고 클라이언트가 종료될 때마다 카운트를 1 감소시킨다. 이렇게 사용 카운트를 유지하면서 카운트가 0이 될 때 DLL을 메모리에서 삭제하면 아무런 문제가 없다.

ProA.exe실행

ProB.exe실행

ProC.exe실행

ProA.exe종료

ProC.exe종료

ProB.exe종료

HAN.DLL로드

 

 

 

 

HAN.DLL삭제

COUNT = 1

COUNT = 2

COUNT = 3

COUNT = 2

COUNT = 1

COUNT = 0

 

 

*  DLL접속

__declspec

DLL을 사용하려면 우선 함수를 제공하는 DLL에서는 자신이 제공하고자 하는 함수에 대한 정보를 밖으로 공개해 놓아야 하며 이 동작을 EXPORT라고 한다. 반대로 DLL을 사용하는 클라이언트에서는 어떤 DLL에 있는 어떤 함수를 사용하겠다고 선언해야 하는데 이 동작을 IMPORT라고 한다. 즉 함수를 제공하는 측은 어떤 함수를 제공하겠다는 선언이 있어야 하며 함수를 사용하는 측에서는 어떤 함수를 사용하겠다는 선언이 있어야 한다.

 

 

__declspec은 함수에 대한 정보를 제공하는 선언문이며 엑스포트 또는 임포트하는 함수 앞에 수식어로 이 문구가 있어야 한다. 원형은 다음과 같으며 앞의 밑줄이 두 개임을 유의하다

 

__declspec(extended-attribute) declaratory

 

__declspec문은 기억부류(Storage Class)에 관한 정보를 단순화,표준화하며 원래의 C++에는 없는 문장이지만 마이크로소프트에서 C++문법을 확장한 예 중 하나에 해단한다. 언뜻 보기에는 괄호가 있어 함수같지만 컴파일러가 제공하는 키워드이다. 기억 부류의 속성을 괄호 안에 인수로 지정한다. 사용가능한 인수는 네 가지

가 있다.

인수

설명

Thread

TSL(Thread Local Storage) 데이터로 지정한다. 이 지정자가 붙은 변수는 해당 스레드에서만 사용할 수 있는 변수가 된다.

Naked

접두(prolog),접미(epilog)를 생성하지 않는다. 어셈블리 언어를 사용하여 직접 접두,접미를 달고자 할 때 사용한다. 어셈블리 언어를 사용하여 가상 디바이스 드라이버를 작성할 때 이 기억부류를 사용한다. 함수에만 적용되며 변수에는 적용되지 않는다.

Dllimport

DLL에 있는 데이터,오브젝트,함수를 임포트한다. DLL에 있는 이렇게 생긴 함수를 앞으로 사용하겠다는 선언이다

dllexport

DLL에 있는 데이터,오브젝트,함수를 엑스포트한다. DLL이 사용하는 클라이언트(실행파일이거나 또는 다른 DLL)에게 DLL의 정보를 명시적으로 제공하는 역할을 한다.

Dllexport로 함수를 선언하면 DEF파일의 Exports란에 이 함수를 명시하지 않아도 되며 __export 키워드를 대체한다.

 

 

n  사용방법

 

DLL에서 엑스포트

extern “c” __deslpsec(dllexport) 함수원형;

client에서 임포트

extern “c” __deslpsec(dllimport) 함수원형;

 
암시적 연결 & 명시적 연결

  암시적 연결

함수가 어느 DLL에 있는지 밝히지 않고 그냥 사용한다. 프로젝트에 임포트 라이브러리를 포함해야 하며 윈도우즈는 임포트 라이브러리의 정보를 참조하여 알아서 DLL을 로드하고 함수를 찾는다. 클라이언트 프로그램이 로드될 때 DLL이 같이 로드되거나 이미 DLL이 로드되어 있으면 사용 카운트를 1 증가시킨다. 클라이언트 프로그램이 실행될 때 DLL이 로드되므로 실행시 연결이라고 한다.

n  임포트 라이브러리 DLL파일 찾는 순서

     클라이언트 프로그램이 포함된 디렉토리

     프로그램의 현재 디렉토리

     윈도우의 시스템 디렉토리

     윈도우 디렉토리

     PATH환경 변수가 지정하는 모든 디렉토리

만약 이 순서대로 DLL을 찾아보고 원하는 DLL이 발견되지 않으면 클라이언트 프로그램은 다음과 같은 에러메세지를 출력하고 실행을 종료한다.

 

 

 

※ 암시적 연결 실습

     새 프로젝트를 만든다(Win32 Dynamic-Link Library 형태로 생성)

 

     함수를 작성한다.

xyz.c

#define DLL_SOURCE

#include "xyz.h"   // 이 안에 있는 DLLFUNC __declspec(dllexport)로 된다.

 

int Add( int a, int b )

{

             return a + b;

}

xyz.h

#ifdef DLL_SOURCE

             #define DLLFUNC __declspec(dllexport)  

#else

             #define DLLFUNC __declspec(dllimport)

#endif

 

#include <windows.h>

 

EXTERN_C DLLFUNC int Add( int a, int b);

 

 

     컴파일하면 DLL파일,LIB파일이 생성된다.

 

     XYZ.Dll , XYZ.lib , XYZ.h 파일을 사용할 폴더에 복사한다.

     사용할 프로젝트에서 사용하고자 하는 DLL의 임포트 라이브러리를 프로젝트에 포함시킨다

 혹은  #pragma comment(lib, "xyz.lib")

Usxxyz.cpp

#include <windows.h> // user32.dll의 모든 함수 선언.

#include <stdio.h>

// DLL 사용하기

#include "xyz.h"                                                          // 관련 헤더 include

#pragma comment(lib, "xyz.lib")                      // 라이브러리 추가

void main()

{

MessageBox(0,"A","",MB_OK);

 

int s = Add(10,20);                           // DLL 함수 사용

printf("결과 : %d\n", s);

 

void* p1 = GetModuleHandle( "xyz.dll");

printf("xyz.dll 주소 : %p\n", p1);

printf("Add 주소 : %p\n",    Add);

}

 

정상적으로 값 30이 메시지박스로 뜨고 콘솔창에는 결과와 각각의 주소값이 출력

 


명시적연결의 사용법은 적지않았다
장점만 알아보고 가겠다.

    명시적 연결의 장점

  1. 필요할 때만 DLL을 읽어와 사용하기 때문에 메모리와 리소스가 절약된다. 암시적 연결의 경우 프로그램이 시작 될 때 DLL도 같이 메모리로 올라오므로 프로그램 실행중에 항상 DLL이 메모리에 상주하고 그만큼 메모리가 더 소비된다.
  2. 경우에 따라 사용할 DLL을 교체할 수 있다. LoadLibray에서 DLL 이름을 문자열로 줄 수 있으므로 상황에 맞게 DLL을 선택적으로 사용할 수 있다. 마찬가지로 호출할 함수도 문자열로 지정하므로 선택 가능하다.
  3. 필요한 DLL이 없는 경우에도 프로그램을 실행할 수 있다. 물론 이 경우 DLL에게 분담된 작업은 제대로 처리할 수 없겠지만 최소한 프로그램이 실행되지도 못하는 상황은 발생하지 않는다. DLL이 없을 경우 다른 방법으로 문제를 해결하거나 최소한 에러 메시지라도 보여줄 수 있다. 반면 암시적 연결의 경우는 DLL이 없으면 아예 실행을 시작할 수 조차 없다.
  4. 클라이언트 프로그램의 시작이 빠르다. 암시적 연결은 클라이언트 실행전에 DLL을 읽어와야 하는데 필요한 DLL의 개수가 수십개가 넘으면(실제로 그정도 된다)이 시간이 무시 못할 정도로 길어질 수도 있다.명시적 연결은 일단 프로그램이 실행된 후 필요할 때 DLL을 로드하므로 신속하게 실행된다. 최종 사용자 입장에서는 이 정도 시간 차이가 굉장히 크게 느껴진다.

 















'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

세마포어  (0) 2010.01.24
파일매핑 사용순서  (0) 2010.01.24
파이프 추가내용  (0) 2010.01.20
Hooking  (0) 2010.01.15
서비스  (0) 2010.01.13
Posted by 아몰라

CreatePipe, CreateNamedPipe
파이프가 없을시 생성
있을시 접근한 클라이언트와 통신하기위한 핸들값을 반환 


check = ConnectNamedPipe 클라이언트가 접속하기를 대기하였다가 접속하면 함수 종료

DisconnectNamedPipe() - CloseHandle
 파이프를 파괴할수 있긴하나 디스콘넥을 안하면 다시 재준비가 안된다. (예) 백화점 직원 - 커피마시러가는 상황


스레드 주의점

스레드는 고유한 스택 정보를 갖고있다. 그러므로 스레드를호출할때 지역변수의 주소를 넘기는것은 위험하다.
같은 주소가 나올 수 있기 때문에 동적할당을 이용 하는 방법이있다.

 

CreateThread - 이러한 진입점을 가진 스레드를 생성해달라. (생성시켜도 바로 생성되서 실행되지않음)


'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

파일매핑 사용순서  (0) 2010.01.24
Dll이란?  (0) 2010.01.24
Hooking  (0) 2010.01.15
서비스  (0) 2010.01.13
IPC란?  (0) 2010.01.12
Posted by 아몰라

접속 기반 프로토콜(Connection Oriented Protocol)



SOCKET PASCAL FAR socket(int af, int type, int protocol);

참고주소 : http://msdn.microsoft.com/en-us/library/ms740506(VS.85).aspx

특정 전송 서비스 제공자로 바인드 될 소켓을 생성한다.

리턴 : 성공시 소켓의 핸들. 실패시 INVALID_SOCKET.

af : address family를 정한다.

 - AF_INET(IPv4), AF_IPX, AF_APPLET!ALK, AF_NETBIOS, AF_INET6(IPv6), AF_IRDA, AF_BTH

type : 새로운 소켓이 어떤 형태인지 정한다.

 - SOCK_STREAM : OOB data 전송 메카니즘을 가진 순서화된 신뢰성 있는 양방향, 접속 기반 바이트 스트림을 제공한다.

 - SOCK_DGRAM : 고정된 최대 크기의 신뢰성 없고 접속하지 않는 버퍼인 데이터그램을 제공한다.

 - SOCK_RAW : Layer 3 프로그래밍을 하고 싶을 때

   예시) ping(컴퓨터가 살았나 죽었나, round-trip), tracert

protocol : 사용될 프로토콜

 - IPPROTO_TCP, IPPROTO_UDP


well-known port(0~1024) : 사람들이 자주 사용하는 포트. 21: ftp, 23: telnet, 25 : SMTP, 80 : web


Socket Address 구조체

참고주소 : http://msdn.microsoft.com/en-us/library/aa252969(VS.60).aspx

struct sockaddr_in{

    short            sin_family;

    unsigned short      sin_port;

    struct   in_addr      sin_addr;

    char               sin_zero[8];

};


sin_family : address family ( AF_INET이어야 한다. )

sin_port : 16비트 포트 번호. htons계열의 함수가 필요하다.

sin_addr : IP 주소. inet_addr함수나 htonl계열의 함수가 필요하다.

sin_zero : 사용되지 않음.


int pascal FAR bind(SOCKET s, struct sockaddr FAR *addr, int namelen);

참고주소 : http://msdn.microsoft.com/en-us/library/ms737550(VS.85).aspx

소켓 핸들과 소켓 구조체를 연관시키고 시스템에게 묶어달라고(bind) 요청한다.

소켓과 지역(현재 컴퓨터) 주소를 연관시킨다.

리턴 : 성공시 0. 실패시 SOCKET_ERROR. 더 자세한 오류코드는 WSAGetLastError를 참고.

s : bind되지 않은 소켓을 나타내는 descriptor

name : sockaddr 구조체로부터 소켓을 지정할 주소

namelen : 바이트 단위. name 전달인자 값의 길이


int PASCAL FAR listen(SOCKET s, int backlog);

참고주소 : http://msdn.microsoft.com/en-us/library/ms739168(VS.85).aspx

포트를 감시모드로 바꾼다.

들어오는 접속에 대해 듣고 있는 상태의 소켓으로 만든다.

리턴 : 성공시 0, 실패시 SOCKET_ERROR

s : 접속되지 않고 bind된 소켓을 나타내는 descriptor

backlog 

 - 기라디는 접속 큐의 최대 길이. (로스터에 올라간 사람 수. 최소 1이상)

 - SOMAXCONN이면 최대로 합리적인 값으로 backlog를 설정.


SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen);

참고주소 : http://msdn.microsoft.com/en-us/library/ms737526(VS.85).aspx

클라이언트가 올 때까지 blocking되었다가 클라이언트가 접속하면 요구를 받아준다.

소켓으로 들어오는 시도를 한 접속을 허가한다.

s : listen 함수에 의해 listen 상태인 소켓을 나타내는 descriptor

addr : 접속한 개체의 주소를 받는 버퍼의 포인터. 접속 peer 프로세스(클라이언트)의 주소를 리턴한다.

addrlen : addr 전달인자를 가리키는 구조체의 길이를 포함한다.


int pascal FAR connect(SOCKET s, struct sockaddr FAR *addr, int namelen);

참고주소 : http://msdn.microsoft.com/en-us/library/ms737625(VS.85).aspx

특정 소켓으로 접속한다.

리턴 : 성공시 0, 실패시 SOCKET_ERROR

s : 접속되지 않은 소켓을 나타내는 descriptor

name : 접속이 설정될 sockaddr 구조체의 포인터

namelen : name 전달인자가 가리키는 sockaddr 구조체의 길이(바이트 단위)


port to port connection

single server는 2개의 소켓을 가진다.

multi server는 n+1 개의 소켓을 가진다.


Blocked : 현실적으로 어느 코드 부분에 멈춰 있음

Blocking : 호출을 하면 정지할 가능성이 있는 코드. 오류나 결과가 나올 때까지 멈춰 있음.

예시) 윈도우즈 상에서 '응답 없음' 표시(잠재적으로 멈출 수 있는 코드 : 파일, 네트워크)


nonblocking : 호출하자마자 바로 리턴한다. 결과가 나올 때까지 반복 호출. 프로그램이 멈출 일이 없다.


asynchronous mode : 결과가 나올 때 시그널, 인터럽트, 메세지를 보내서 확인한다. 프로그램이 멈출 일이 없다. WSA계열 함수(Windows Socket Asynchronous)



 way handshake 방식을 통해 접속을 설정한다.

send() <-> recv()

socket은 패킷을 받아 buffer(수십K바이트)에 보관한다.


패킷단위

스트림단위

소켓단위(버퍼)


send buffer : send() 함수는 보낼 내용을 send buffer에 담는 역할을 한다. 프로그래머가 신경 쓸 필요가 없다.

receive buffer : recv() 함수는 receive buffer에 있는 받을 내용을 가지고(읽어) 온다.


send buffer가 꽉 차있다면 send(), write() 함수는 기다려야 한다. (blocking)

receive buffer가 비어 있는데 recv(), read() 함수는 기다려야 한다. (blocking)


int send(__in  SOCKET s, __in  const char *buf, __in  int len, __in  int flags);

참고주소 : http://msdn.microsoft.com/en-us/library/ms740149(VS.85).aspx

접속된 소켓에 데이터를 보낸다.

리턴 

성공시 len 전달인자에서 보내질 요청된 수보다 작을 가능성이 있는 보내진 바이트 수.

실패시 SOCKET_ERROR

s : 접속된 소켓을 나타내는 descriptor

buf : 보낼 데이터를 포함한 버퍼의 포인터

len : buf가 가리키는 데이터의 길이(바이트 단위)

flags : 호출하는 방법을 정의하는 집합.


int recv(__in   SOCKET s, __out  char *buf, __in   int len, __in   int flags);

참고주소 : http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx

접속된 소켓이나 바인드된 비접속 소켓으로부터 데이터를 받는다.

리턴 : 성공시 받은 바이트 수 실패시 SOCKET_ERROR

s : 접속된 소켓을 나타내는 descriptor

buf : 들어올 데이터를 받을 버퍼 포인터

len : buf가 가리키는 데이터의 길이(바이트 단위)

flags : 함수에 행동에 영향을 줄 집합


비동기 소켓방식

버퍼의 상태를 확인해 주는 함수를 이용한다.

 


윈도우즈 비동기 소켓 방식

WSAAsyncSelect(소켓 핸들, 윈도우 핸들, 윈도우즈 user-defined message, 소켓 이벤트)

소켓 이벤트(4)가 발생하면 윈도우즈 user defined message(3)를 윈도우 핸들(2)에 보낸다.

소켓 하나에 user defined message는 하나만 등록 가능하다.

※ 취소하는 경우 : e = WSAAsyncSelect(socket, hWnd, 0, 0); 


int WSAAsyncSelect(__in  SOCKET s, __in  HWND hWnd, __in  unsigned int wMsg, __in  long lEvent);

참고주소 : http://msdn.microsoft.com/en-us/library/ms741540(VS.85).aspx

소켓에 대한 네트워크 이벤트의 윈도우 기반 알림(notification)을 요청한다.

s : 이벤트 알림(notification)이 요구되는 소켓을 나타내는 descriptor

hWnd : 네트워크 이벤트가 발생할 때 메세지를 받게 될 윈도우 핸들.

wMsg : 네트워크 이벤트가 발생할 때 받게될 (사용자 정의) 메세지.

lEvent : 응용 프로그램이 관심있는 네트워크 이벤트의 조합을 나타내는 비트마스크


소켓 이벤트(lEvent)

FD_READ : receive 버퍼에 무엇인가 들어왔다.

FD_WRITE : send 버퍼에 쓸 수 있다.

FD_OOB : FD_READ의 특수한 형태.

FD_ACCEPT : 접속 요구가 들어왔다.

FD_CONNECT : 접속이 되었다. 서버와 연결에 성공하였음.

FD_CLOSE : 상대방과 socket 연결이 끊어짐.


윈도우 프로시저를 호출할 때 전달되는 인자

wParam : 소켓 식별자

LOWORD(lParam) : 발생한 이벤트 종류. WSAGETSELECTEVENT(lParam)와 같은 뜻

HIWORD(lParam) : 에러 상태. WSAGETSELECTERROR(lParam)와 같은 뜻


closesocket() : 유닉스는 소켓 닫는 함수를 close()를 쓰지만 윈도우즈는 closesocket을 사용한다.


int closesocket(__in  SOCKET s);

참고주소 : http://msdn.microsoft.com/en-us/library/ms737582.aspx

현재 존재하는 소켓을 닫는다.

리턴 : 성공시 0, 실패시 SOCKET_ERROR

s : 닫을 소켓을 나타내는 descriptor



출처 http://blog.daum.net/sdr1982/

'API & MFC > 네트워크프로그래밍' 카테고리의 다른 글

EventSelect란?  (0) 2010.02.05
ASyncSelect 예제  (1) 2010.02.04
소켓통신의 라이브러리 사용 선택 시 고려사항  (0) 2010.02.02
소켓함수 예제(로그인서버)  (0) 2010.01.25
OSI 모델 And Ip계층  (0) 2010.01.18
Posted by 아몰라

응용계층

프리젠테이션계층

세션계층 - 컴퓨터내의  응용에게 보내준다.

전송계층 - 어떠한 방식으로 보낼건지 (TCP, UDP)
네트워크계층 - 누가누구한테 보내는지 

데이터링크계층 - 디바이스드라이버 (운영체제에서 디바이스에게...)

물리계층 - 패킷은 회선을 이용한다



1.  Layer - Based 통신 모델    - 계층적 구조

- Layer N 

   (N-1)계층에서 제공하는 서비스를 사용

   동일 계층의 instance와의 통신

 

- Protocols

    동일 계층간에 통신을 위해 미리 정해놓은 규약

 - Service

    계층 N이 (N+1)계층에게 제공하는 기능

    Service Interface라고도 불린다.

 - Instance

   한 개의 계층이 제공하는 통신 프로토콜과 서비스를 구현한 것

 

 

통신 흐름

 

 2. ISO/OSI Reference Model

-특징

   시스템 간의 통신을 위한 추상화 모델을 제시

   개방형 통신 시스템을 위해 표준안 개발 체제 제공 

   통신 시스템의 기능을 논리적으로 분해하는 측면에서 중요하게 인식하고 있다.

   복잡성 때문에 실질적으로 구현하는 입장에서 보면 실패한 모델

 

- Physical Layer (물리 계층)

   구조화되어 있지 않은 비트 시퀀스를 물리적인 신호로 변환하여 매체를 통해 전송하는 계층

 

- Data Link Layer (데이터 링크 계층)

   송신부에서는 데이터를 프레임으로 만들어 전송한다.

   수신부에서는 과부하가 걸리지 않도록 데이터의 흐름을 조정한다. 

   에러 검출 및 재 전송을 한다.

   Protocol : SLIP, PPP, HDLS,...

 

- Network Layer (네트워크 계층)

  통신망에서 System간의 연결성을 제공한다.

   Routing, Fragmenting을 담당한다.

   Protocol : IP, ICMP, IGMP,...

 

- Transport Layer (전송 계층)

   Application간의 데이터 전송 제공

   데이터의 정확성과 순서를 안전하게 하기 위해 존재한다. 

   Protocol: TCP, UDP,...

 

- Session Layer (세션 계층)

   전송 계층을 통한 구조화된 메시지 교환을 핸들링한다.

 

- Presentation Layer (프리젠테이션 계층)

  터미널 시스템 사이의 데이터 흐름을 제어한다.

  통신하고 있는 컴퓨터 시스템들에 의존적이지 않은(독립적인) 데이터 전달을 규정한다.

  예: ASCII vs Unicode , Big endian vs Little endian

 

- Application Layer (응용 계층) 

  

3. TCP/IP Reference Model

 

- Interface Layer

   네트워크 아답터들과 그들의 드라이버들을 다룬다.

 

- Internet layer

   IP

   ICMP - 제어 및 에러 정보 전송

   IGMP - 통신 그룹 관리

 

- Transfer layer

   터미널 시스템의 용용들 간의 전송담당

   TCP - 연결지향, 신뢰성,STREAM

   UDP - 비 연결지향, 가벼운 스택, DGRAM

             복잡한(무거운) TCP에 비해 선호하는 경우가 늘고 있다.(멀티미디어와 같은 전송에서)

 

- Application layer

   응용 프로그램과 관련된 모든 태스크들의 계층(ISO/OSI 모델의 5~7 계층)

   Telnet, FTP, SMTP, DNS, HTTP

출처 - http://cafe.daum.net/sbehclub


라우터 - 3계층까지만 이용

세대별 통신

1G - 아날로그 통신(PSTN망)

2G - 디지털 통신

3G- 개인단말

4G- 차세대통신


Circuit Switching망( 독점)  = Packet Flooding망

Packet Flooding - 전체 망에 뿌려지면서 해당 대상까지 간다.

패킷이 어떠한 망을 사용하는지



IP 프로토콜 

   RFC 791에 정의되어 있는 모든 IP 기반 네트워크에 사용되는 데이터 트래픽에 대한 기본 서비스를 제공 

   데이터그램 기반으로 만들어졌다. 

   전화망의 circuit-switching방식과 달리 packet-switching방식을 사용한다. 

   - 롤

    데이터 전송 계층의 차이를 감추고 상이한 네트워크 기술(LAN, SLIP, PP, 모뎀, ISDN 등)에 대한 일관된 표현을 제공한다. 

   IP Address family를 통해 Uniform address scheme를 제공

   큰 데이터 패킷은 fragmentation하여 작은 패킷 크기로 전송

   (통신에 거치는 모든 네트워크 기술들의 MTU중 최소 MTU에 맞춰서 fragmentation한다.)

 

 

통신 기술 

 

 

IPv4 스택 

 

 

Version

   현재는 v4(0x800)와 v6(0x86DD)만 정의되어 있다.

 

IHL

   패킷 헤더의 길이

   옵션을 사용하면 패킷 헤더의 길이는 5옥텟(1옥텟은 4바이트)를 넘을 수 있다.  최대 15옥텟(60바이트) 

 

Codepoint

    ToS라고 불렀었던 것을 RFC2474에서 Differentiated Services Codepoint라고 이름을 변경하였다.

    IP에 사용되는 forwarding behavior를 나타낸다.

 

Total Length

   패킷 전체의 길이, 최대 64K

   RFC791에 의하면 576바이트인 데이터 패킷을 처리할 수 있어야 한다고 명시(길이가 더 큰 패킷도 처리할 수 있다.) 

 

Fragment ID - 상위에서 날라온 데이터의 구분자 역할을 한다.

    원래 하나였던 패킷을 fragmenation을 했을 때 모든 fragments는 동일한 fragment id를 갖는다.

 

Flags

    DF : 데이터그램이 fragment되지 말아야 함을 나타낸다.

    MF: fragment가 되었음을 나타냄, 마지막 fragment에는 표시되지 않는다.

 

Fragment Offset

    Fragment의 일련번호

    수신부에서 원래의 데이터그램으로 재구성하기 위해 필요하다.

 

TTL -  Keep Alive   에 해당 되는 부분

   IP 패킷의 수명을 제한하기 위하여 사용

   패킷이 라우터를 거칠 때마다 1감소되며 0이되면 패킷은 제거된다.

   라우터에서 버퍼링을 위해 1이상 감소시키는 경우도 있다. 

 

Protocol

    전송 계층의 구분

    TCP(6), UDP(17), IGMP(2)

 

Checksum

   IP 패킷 허더 필드들에 대한 checksum

   라우터를 거쳐가면서 TTL이 감소하기 때문에 매번 다시 계산된다.

   Checksum필드를 제외한 부분을 16비트 단위로 1의 보수의 합을 계산한 값이다.

   유효한 패킷인지 확인하기 위한 용도로 있는 필드이다.


 Sorce address - 192.168.34.442 송신자아이피  



 Destination address - 192.168.34.442 수신자아이피


여기에서는 옵션과 ICMP, IGMP등을 다루지 않으니 각자가 확인하여 학습하길 바란다.   

'API & MFC > 네트워크프로그래밍' 카테고리의 다른 글

EventSelect란?  (0) 2010.02.05
ASyncSelect 예제  (1) 2010.02.04
소켓통신의 라이브러리 사용 선택 시 고려사항  (0) 2010.02.02
소켓함수 예제(로그인서버)  (0) 2010.01.25
소켓통신(함수정리)  (1) 2010.01.18
Posted by 아몰라
Hooking - 이미 작성되어 있는 코드의 특정 지점을 가로채서 동작 방식에 변화를 주는 일체의 기술


훅 프로시저 설치 함수
HHOOK SetWindowHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadld);

int idHook - 어떠한 이벤트에 대해서 후킹을 할것인가
HOOKPROC lpfn - 키보드 이벤트를 받을 훅 프로시저 명
HINSTANCE hMod - 누가 이 훅 체인을 등록할것인지
DWORD dwThreadld - 어느 스레드한테 후킹할것인가


LRESULT CALLBACK keyboardProc(int code, WPARAM wParam, LPARAM lParam);

code - 메시지를 어떤 처리를 할 것인가를 결정
wParam, lParam - 전달된 메시지에 대한 추가 정보

메시지를 훅 체인의 다음 훅 프로시저에게 전달해주는 함수
LRESULT CallNextHookEx(HHOOK hhk, int cCode, WPARAM, wParam, LPARAM, lParam);

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

Dll이란?  (0) 2010.01.24
파이프 추가내용  (0) 2010.01.20
서비스  (0) 2010.01.13
IPC란?  (0) 2010.01.12
동기화  (0) 2010.01.12
Posted by 아몰라
서비스 - 백그라운드에서 실행되는 프로그램 (유닉스식으로 표현하면데몬)

1. WIN32 서비스 - SDK영역
 
2. 드라이버 서비스 - DDK영역(저수준이고 익히는 사람도 드물다)
WinMain
{
윈도우생성 X
}

서비스 하나 만들기 위한 세 가지 프로그램

  • 서비스 프로그램 - 실제로 서비스 코드를 제공하는 프로그램
  • 서비스 설정 프로그램 - 서비스 설치와 제거에 대한 작업을 수행하는 프로그램
  • 서비스 제어 프로그램 - 사용자로부터 명령을 받아 서비스에게 명령을 전달하는 프로그램

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

파이프 추가내용  (0) 2010.01.20
Hooking  (0) 2010.01.15
IPC란?  (0) 2010.01.12
동기화  (0) 2010.01.12
디폴트 함수  (0) 2010.01.04
Posted by 아몰라

Ipc 는 두 프로그램이 상호 통신하며 정보를 교환하는 방법이다.


- 메세지

- 파이프

- 메일슬롯

- 소켓

파일매핑 - 프로세스간에 자원공유

등이 있다.


CreateNamedPipe(파이프명(\\.\pipe\파이프명, Access모드(읽고 쓰기), 파이프유형, 5(같은 파이프 이름 최대의 인스턴스 개수, 4096, 4096, 0(접근을 하기위한 대기시간), 보안기술자); 


메세지 보내는 유형
Stream - 파일같은거 보낼 때  PIPE_TYPE_BYTE 

Dgram   -리얼타임보장 예) 방송   PIPE_TYPE_MESSAGE


CreatenamedPipe()
----------------(1) 이 사이에 클라이언트 접속시 ConnectenamedPipe False로 반환된다.
ConnectenamedPipe(핸들, 0);

if(!Check)&&(GetLastError() == ERROR_PIPE_CONNECTED)) //(1) 상황일시 발생
{
Check = true;
}
if(Check)
{

}

FlushFileBuffer(hfile); //ffulsh와 유사, Disconected 를 해도 문제가 생기는데 운영체제에서 버퍼가 남는 문제가 생길수있다.

직렬화 - 객체정보를 화일에 전송

역직렬화 - 생성자

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

Hooking  (0) 2010.01.15
서비스  (0) 2010.01.13
동기화  (0) 2010.01.12
디폴트 함수  (0) 2010.01.04
API (원 가지고 놀기)  (0) 2010.01.04
Posted by 아몰라
동기화 - 스레드간의 실행 순서를 제어 할 수 있는 기술


Loop  : 자원 사용중
(1) ConTex Switching 이 발생? Atomic Operation
자원을 비 신호 상태로
               ---------------------------
Doit                                   임계구간(Critical Section) - Race condition을 방지
               ---------------------------
자원을 신호 상태로

ConTex Switching를 허용안하는 방법 -  타임인터럽트를 Disable하면 되지만 사용자 수준에서는 변경이 힘들다.


CRITICAL_SECTION cs;

Initialize CriticalSection(&cs);  //프로그램시작시

while(1)
{
-----------------
if(flag)
{
flag = false;                        Atomic 하게 만들었다.
doit();
------------------
flag=true;
break;
}
}
                                                
DeleteCriticalSection(&cs) //종료시
 



Mutax(상호배제)


신호상태 - 커널객체를 사용 할 수있는 상태
비신호상태  - 커널객체를 사용 할 수없는 상태

WaitForSingleObject(HANDLE hHAndle, DWORD dwMilliseconds);  //hHandle 이 지정하는 하나의 동기화 객체가 신호상태가 되기를 기다린다.

두번째 인자를 INFINITE로 지정하면 무한정 기다린다.


HANDLE CreateMutex(null, bool, lpName (뮤텍스를 구분하기위함)); //통상 프로그램 시작시

OpenMutex

CloseHandle(handle); //죵료시

비신호상태로 만들겠다 내가 점유하지 않은상태에서 만들겠다.

if(GetLastError() == ERROR_ALREADY_EXISTED)  // 이면 이미 프로그램이 가동중이다.

HANDLE hMu = CreateMutex(null, false, "hello");
{
if(get)
{
closeHandle(hMu)     //시작시 한번 들어오고 다음 스레드는 여기서 해제시킨다.
return;
}
}


세마포어 - 제한된 일정 개수를 가지는 자원을 보호하고 관리(뮤텍스와 유사하나 다수의 갯수를 관리)


HANDLE CreateSemaphore(보호기술자, 5(최대사용개수), 5(count초기값), 세마포어를 구분하기위한 문자열);
// 세마포어 카운트가 다 차야 비신호 상태가 된다.

이벤트

HANDLE CreateEvent(보안기술자,  ManualReset(자동이냐 수동이냐), bInitialState ,  
WaitForSingleObject(handle, INFINITE);
{
dout();
SetEvent(handle);
}
// ManualReset - True 이면 Set을 안한다!무한정 기다리기만 한다.
// SetEvent(hwnd); 이 필요
SetEvent()     //이벤트를 신호상태로
ResetEvent() //이벤틀를 비신호상태로





 

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

서비스  (0) 2010.01.13
IPC란?  (0) 2010.01.12
디폴트 함수  (0) 2010.01.04
API (원 가지고 놀기)  (0) 2010.01.04
API란?  (0) 2010.01.04
Posted by 아몰라


#include <windows.h>


LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
 switch( msg )
 {
 case WM_LBUTTONDOWN:
  return 0;
 case WM_RBUTTONDOWN:
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return DefWindowProc(hwnd, msg, wParam, lParam);
}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
       LPSTR lpCmdLine, int nShowCmd)
{
 // 1. 윈도우 클래스 만들기
 WNDCLASS wc;
 wc.cbWndExtra   = 0;
 wc.cbClsExtra   = 0;
 wc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
 wc.hCursor    = LoadCursor(0, IDC_ARROW);
 wc.hIcon    = LoadIcon(0, IDI_APPLICATION);
 wc.hInstance   = hInstance;
 wc.lpfnWndProc   = WndProc;   // DefWindowProc;
 wc.lpszClassName  = "First";
 wc.lpszMenuName   = 0;
 wc.style    = 0;

 // 2. 등록(레지스트리에)
 RegisterClass(&wc);

 // 3. 윈도우 창 만들기
 HWND hwnd = CreateWindowEx( 0,     // WS_EX_TOPMOST
     "first",    // 클래스 명
     "Hello",    // 캡션바 내용
     WS_OVERLAPPEDWINDOW,
     CW_USEDEFAULT , 0, CW_USEDEFAULT, 0, // 초기 위치
     0, 0,   // 부모 윈도우 핸들, 메뉴 핸들
     hInstance,  // WinMain의 1번째 파라미터 (exe 주소)
     0);   // 생성 인자

 

 // 4. 윈도우 보여주기
 ShowWindow(hwnd, SW_SHOW);
 UpdateWindow(hwnd);
 

 // 5. Message
 MSG msg;
 while( GetMessage( &msg, 0, 0, 0 ) )
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return 0;
}

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

서비스  (0) 2010.01.13
IPC란?  (0) 2010.01.12
동기화  (0) 2010.01.12
API (원 가지고 놀기)  (0) 2010.01.04
API란?  (0) 2010.01.04
Posted by 아몰라


HDC hdc;       //DC의 핸들 HDC 만들기
 PAINTSTRUCT ps;  //그림 그리기에 필요한 여러가지 데이터
 static int x;
 static int y;
  
 switch(iMessage)
 {
 case WM_DESTROY: PostQuitMessage(0); return 0;
 
 case WM_LBUTTONDOWN:
  x=LOWORD(IParam);
  y=HIWORD(IParam);      
  InvalidateRect(hWnd, NULL, TRUE);  //첫번째 인자: 무효화할 윈도우 
                                                      //두번째 인자: 무효화할 사각영역을 지정하되, NULL일 경우 전 영역 
                                                     //세번째 인자: 무효화되기 전에 배경을 모두 지운 후 다시 그릴 것인지 아니면   배경을 지우지 않고 그릴 것인지를 지정한다. 이 값이 TRUE 이면 배경을 지운 후 다시 그리고 FALSE이면 배경을 지우지 않은 채로 다시 그린다.

  return 0;

 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);  // 윈도우 핸들과 페인트 정보 구조체
  Ellipse(hdc, x-100, y-100, x+100, y+100); //원그리기
  EndPaint(hWnd, &ps); 
  return 0; 

 case WM_KEYDOWN:
  switch(wParam)
  {
  case VK_LEFT:
   x-=10;
   break;
  case VK_RIGHT:
   x+=10;
   break;
  case VK_UP:
   y-=10;
   break;
  case VK_DOWN:
   y+=10;
   break;
  }
  InvalidateRect(hWnd, NULL, TRUE);
 }

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

서비스  (0) 2010.01.13
IPC란?  (0) 2010.01.12
동기화  (0) 2010.01.12
디폴트 함수  (0) 2010.01.04
API란?  (0) 2010.01.04
Posted by 아몰라
이전버튼 1 2 3 이전버튼