ch02. 소켓 시작하기

해담·2024년 10월 13일

오류 처리

윈도우 오류 처리

소켓 함수의 리턴값으로 오류 발생이 확인되었다면, WSAGetLastError() 함수를 사용해 구체적인 오류 코드를 얻을 수 있습니다. WSAGetLastError() 오류 코드에 대응하는 오류 메시지는 FormatMessage() 함수로 얻을 수 있습니다.

err_quit() 함수는 msg 인수로 전달된 문자열과 더불어 현재 발생한 오류 메시지를 화면에 메시지 상자로 표시하고 응용 프로그램을 종료하는 역할을 합니다.
err_disply() 함수는 오류 메시지를 출력하되 응용 프로그램을 종료하지 않습니다.

리눅스 오류 처리

소켓 함수의 리턴값으로 오류 발생이 확인되었다면, 전역 변수 errno로 구체적인 오류 코드를 얻을 수 있습니다. errno 오류 코드에 대응하는 오류 메시지는 strerror() 함수로 얻을 수 있습니다. strerror() 함수는 오류 코드를 입력으로 받아 오류 메시지를 리턴합니다.

err_quit() 함수와 err_disply() 함수의 사용법은 윈도우와 동일합니다.

소켓 초기화와 종료 (윈도우)

윈도우에서는 소켓 생성 전에 '윈속 초기화'와 소켓 닫기 후에 '윈속 종료' 단계가 더 필요합니다.

WSAStartup() 함수는 프로그램에서 사용할 윈속 버전을 요청하여 윈속 라이브러리(WS2_32.DLL)를 초기화합니다. 해당 함수가 실패하면 WS2_32.DLL이 메모리에 로드되지 않습니다. 이 경우는 앞 절에서 소개한 WSAGetLastError() 함수의 오류 정보가 부정확하므로 WSAStartup() 함수가 직접 오류 코드를 리턴하도록 설계되어 있습니다.

프로그램을 종료할 때는 윈속 종료 함수인 WSACleanup() 함수를 사용하여, 윈속 사용의 중지를 운영체제에 알려서 관련 리소스를 반환하게 하니다. 함수 호출이 실패하면 WSAGetLastError() 함수를 호출하여 구체적인 오류 코드를 얻을 수 있습니다.

소켓 생성과 닫기

소켓을 사용해 통신하려면 통신 양단이 같은 프로토콜을 사용해야 합니다. 예를 들면, TCP를 사용할 것인지 혹은 UDP를 사용할 것인지를 약속해야 합니다.

소켓 생성하기

socket() 함수는 사용자가 요청한 프로토콜을 사용해 통신할 수 있도록 내부적으로 리소스를 할당하고, 이에 접근할 수 있는 일종의 핸들값을 리턴합니다. 이 값을 소켓 디스크립터라고 부르며, 각종 소켓 함수를 호출할 때 인수로 전달합니다.

socket() 함수는 인수로, 주소 체계, 소켓 타입, 사용할 프로토콜을 전달받습니다. 주소 체계만 윈도우에서 af, 리눅스에서 domain이고, 소켓 타입은 type, 사용할 프로토콜은 protocol입니다.

주소 체계

사용할 프로토콜 주소 체계
IPv4 AF_INET
IPv6 AF_INET6
블루투스 AF_BTH

위 표는 주소 체계를 나타내는 대표적인 상숫값입니다. 자신이 사용할 프로토콜에 대응하는 값을 선택하여 socket() 함수의 첫 번째 인수로 전달하면 됩니다.

소켓 타입

사용할 프로토콜 주소 체계 소켓 타입
TCP AF_INET 또는 AF_IENT6 SOCKET_STREAM
(특성: 신뢰성 있는 데이터 전송, 연결형 프로토콜)
UDP AF_INET 또는 AF_IENT6 SOCKET_DGRAM
(특성: 신뢰성 없는 데이터 전송, 비연결형 프로토콜)

주소 체계가 같아도 소켓 타입을 다르게 설정할 수 있으며, 결과적으로 사용할 프로토콜의 종류는 소켓 타입에 따라 달라집니다.

프로토콜

주소 체계와 소켓 타입만으로 프로토콜을 결정할 수 있는 예도 있으나 일반적으로는 두 개가 같아도 이에 해당하는 프로토콜이 두 개 이상 존재합니다. 이때는 프로토콜을 명시적으로 지정해야 하며, socket() 함수의 세 번째 인수가 이 역할을 합니다. 하지만 TCP나 UDP 프로토콜은 주소 체계와 소켓 타입만으로 프로토콜을 결정할 수 있으므로 대개는 프로토콜 부분에 0을 넣습니다.

사용할 프로토콜 주소 체계 소켓 타입 프로토콜
TCP AF_INET 또는 AF_IENT6 SOCKET_STREAM IPPROTO_TCP
UDP AF_INET 또는 AF_IENT6 SOCKET_DGRAM IPPROTO_UDP

소켓 닫기

소켓을 사용한 통신을 마치면 해당 소스를 닫고 관련 리소스를 운영체제에 반환해야 합니다. 이때, closesocket() 함수(윈도우) 또는 close() 함수(리눅스)를 사용합니다. 인수로는 소켓을 생성할 때 지정한 소켓 이름(또는 리눅스에서는 파일 디스크립터 값인 정수형 값)를 넣습니다.

profile
해담이를먹여살리기위한..

0개의 댓글