[TCP/IP] #2-1. 오류 처리

오류 처리

윈도우에서 소켓 함수 호출 시 발생하는 오류 처리 방법에 대해 알아본다.

 

  • 오류 처리 방법의 세 가지 유형
    1. 오류를 처리할 필요가 없는 경우
      • 리턴 값이 없거나 항상 성공하는 일부 소켓 함수
    2. 리턴값만으로 오류를 확인하고 처리하는 경우
      • 윈도우의 WSAStartup() 함수
    3. 리턴값으로 오류 발생을 확인 후, 구체적인 내용은 오류 코드로 확인하는 경우
      • 대부분의 소켓 함수
      • 1번과 2번은 특수한 경우이므로, 이번에는 3번 유형을 처리하는 방법을 알아본다.

윈도우 오류 처리

  • 오류 코드 확인 방법
    • 함수의 리턴값으로 오류 발생 확인
    • WSAGetLastError()의 리턴 값으로 오류 코드 얻기
    • 오류 메시지 문자열은 FormatMessage()로 얻는다.

 

  • FormatMessage()
      #include <windows.h>
      DWORD FormatMessage(
          DWORD dwFlags,  // 1
          LPCVOID lpSource,
          DWORD dwMessageId,  // 2
          DWORD dwLanguageId, // 3
          LPTSTR lpBuffer,    // 4
          DWORD nSize,
          va_list *Arguments
      )
    

 

  1. dwFlag
    • FORMAT_MESSAGE_ALLOCATE_BUFFER: 오류 메시지 저장 공간을 FormatMessage()가 알아서 할당한다.
    • FORMAT_MESSAGE_FROM_SYSTEM: OS에서 오류 메시지를 가져온다.
  2. dwMessageId
    • 오류 코드(WSAGetLastError()의 리턴값)
  3. dwLanguageId
    • 오류 메시지를 표시할 언어(시스템의 기본 언어)
  4. lpBuffer
    • 오류 메시지의 시작 주소가 저장
    • 오류 메시지 사용을 마치면 LocalFree()로 메모리 해제 필요

 

  • FormatMessage()를 사용한 오류 처리 함수 예시
      void err_quit(const char *msg)
      {
          LPVOID lpMsgBuf;
          FormatMessageA(
              FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
              NULL, WSAGetLastError(),
              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
              (char*)&lpMsgBuf, 0, NULL);
    
          MessageBoxA(NULL, (const char*)lpMsgBuf, msg, MB_ICONERROR);
          LocalFree(lpMsgBuf);
          exit(1);
      }
    

 

💡 FormatMessageA(), MessageBoxA()

  • 윈도우 문자열 관련 API에는 ANSI와 유니코드 버전이 있다.
    • A로 끝나는 함수: ANSI
    • W로 끝나는 함수: 유니코드
    • 접미어 없는 함수: 프로젝트 설정에 따라 자동으로 선택된다.

 

  • 사용 예
      if (socket(...) == INVALID_SOCKET) err_quit("socket()");
      if (bind(...) == SOCKET_ERROR) err_quit("bind()");
    
    • 오류 발생 시 메시지 상자가 화면에 표시되고, [확인]을 누르면 프로그램이 종료된다.

출처 TCP/IP 소켓 프로그래밍

Categories:

Updated:

Leave a comment