블로그 이미지
vee

카테고리

분류 전체보기 (17)
void (1)
Information (0)
Develop (5)
Linux (3)
Hardware (3)
Operating system (5)
Total
Today
Yesterday

달력

« » 2026.7
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

최근에 올라온 글

서로 통신을 하려면 두 개의 소켓을 생성하여 자료를 송수신하게 된다.

이 때 두개의 소켓을 생성하는 가장 간단한 방법이 socketpair 함수를 사용하는 것이다.

socketpair 함수는 두 개의 소켓을 생성해주면서 자동으로 연결해주는 작업도 수행하기 때문에
개발자는 read와 write함수를 호출하여 자료를 송수신하면 된다.

 

int socketpair(int domain, int type, int protocol, int sd[2]);

domain – 사용할 프로토콜 패밀리
type – 해당 프로토콜에서 사용할 소켓의 유형
protocol – IPPROTO_TCP, IPPROTO_UDP, NULL 등의 프로토콜
sd[2] – sd[0], sd[1]

'Develop > TCP/IP' 카테고리의 다른 글

TCP/IP Socket programming  (0) 2013.09.06
Posted by vee
, |

 

응용프로그램에서 소켓을 생성하면 해당 소켓에 대한 포인터를 가지고 있는 기술자 테이블(Descriptor Table)의 색인(Index)를 얻게 되는데,
이것을 소켓 기술자(Socket Descriptor)라고 부른다. (Windows에서는 소켓 핸들)

응용프로그램에서 소켓을 생성할 때는 socket함수를 사용한다.

Visual C++에서의 socket 함수

SOCKET

WSAAPI

socket(

_In_ int af,

_In_ int type,

_In_ int protocol

);

af = Address Family (domain) – 사용할 프로토콜 패밀리
type – 프로토콜에서 사용할 소켓 유형
protocol – 사용할 프로토콜

return value

  • 지정한 유형의 소켓을 성공적으로 생성하면 소켓 기술자(소켓 핸들)을 반환한다.
  • 소켓을 성공적으로 생성하지 못하면 socket 함수는 -1을 반환한다.
  • typedef UINT_PTR SOCKET; (Winsock2.h)
  • typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;

인자

비고

domain

PF_INET

IPv4 인터넷 프로토콜 패밀리

PF_INET6

IPv6인터넷 프로토콜 패밀리

PF_LOCAL

로컬 유닉스 소켓 프로그램 패밀리

PF_UNIX

로컬 유닉스 소켓 프로그램 패밀리

type

SOCK_STREAM

스트림 소켓

SOCK_DRAM

데이터그램 소켓

SOCK_RAW

Raw 소켓

SOCK_SEQPACKET

순차 패킷 소켓

protocol

IPPROTO_TCP

스트림 소켓

IPPROTO_UDP

데이터그램 소켓

 

socket은 사용한 후 더 이상 사용하지 않으면 소켓을 종료하고 자원을 반납해야 한다.
이 때 사용하는 함수가 close 함수이다. (Winsock에서는 closesocket)

int

WSAAPI

closesocket(

_In_ SOCKET s

);

SOCKET – 종료할 소켓

return value

  • 성공하면 0, 실패하면 -1

 

소켓 기술자 (소켓 핸들)을 이용하여 자료를 송신하고 수신할 수 있다.

리눅스에서는 read 함수를 이용하여 자료를 수신하며
Winsock에서는 recv 함수를 이용한다.

int read(int fd, void *buf, int count); - 리눅스

int

WSAAPI

recv(

_In_ SOCKET s,

_Out_writes_bytes_to_(len, return) __out_data_source(NETWORK) char FAR * buf,

_In_ int len,

_In_ int flags

);

SOCKET s – 자료를 수신할 소켓 핸들
char FAR * buf – 수신한 자료를 저장할 버퍼의 주소 (포인터)
int len – 수신하는 자료의 최대 크기 (byte)
int flags – 옵션, NULL이면 리눅스 에서의 read 함수와 동일

return value

  • 성공 – 실제 수신한 자료의 크기 (byte)
  • 실패 – -1

 

리눅스에서는 write 함수를 이용하여 자료를 송신하며
Winsock에서는 send 함수를 이용한다.

int write(int fd, const void *buf, int count);

int

WSAAPI

send(

_In_ SOCKET s,

_In_reads_bytes_(len) const char FAR * buf,

_In_ int len,

_In_ int flags

);

SOCKET s – 자료를 송신할 소켓 핸들
const char FAR * buf – 전송할 자료를 저장하는 버퍼의 주소 (송신 버퍼)
int len – 전송할 자료의 최대 크기 (byte)
int flags – 옵션, NULL이면 리눅스 에서의 write와 동일

return value

  • 성공 – 실제 쓴 자료의 크기 (byte)
  • 실패 – -1
Posted by vee
, |

typedef struct tagWNDCLASSW {

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HINSTANCE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCWSTR lpszMenuName;

LPCWSTR lpszClassName;

}

 

UINT style;

윈도우 스타일, 즉 윈도우가 어떤 형태를 가질 것인가를 지정한다.

가장 많이 사용되는 값은 CS_HEADRAW|CS_VREDRAW이다.

특이하게도 OR 연산자를 이용하는 기법을 사용한다. (고성능, 고효율)

 

WNDPROC lpfnWndProc;

윈도우의 메시지 처리 함수를 지정한다. – 함수 포인터

메시지가 발생할 때 마다 이 멤버가 지정한 함수가 호출되며 모든 메시지를 처리하게 된다.

WndProc을 대입하게 된다.

 

int cbClsExtra;

int cbWndExtra;

일종의 예약 영역으로서 아주 특수한 목적에 사용되는 여분의 공간이다.

예약 영역을 사용하지 않을 때는 0으로 지정한다.

HINSTANCE hInstance;

이 윈도우 클래스를 등록하는 프로그램의 번호(핸들)이며 WinMain의 인수로 전달된 hInstance값을 그대로 대입하게 된다.

핸들은 운영체제가 임의로 생성하는 값으로 프로그래머가 특정한 값을 생각할 필요는 없다.

 

HICON hIcon;

HCURSOR hCursor;

이 윈도우가 사용할 마우스 커서와 아이콘을 지정하는 변수이다.

LoadCursor함수와 LoadIcon함수를 이용하여 이 멤버에 대입하면 된다.

 

HBRUSH hbrBackground;

윈도우의 배경 색상을 채색할 브러시를 지정하는 멤버이다.

GetStockObject 함수를 이용하여 윈도우에서 제공하는 브러시를 지정하거나 COLOR_WINDOW같은 시스템 색상을 지정할 수도 있다.

 

LPCWSTR lpszMenuName;

이 프로그램(윈도우)이 사용할 메뉴를 지정한다.

메뉴는 리소스 에디터에 의해 별도로 만들어져 링크시 같이 합쳐지며 메뉴를 사용하지 않을 경우 NULL을 대입한다.

 

LPCWSTR lpszClassName;

윈도우 클래스의 이름을 문자열로 정의하는 멤버.

여기서 지정한 이름은 CreteWindow함수에 전달되며 CreteWIndow 함수는 윈도우 클래스에서 정의한 특성 값을 참조하여 윈도우를 만든다.

 

WNDCLASS는 WinUser.h에 정의되어 있다.

WNDCLASS는 프로젝트가 유니코드이거나 멀티바이트일 때 다르게 정의된다.

#ifdef UNICODE

typedef WNDCLASSW WNDCLASS;

typedef PWNDCLASSW PWNDCLASS;

typedef NPWNDCLASSW NPWNDCLASS;

typedef LPWNDCLASSW LPWNDCLASS;

#else

typedef WNDCLASSA WNDCLASS;

typedef PWNDCLASSA PWNDCLASS;

typedef NPWNDCLASSA NPWNDCLASS;

typedef LPWNDCLASSA LPWNDCLASS;

#endif // UNICODE

WNDCLASSA 는 멀티바이트 Windows 응용프로그램에서 사용되며
WNDCLASSW는 유니코드 Windows 응용프로그램에서 사용된다.

두 클래스의 차이는 문자열을 LPCSTR 을 사용하느냐 아니면 LPCWSTR를 사용하느냐의 차이만 존재한다.

'Develop > Windows API' 카테고리의 다른 글

Windows API – 2. WinMain, WndProc  (0) 2013.08.29
Windows API – 1. Basis of Windows Programming  (0) 2013.08.28
Posted by vee
, |

 

Windows.h

기본적인 데이터 타입, 함수 원형, 매크로 상수 등을 정의하며 그 외 Windows 프로그래밍에 필요한 보조 헤더 파일을 포함하고 있다.

 

Win32 응용프로그램의 Entry Point(시작점)은 main()이 아니라 WinMain()이다.

 

WinMain의 원형

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)

  • WinMain의 원형은 고정되어 있다.
  • APIENTRY 지정자는 Windows의 표준 호출 규약인 __Stdcall을 사용한다는 뜻
  • hInstance : 프로그램의 인스턴스 핸들
  • hPrevInstance : 바로 앞에 실행된 현재 프로그램의 인스턴스 핸들
  • lpszCmdParam : argv에 해당
  • nCmdShow : 프로그램이 실행될 형태이며 최소화, 보통 모양 등이 전달됨

 

WndProc 함수

WndProc 함수는 사용자와 시스템이 보내오는 메시지를 처리하는 역할

Windows 응용 프로그램은 WinMain과 WndProc이 전부 존재해야 정상적으로 동작할 수 있다.

 

WndProc의 원형

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

  • CALLBACK 매크로는 APIENTRY와 마찬가지로 __stdcall로 정의되어 있다.
Posted by vee
, |

 

Windows Application Programming Interface

Windows API

 

Textbook – Windows API 정복 개정판 (한빛미디어, 김상형)

 

첫 번째 예제 – 기본 윈도우 띄우기

 

Source code

#include <Windows.h>

 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE g_hInst;

LPCTSTR lpszClass=TEXT("First API project");

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)

{

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst=hInstance;

 

    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL, IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW|CS_VREDRAW;

    RegisterClass(&WndClass);

 

    hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);

 

    while(GetMessage(&Message, NULL, 0, 0))

    {

        TranslateMessage(&Message);

        DispatchMessage(&Message);

    }

    return (int)Message.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

{

    switch(iMessage)

    {

    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    }

    return(DefWindowProc(hWnd, iMessage, wParam, lParam));

}

 

Compile

Posted by vee
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함