UNIX 소켓을 기반으로 윈도우 환경에서 사용할 수 있게 만든 네트워크 프로그래밍 인터페이스.
WSAStartup()
) 및 종료(WSACleanup()
) 작업을 위한 함수가 필요하다.Winsock을 사용하는 응용 프로그램의 흐름도는 Winsock 초기화
→ 소켓 생성
→ 통신
→ 소켓 닫기
→ Winsock 종료
와 같다.
Winsock을 사용하려면 먼저 사용할 Winsock 버전을 요청하여 Winsock 라이브러리를 초기화해야한다. 이때 사용하는 것이 WSAStartup()
함수이다.
// int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
WSADATA wsa;
WSAStartup(MAKEWORD(3, 2), &wsa != 0)
Winsock 초기화에는 요청 버전과 WSADATA 구조체를 파라미터로 전달한다.
WSADATA에서는 Winsock 버전, 시스템이 지원하는 최상위 Winsock 버전 등에 대한 정보를 얻을 수 있다. 응용 레벨에서 그다지 쓸 일은 없다.
성공 시 0
, 실패 시 오류 코드 (MSDN 참고!)
를 반환한다.
💡 WSAStartup() 은 직접 오류 코드를 반환한다!
일반적으로 소켓 함수의 에러 코드를 얻을 때에는
WSAGetLastError()
함수를 사용한다. 그러나 이 함수는 이름 그대로 호출 스레드의 가장 마지막 에러를 반환하기 때문에 부정확할 수 있다. 따라서 WSAStartup() 은 스스로 오류 코드를 반환한다.
💡 비동기 함수의 오류 코드 확인을 위해
WSAGetLastError()
를 사용해서는 안된다.아직 비동기 모델까지는 포스팅하지 않았지만. 위의 이유와 마찬가지로 그러하다.
공식 문서에도 명시되어 있다. 비동기 함수의 경우에는 lParam에 오류 코드 값이 전달된다.
// int WSACleanup(void)
WSACleanup();
별도의 매개변수 없이 호출한다. 이 함수를 호출하면 OS에게 사용이 끝났음을 알리고 리소스를 반환한다.
성공 시 0
, 실패 시 SOCKET_ERROR
자세한 에러 코드는 WSAGetLastError()
함수를 호출해 파악할 수 있다.
// SOCKET socket(int af, int type, int protocol)
SOCKET TCP_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKET UDP_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
AF(Address Family)
는 주소 체계, Type
는 소켓 타입, Protocol
은 프로토콜을 의미한다.
상수명 | 용도 |
---|---|
AF_INET | IPv4 기반 TCP, UDP |
AF_INET6 | IPv6 기반 TCP, UDP |
AF_IRDA | IrDA |
AF_BTH | 블루투스 |
상수명 | 설명 |
---|---|
SOCK_STREAM | TCP 프로토콜 기반 - 신뢰성, 연결형 |
SOCK_DGRAM | UDP 프로토콜 기반 - 비신뢰성, 비연결형 |
상수명 | 설명 |
---|---|
IPPROTO_TCP | TCP 프로토콜 |
IPPROTO_UDP | UDP 프로토콜 |
성공 시 SOCKET
, 실패 시 INVALID_SOCKET
성공해서 받아온 SOCKET
핸들 값을 사용해 소켓 함수를 호출한다.
// int closesocket(SOCKET s)
int closeRet = closesocket(socket);
이 함수를 호출하면 해당 소켓을 닫고 리소스를 반환한다. 이때의 동작은 Linger 옵션에 따라 달라질 수 있다.
💡 Linger 옵션에 따른 closesocket() 동작 방식 차이
일단 한 번 FIN을 보내면 4-way-handshake로의 진입(graceful shutdown) 을 막을 수 없다.
이 경우 FIN을 보낸 쪽(먼저 연결을 종료한 쪽)에 TIME_WAIT이 남게 되어 부하가 발생한다. 이를 위해 Linger 옵션을 조정하여 RST를 날리고, 연결을 강제 종료할 수 있다. (→ TIME_WAIT이 남지 않는다.)
시간이 되면 closesocket() 과 shutdown() 의 차이, Linger 옵션에 따른 TCP State 변화에 대해서도 기록하기!