Поиск локального IP через создание сокета / getsockname - PullRequest
1 голос
/ 12 июня 2010

Мне нужно получить IP-адрес системы в C ++.Я следовал логике и советам другого комментария здесь и создал сокет, а затем использовал getsockname для определения IP-адреса, к которому привязан сокет.

Однако это не работает (код ниже),Я получаю неверный IP-адрес (58.etc), когда мне нужно получить 128.etc

Любые идеи?

   string Routes::systemIP(){

    // basic setup
    int sockfd;
    char str[INET_ADDRSTRLEN];
    sockaddr* sa;
    socklen_t* sl;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((rv = getaddrinfo("4.2.2.1", "80", &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return "1";
    }

    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("talker: socket");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "talker: failed to bind socket\n");
        return "2";
    }

    // get information on the local IP from the socket we created
    getsockname(sockfd, sa, sl);

    // convert the sockaddr to a sockaddr_in via casting
    struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;

    // get the IP from the sockaddr_in and print it
    inet_ntop(AF_INET, &(sa_ipv4->sin_addr.s_addr), str, INET_ADDRSTRLEN);
    printf("%s\n", str);

    // return the IP
    return str;
}

Ответы [ 2 ]

1 голос
/ 12 июня 2010

Ваш код уже содержит подсказку: failed to bind socket. Но вы вырезали ту часть кода, которая пытается подключиться (вы копировали из Stevens UnP?). Сокет ни к чему не подключен, поэтому сетевой стек еще не назначил ему локальный адрес.

После подключения сокета ядро ​​должно выбрать для него локальный адрес в соответствии с таблицей маршрутизации. В этот момент getsockname(2) будет работать как положено.

0 голосов
/ 12 июня 2010

Вам не нужно выделять сокет для получения доступных IP-адресов аппарата. Вместо этого вы можете использовать функции сокетов API gethostname () и gethostbyname (). Или в Windows вы можете вместо этого использовать Win32 API GetAdaptersInfo () или GetAdaptersAddresses ().

...