CS/C, C++

C언어에서 IP 주소 가져오는 2가지 방법

하이하이루루 2023. 7. 9. 23:13

현재 C언어를 사용해서 일을 하고 있습니다.

 

관련 작업을 하면서 C언어를 이용해서 IP 주소를 가져오는 작업과 관련해서 포스팅 하려고 합니다.

 

일반적으로, C 언어로 직접 자신의 IP 주소를 가져오는 것은 어렵습니다. IP 주소는 네트워크 연결에 대한 정보이므로, 일반적으로 운영 체제와 네트워크 스택에서 제공하는 기능을 사용하여 IP 주소를 가져옵니다. C 언어 자체에는 이러한 기능이 내장되어 있지 않습니다.

그러나, C 언어를 사용하여 IP 주소를 얻으려면 운영 체제의 네트워크 기능을 활용해야 합니다. 여러 운영 체제에서는 이를 위해 네트워크 라이브러리를 제공하며, 이를 사용하여 IP 주소를 가져올 수 있습니다. 예를 들어, Windows 운영 체제에서는 Winsock API를 사용하여 IP 주소를 얻을 수 있습니다. Linux나 macOS에서는 네트워크 소켓 프로그래밍을 통해 IP 주소를 가져올 수 있습니다.

1. 윈도우 기반 C언어에서 IP 주소 가져오기

다음은 C 언어에서 Windows 운영 체제에서 IP 주소를 가져오는 간단한 예제입니다.

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("Failed to initialize Winsock\n");
        return 1;
    }

    char hostname[256];
    if (gethostname(hostname, sizeof(hostname)) == 0) {
        struct hostent *host = gethostbyname(hostname);
        if (host != NULL) {
            struct in_addr **addr_list = (struct in_addr **)host->h_addr_list;
            for (int i = 0; addr_list[i] != NULL; ++i) {
                printf("IP Address: %s\n", inet_ntoa(*addr_list[i]));
            }
        }
    }

    WSACleanup();
    return 0;
}

이 예제에서는 Windows에서 제공하는 Winsock API를 사용하여 IP 주소를 가져옵니다. gethostname() 함수를 사용하여 호스트 이름을 가져온 다음, gethostbyname() 함수를 사용하여 호스트 이름에 대한 IP 주소 목록을 얻습니다. 이후 inet_ntoa() 함수를 사용하여 IP 주소를 문자열로 변환하여 출력합니다.

하지만 주의할 점은 이 코드가 Windows 운영 체제에서만 동작한다는 것입니다. 다른 운영 체제에서는 해당 운영 체제에 맞는 네트워크 라이브러리나 API를 사용해야 합니다. 또한, 이 예제는 단순한 예제일 뿐이며 실제로 네트워크 프로그래밍을 할 때는 보안과 에러 처리를 고려해야 합니다.

 

2. 리눅스 기반 C언어에서 IP 주소 가져오기

다음은 C 언어에서 리눅스 기반 운영 체제에서 IP 주소를 가져오는 간단한 예제입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ifaddrs.h>

int main() {
    struct ifaddrs *ifaddr, *ifa;
    int family, s;
    char host[NI_MAXHOST];

    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        exit(1);
    }

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL)
            continue;

        family = ifa->ifa_addr->sa_family;

        if (family == AF_INET || family == AF_INET6) {
            s = getnameinfo(ifa->ifa_addr,
                            (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                                  sizeof(struct sockaddr_in6),
                            host, NI_MAXHOST,
                            NULL, 0, NI_NUMERICHOST);
            if (s != 0) {
                printf("getnameinfo() failed: %s\n", gai_strerror(s));
                exit(1);
            }

            if (strcmp(ifa->ifa_name, "lo") != 0) {  // 루프백 인터페이스 제외
                printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, host);
            }
        }
    }

    freeifaddrs(ifaddr);
    return 0;
}

위의 코드는 getifaddrs() 함수를 사용하여 시스템에 대한 네트워크 인터페이스 목록을 얻습니다. 그런 다음, 각 인터페이스에 대해 getnameinfo() 함수를 사용하여 IP 주소를 가져옵니다. 이를 통해 인터페이스의 이름과 IP 주소를 출력합니다. 코드에서는 루프백(lo) 인터페이스를 제외하고 출력하도록 필터링하였습니다.

위의 예제 코드를 컴파일하고 실행하면, 시스템의 각 네트워크 인터페이스에 대한 IP 주소를 얻을 수 있습니다.