(2-3 그림)
위 그림은 모든 윈속 응용 프로그램의 공통 구조를 보여준다. 여기에서는 윈속 초기화와 종료 방법을 소개하겠다.
모든 윈속 프로그램은 소켓 함수를 호출하기 전에 반드시 윈속 초기화 함수인 WSAStartup()
을 호출해야 한다. WSAStartup()
함수는 프로그램에서 사용한 윈속 버전을 요청하여 윈속 라이브러리(ws2_32.DLL
)를 초기화하는 역할을 한다.
WSAStartup()
함수가 실패할 경우 ws2_32.DLL
이 메모리에 로드되지 않는다. 이 경우 WSAGetLastError()
함수가 리턴하는 오류 코드는 부정확하기 때문에 WSAStartup()
함수는 오류 코드를 리턴하도록 설계되어 있다.
// 성공: 0, 실패: 오류코드
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
0x0203
또는 MAKEWORD(3, 2)
를 사용한다.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;
WSAStartup()
함수 사용 시 주의 사항WSAStartup()
함수를 호출할 때 요청하는 윈속 버전이 같아도 실제 사용 가능한 프로토콜은 운영 체제에 따라 달라지기 때문에 주의해야한다.
예를 들면 IPv6는 윈도우 XP SP1 이상에서만 사용할 수 있고, 블루투스(Bluetooth)는 윈도우 XP SP2 이상에서만 사용할 수 있다.
WSAStartup()
함수를 두 번 이상 호출하는 것도 가능하다.
예를 들어 MFC 소켓 클래스의 경우 윈속 1.1 버전만 지원하지만 윈속 2.2 버전을 사용하도록 WSAStartup()
함수를 다시 호출할 수 있다. 단, WSAStartup()
함수를 호출한 횟수만틈 SWACleanup()
함수를 호출해야한다.
프로그램을 종료할 때는 윈속 종료 함수인 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