윈도우 소켓 초기화와 종료

bolee·2022년 4월 4일
0

(2-3 그림)

위 그림은 모든 윈속 응용 프로그램의 공통 구조를 보여준다. 여기에서는 윈속 초기화와 종료 방법을 소개하겠다.

WSAStartup

모든 윈속 프로그램은 소켓 함수를 호출하기 전에 반드시 윈속 초기화 함수인 WSAStartup()을 호출해야 한다. WSAStartup() 함수는 프로그램에서 사용한 윈속 버전을 요청하여 윈속 라이브러리(ws2_32.DLL)를 초기화하는 역할을 한다.
WSAStartup() 함수가 실패할 경우 ws2_32.DLL이 메모리에 로드되지 않는다. 이 경우 WSAGetLastError() 함수가 리턴하는 오류 코드는 부정확하기 때문에 WSAStartup() 함수는 오류 코드를 리턴하도록 설계되어 있다.

// 성공: 0, 실패: 오류코드
int WSAStartup(
	WORD wVersionRequested,
    LPWSADATA lpWSAData
);
  • wVersionRequested: 프로그램이 요규하는 최상위 윈속 버전이다. 하위 8비트에 주(major) 버전, 상위 8비트에 부(minor) 버전을 넣어 전달한다. 예를 들어, 윈속 3.2 버전사용을 요청한다면 0x0203 또는 MAKEWORD(3, 2)를 사용한다.
  • lpWSAData: WSADATA 구조체를 전달하면 이를 통해 윈도우가 제공하는 윈속 구현에 관한 정보(응용 프로그램이 실제 사용하게 될 윈속 버전, 시스템이 지원하는 윈속 최상위 버전 등)을 얻을 수 있다. 하지만 응용 프로그램이 이런 정보를 사용할 일은 거의 없다.

WSADATA

윈속 구현에 관한 정보를 담을 수 있는 구조체로 초기화 함수 내부에서 윈속 속성 정보로 설정해준다.
실제 네트워크 프로그래밍에서 이를 활용할 필요는 없으며, 하위 버전과의 호환성을 위해 남아있는 것이다.

WSADATA 구조체는 winsock.h에서 확인할 수 있으며, 아래와 같이 정의 되어 있다.

typedef struct WSAData
{
    WORD           wVersion;
    WORD           wHighVersion;
    unsigned short iMaxSockets;
    unsigned short iMaxUdpDg;
    char           *lpVendorInfo;
    char           szDescription[WSADESCRIPTION_LEN + 1];
    char           szSystemStatus[WSASYS_STATUS_LEN + 1];
}	WSADATA;
  • wVersion: 윈속 버전
  • wHighVersion: 사용할 수 있는 상위 버전으로 wVersion과 일치
  • iMaxSockets: 최대 소켓 수
  • iMaxUdpDg: 데이터 그램 메세지의 최대 크기
  • lpVendorInfo: 벤더(vendor) 정보
  • szDescription[WSADESCRIPTION_LEN + 1]: 윈속 구현에 대한 설명
  • szSystemStatuspWSASYS_STATUS_LEN + 1]: 관련 상태 또는 구성 정보

WSAStartup() 함수 사용 시 주의 사항

  1. WSAStartup() 함수를 호출할 때 요청하는 윈속 버전이 같아도 실제 사용 가능한 프로토콜은 운영 체제에 따라 달라지기 때문에 주의해야한다.
    예를 들면 IPv6는 윈도우 XP SP1 이상에서만 사용할 수 있고, 블루투스(Bluetooth)는 윈도우 XP SP2 이상에서만 사용할 수 있다.

  2. WSAStartup() 함수를 두 번 이상 호출하는 것도 가능하다.
    예를 들어 MFC 소켓 클래스의 경우 윈속 1.1 버전만 지원하지만 윈속 2.2 버전을 사용하도록 WSAStartup()함수를 다시 호출할 수 있다. 단, WSAStartup()함수를 호출한 횟수만틈 SWACleanup()함수를 호출해야한다.

WSACleanup

프로그램을 종료할 때는 윈속 종료 함수인 WSACleanup()을 호출해야 한다. WSACleanup()함수는 윈속 사용을 중지하는 것을 운영체제에 알라고, 관련 리소스를 반환하는 역할을 한다.
함수 호출이 실패할 경우 WSAGetLastError()함수를 호출함으로써 구체적인 오류 코드를 얻을 수 있다.

// 성공: 0, 실패: SOCKET_ERROR
int WSACleanup(void);

윈속 초기화 및 종료

위의 내용을 가지고 윈속을 초기화하고 종료하는 간단한 콘솔 응용 프로그램은 아래와 같다.

#pragma comment(lib, "ws2_32")
#include <winsock2.h>

int main(int argc, char *argv[])
{
	// 윈속 초기화
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    	return 1;
    MessageBox(NULL, "윈속 초기화 성공", "알림", MB_OK);
    
    // 윈속 종료
    WSACleanup();
    return 0;
}

컴파일, 링크 후 실행 결과는 다음과 같다.

참고 자료
김성우 저, "TCP/IP 윈도우 소켓 프로그래밍", 한빛아카데미, 2018

0개의 댓글