2015-08-24 5 views
0

Я получаю странные ошибки из getaddrinfo() на Windows 10 при выполнении следующей программы C:getaddrinfo: Произошла неустранимая ошибка во время поиска в базе данных

https://gist.github.com/anonymous/4406cb031791afba29e5

Вот соответствующая часть из код, который вызывает getaddrinfo():

int error; 
    socket_t sock; 
    struct sockaddr_in addr; 
    struct addrinfo ai_hints, *ai_result, *ai_cur; 
    #ifdef _WIN32 
    int wsa_error; 
    WSADATA wsa_data; 
    #endif 

    if (argc < 3) { 
    fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]); 
    return 1; 
    } 

    #ifdef _WIN32 
    wsa_error = WSAStartup(MAKEWORD(2, 2), &wsa_data); 
    if (wsa_error != 0) { 
     fprintf(stderr, "WSAStartup: %s\n", 
      get_error_string(wsa_error, NULL, 0)); 
     return 2; 
    } 
    #endif 

    puts("Hello, World!"); 

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sock == -1) { 
    fprintf(stderr, "socket: %s\n", 
     get_error_string(get_socket_error(), NULL, 0)); 
    return 3; 
    } 

    memset(&ai_hints, sizeof(ai_hints), 0); 
    ai_hints.ai_family = AF_UNSPEC; 
    ai_hints.ai_protocol = IPPROTO_TCP; 
    ai_hints.ai_socktype = SOCK_STREAM; 

    error = getaddrinfo(argv[1], argv[2], &ai_hints, &ai_result); 
    if (error != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", error); 
    close(sock); 
    return 4; 
    } 

Каждый раз, когда программа не получает его запуск независимо от того, что имя хоста и порта я прохожу через командную строку выводит следующее:

Hello, World! 
getaddrinfo: A non-recoverable error occurred during a database lookup. 

Я также написал соответствующую серверную программу, и она отлично работала (проверена с помощью telnet!).

Вы видите, что что-то не в порядке с моим кодом?

EDIT:

Это, кажется, работает хорошо на Linux, getaddrinfo() не дает каких-либо ошибок там, и клиент может подключиться к серверу.

+0

Вы пробовали переходить через него в отладчик? – Ben

+0

Когда 'getaddrinfo()' терпит неудачу, 'gai_strerror (get_socket_error())' должен быть 'gai_strerror (error)' вместо. –

+1

В отдельном примечании нет смысла устанавливать 'ai_hints.ai_family'' AF_UNSPEC', поскольку только IPv4-адреса могут использоваться с гнездом 'AF_INET'. 'AF_UNSPEC' позволяет' getaddrinfo() 'сообщать как адреса IPv4, так и IPv6. Если 'getaddrinfo()' случилось, чтобы вернуть адреса IPv6 для имени узла, 'connect()' будет терпеть неудачу на них. Итак, 'ai_hints.ai_family' должен быть' AF_INET' в этой ситуации. Кроме того, код не вызывает 'freeaddrinfo()' по окончании использования 'ai_result'. –

ответ

2

Ура! Я нашел это!

Оказывается, я перепутал порядок аргументов в memset() при инициализации ai_hints, т.е. вместо:

memset(&ai_hints, sizeof(ai_hints), 0); 

это должно было быть:

memset(&ai_hints, 0, sizeof(ai_hints)); 

Жаль, что я не читал getaddrinfo() документация полностью описана именно в этой ошибке:

pHints [in, optional]

Указатель на структуру addrinfo, которая содержит подсказки о типе сокета, который поддерживает вызывающий.

Ai_addrlen, ai_canonname, ai_addr и ai_next элементы структуры addrinfo, на которые указывает параметр pHints, должны быть равны нулю или NULL. В противном случае функция GetAddrInfoEx завершится с WSANO_RECOVERY.

+1

Для e xacting this reason, вы можете захотеть привыкнуть использовать '= {0}' для инициализации структуры вместо использования 'memset()', например: 'struct addrinfo ai_hints = {0};' –

Смежные вопросы