IPPROTO_IP 수준에서 소켓 옵션을 설정/가져올 때 헤더 및 라이브러리 요구 사항

  • 아티클
  • 2023. 07. 17.
  •  

이 문서의 내용

  1. 요약
  2. Winsock.h의 IPPROTO_IP 수준 소켓 옵션
  3. Ws2tcpip.h의 IPPROTO_IP 수준 소켓 옵션
  4. Setsockopt 또는 getsockopt 런타임 오류

이 문서에서는 수준에서 소켓 옵션을 IPPROTO_IP 설정하거나 가져올 때 헤더 및 라이브러리 요구 사항에 대한 정보를 제공하며 setsockopt 런타임 오류로 또는 getsockopt 함수가 실패합니다.

원래 제품 버전: Winsock
원래 KB 번호: 257460

요약

프로그램 프로젝트의 올바른 헤더 및 라이브러리 파일을 포함하여 Windows를 대상으로 하는 C/C++ Winsock 애플리케이션 수준에서 소켓 옵션을 IPPROTO_IP 설정하거나 가져오는 경우 매우 중요합니다. 헤더 및 라이브러리 파일이 제대로 일치하지 setsockoptgetsockopt 않거나 런타임 오류 10042(WSAENOPROTOOPT)로 실패할 수 있는 경우 경우에 따라 API가 성공적으로 반환되더라도 설정하거나 가져오는 옵션 값이 예상과 다를 수 있습니다.

이 문제를 방지하려면 다음 지침을 따릅니다.

  • 포함된 Winsock.h 프로그램은 .에 Wsock32.lib만 연결되어야 합니다.
  • 포함된 Ws2tcpip.h 프로그램은 둘 중 하나 Ws2_32.lib 또는 Wsock32.lib.와 연결 될 수 있습니다.
  • 참고
  • Ws2tcpip.h 이 수준에서 소켓 옵션을 사용하려면 이후에 Winsock2.h 명시적으로 포함되어야 합니다.

Winsock.h의 IPPROTO_IP 수준 소켓 옵션

IPPROTO_IP 수준 소켓 옵션은 .에서 Winsock.hWs2tcpip.h와 다르게 정의됩니다. 에서 Winsock.h정의는 다음과 같습니다.

C++
/*
 * Options for use with [gs]etsockopt at the IP level.
 */
#define IP_OPTIONS          1           /* set/get IP per-packet options    */
#define IP_MULTICAST_IF     2           /* set/get IP multicast interface   */
#define IP_MULTICAST_TTL    3           /* set/get IP multicast timetolive  */
#define IP_MULTICAST_LOOP   4           /* set/get IP multicast loopback    */
#define IP_ADD_MEMBERSHIP   5           /* add  an IP group membership      */
#define IP_DROP_MEMBERSHIP  6           /* drop an IP group membership      */
#define IP_TTL              7           /* set/get IP Time To Live          */
#define IP_TOS              8           /* set/get IP Type Of Service       */
#define IP_DONTFRAGMENT     9           /* set/get IP Don't Fragment flag   */
#define IP_DEFAULT_MULTICAST_TTL   1    /* normally limit m'casts to 1 hop  */
#define IP_DEFAULT_MULTICAST_LOOP  1    /* normally hear sends if a member  */
#define IP_MAX_MEMBERSHIPS         20   /* per socket; must fit in one mbuf */

Ws2tcpip.h의 IPPROTO_IP 수준 소켓 옵션

이 수준의 옵션은 다음과 같이 정의됩니다.Ws2tcpip.h

C++
/*
 * Option to use with [gs]etsockopt at the IPPROTO_IP level.
*/
#define IP_OPTIONS             1     /* set/get IP options */
#define IP_HDRINCL             2     /* header is included with data */
#define IP_TOS                 3     /* IP type of service and preced*/
#define IP_TTL                 4     /* IP time to live */
#define IP_MULTICAST_IF        9     /* set/get IP multicast i/f  */
#define IP_MULTICAST_TTL       10     /* set/get IP multicast ttl */
#define IP_MULTICAST_LOOP      11     /*set/get IP multicast loopback */
#define IP_ADD_MEMBERSHIP      12     /* add an IP group membership */
#define IP_DROP_MEMBERSHIP     13    /* drop an IP group membership */
#define IP_DONTFRAGMENT        14     /* don't fragment IP datagrams */

Setsockopt 또는 getsockopt 런타임 오류

헤더 및 라이브러리 파일 setsockoptgetsockopt 과 올바르게 일치하지 않거나 런타임 오류 10042(WSAENOPROTOOPT)로 실패하거나 설정하거나 가져오는 옵션 값이 예상과 다를 수 있습니다.

사례 1: 런타임 오류 10042(WSAENOPROTOOPT)

이 범주에 속하는 옵션은 다음과 같습니다.

  • IP_ADD_MEMBERSHIP
  • IP_DROP_MEMBERSHIP
  • IP_TTL
  • IP_TOS

다음과 유사한 코드를 실행하여 멀티캐스트 그룹에 조인하려는 경우를 가정합니다.

C++
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

int main(int argc, char* argv[])
{
   ...
   if (setsockopt(sock,
                  IPPROTO_IP,
                  IP_ADD_MEMBERSHIP,
                  (char FAR *)&mreq,
                  sizeof (mreq)) == SOCKET_ERROR)
   {
      printf ("setsockopt failed: %d"), WSAGetLastError());
      closesocket (sock);
      return FALSE;
   }
   ...
}

참고

여기에는 Winsock.h가 포함됩니다. 프로젝트가 연결된 Ws2_32.lib경우 setsockopt는 런타임 오류 10042(WSAENOPROTOOPT)로 실패합니다. 이는 in에서 Winsock.hIP_ADD_MEMBERSHIP 5로 정의되었기 때문입니다. 해당 Winsock 런타임은 수준에서 옵션 5를 IPPROTO_IP 확인할 수 없으므로 오류 코드 10042로 오류가 발생합니다.

사례 2: 옵션 설정 또는 적용 안 함

이 범주에 속하는 옵션은 다음과 같습니다.

  • IP_MULTICAST_IF
  • IP_MULTICAST_TTL
  • IP_MULTICAST_LOOP
  • IP_DONTFRAGMENT

IP_MULTICAST_TTL 예를 들면 다음과 같습니다. IP_MULTICAST_TTL 에서 Winsock.h3으로 정의됩니다. 에서 ws2tcpip.h상수는 10으로 정의되고 IP_TOS 3으로 정의됩니다. 기본 TTL 값을 변경해 보세요.

C++
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

int main(int argc, char* argv[])
{
   int ttl = 7 ; // Arbitrary TTL value.
   ...
   source_sin.sin_family = AF_INET;
   source_sin.sin_port = htons(0);
   source_sin.sin_addr.s_addr = htonl (INADDR_ANY);

    if (bind(sock,
                (struct sockaddr FAR *)&source_sin,
                sizeof(source_sin)) == SOCKET_ERROR)
    {
        printf ("bind() failed: %d"), WSAGetLastError());
        closesocket (sock);
        return FALSE;
    }

    if (setsockopt(sock,
                      IPPROTO_IP,
                      IP_MULTICAST_TTL,
                      (char *)&ttl,
                      sizeof(ttl))) == SOCKET_ERROR)
    {
        printf ("setsockopt failed: %d"), WSAGetLastError());
        closesocket (sock);
        return FALSE;
    }
    ...
}

프로젝트를 애플리케이션 setsockoptIP_MULTICAST_TTL 과 Ws2_32.lib 연결하고 실행하면 성공합니다. 그러나 멀티캐스트 TTL 설정은 적용되지 않습니다. 네트워크 추적을 검사하면 TTL 값이 여전히 1(기본값)으로 유지됩니다.

Posted by gurupia
,