gethostbyname в C

Я не умею писать приложения на C, но мне нужна крошечная программа, которая делает:

lh = gethostbyname("localhost");
output = lh->h_name;

выходная переменная должна быть напечатана.

Приведенный выше код используется в драйвере базы данных PHP MongoDB для получения имени хоста компьютера (имя хоста является частью ввода для создания уникального идентификатора). Я скептически отношусь к тому, что это вернет имя хоста, поэтому мне нужны доказательства.

Любые примеры кода будут наиболее полезными.

Счастливый день.


person Matic    schedule 19.05.2010    source источник


Ответы (3)


#include <stdio.h>
#include <netdb.h>


int main(int argc, char *argv[])
{
    struct hostent *lh = gethostbyname("localhost");

    if (lh)
        puts(lh->h_name);
    else
        herror("gethostbyname");

    return 0;
}

Это не очень надежный способ определения имени хоста, хотя иногда он может работать. (то, что он возвращает, зависит от того, как настроен /etc/hosts). Если у вас есть строка типа:

127.0.0.1    foobar    localhost

...тогда он вернет "foobar". Если у вас все наоборот, что также распространено, то он просто вернет «localhost». Более надежный способ — использовать функцию gethostname():

#include <stdio.h>
#include <unistd.h>
#include <limits.h>

int main(int argc, char *argv[])
{
    char hostname[HOST_NAME_MAX + 1];

    hostname[HOST_NAME_MAX] = 0;
    if (gethostname(hostname, HOST_NAME_MAX) == 0)
        puts(hostname);
    else
        perror("gethostname");

    return 0;
}
person caf    schedule 19.05.2010
comment
Вы должны передать sizeof(hostname) -1 как длину gethostname(). В противном случае вы можете не получить нулевое завершение, если произойдет усечение. Согласно моей справочной странице: POSIX.1 говорит, что если такое усечение происходит, то не указано, включает ли возвращаемый буфер завершающий нулевой байт. - person scai; 24.01.2017
comment
@scai: Спасибо, исправлено. - person caf; 24.01.2017

В C/UNIX эквивалентом будет что-то вроде:

#include <stdio.h>
#include <netdb.h>

int main (int argc, char *argv[]) {
    struct hostent *hstnm;
    if (argc != 2) {
        fprintf(stderr, "usage: %s hostname\n", argv[0]);
        return 1;
    }
    hstnm = gethostbyname (argv[1]);
    if (!hstnm)
        return 1;
    printf ("Name: %s\n", hstnm->h_name);
    return 0;
}

и доказательство того, что это работает:

$ hstnm localhost
Name: demon-a21pht

Но попробуйте сами. Если у вас правильная среда, все должно быть в порядке.

person paxdiablo    schedule 19.05.2010

что случилось?

h_name

Официальное имя хоста (ПК). При использовании DNS или аналогичной системы разрешения именно полное доменное имя (FQDN) заставляет сервер возвращать ответ. При использовании локального файла hosts это первая запись после адреса IPv4.

person Andrey    schedule 19.05.2010
comment
И, конечно же, DNS не будет использоваться для локального хоста, поэтому важен файл локальных хостов. Если запись в файле локальных хостов имеет и локальный хост, и реальное имя хоста, связанное с одним и тем же адресом (127.0.0.1), и реальное имя хоста является первой записью, тогда h_name вернет настоящее имя хоста. - person David Gelhar; 19.05.2010
comment
@David Gelhar: localhost - это не имя компьютера. localhost разрешается в 127.0.0.1, но обратного преобразования нет. en.wikipedia.org/wiki/Localhost - person Andrey; 19.05.2010
comment
правильно, но дело в том, что если /etc/hosts выглядит как 127.0.0.1 realname.com localhost, то gethostbyname("localhost") вернет realname.com в h_name, но если порядок будет обратным, он вернет localhost (см. ответ caf). - person David Gelhar; 19.05.2010