2010-12-09 3 views
2

Я использую системный вызов getaddrinfo, и он возвращает -2. Я пытаюсь понять, что это за ошибка, и получить то, что «имя или услуга неизвестны». имя - это мое имя хоста, и я уверен, что это известно. но служба - это номер, который изменяется от запуска до запуска. как я могу узнать, что я привожу правильный параметр?Системный вызов Linux: getaddrinfo return -2

мой код:

int GetSockPeerIPs(int sock, AddressList &addresses, int &error, 
        int family, bool zeroport) 
{ 
    struct sockaddr_storage ss; 
    socklen_t salen = sizeof(ss); 
    struct sockaddr *sa; 
    struct addrinfo hints, *paddr, *paddrp; 

    sa = (struct sockaddr *)&ss; 

    if (getpeername(sock, sa, &salen) != 0) { 
     error = errno; 
     return -1; 
    } 

    char hbuf[NI_MAXHOST]; 
    char pbuf[NI_MAXSERV]; 
    if (0 != (error = getnameinfo(sa, salen, 
         hbuf, sizeof(hbuf), 
         pbuf, sizeof(pbuf), 
         0))) { 
     return -1; 
    } 

    memset(&hints, 0, sizeof(hints)); 
    if (ATNetworkTool::AF_XINETX == family) { 
     hints.ai_family = PF_UNSPEC; 
    } else { 
     hints.ai_family = family; 
    } 
    hints.ai_socktype = SOCK_STREAM; 
    if (0 != (error = getaddrinfo(hbuf, pbuf, &hints, &paddrp))) { 
     return -1; 
    } 
    addresses.clear(); 
    for (paddr = paddrp; paddr; paddr = paddr->ai_next) { 
     if (ATNetworkTool::AF_XINETX == family) { 
      if (!ATAddress::saIsInet(paddr->ai_addr)) { 
       continue; 
      } 
     } 
     if (zeroport) { 
      addresses.insert(ATAddress(paddr->ai_addr, 0)); 
     } else { 
      addresses.insert(paddr->ai_addr); 
     } 
    } 
    freeaddrinfo(paddrp); 
    return 0; 
} 

спасибо! gln

+0

Показать ваш код, пожалуйста. – 2010-12-09 07:45:53

+0

Обратите внимание, что если getaddrinfo() и друзья терпят неудачу, вы можете вызвать [gai_strerror()] (http://pubs.opengroup.org/onlinepubs/009695399/functions/gai_strerror.html) код возврата, чтобы получить текстовое сообщение об ошибке , например `printf (" getaddrinfo() не удалось:% s \ n ", gai_strerror (ошибка));` в вашем случае – nos 2011-11-01 13:45:45

ответ

2

У вас есть код ошибки. Думали ли вы о том, что это значит? По этому случаю я сделал это для вас. Но вот что я сделал, чтобы в следующий раз вы могли посмотреть на себя.

Посмотрите на страницу руководства для getaddrinfo(). Я обнаружил, что он может вернуть несколько кодов ошибок, например. EAI_AGAIN. Числовые значения будут указаны в файле заголовка где-нибудь, поэтому я сделал

cd /usr/include 
find . -name "*.h" -exec grep -l EAI_AGAIN {} \; 

Это идентифицировало netdb.h. Таким образом, я открыл, что в VI, и это то, что он сказал:

# define EAI_BADFLAGS  -1 /* Invalid value for `ai_flags' field. */ 
# define EAI_NONAME  -2 /* NAME or SERVICE is unknown. */ 
# define EAI_AGAIN  -3 /* Temporary failure in name resolution. */ 
# define EAI_FAIL   -4 /* Non-recoverable failure in name res. */ 
# define EAI_FAMILY  -6 /* `ai_family' not supported. */ 
# define EAI_SOCKTYPE  -7 /* `ai_socktype' not supported. */ 
# define EAI_SERVICE  -8 /* SERVICE not supported for `ai_socktype'. */ 
# define EAI_MEMORY  -10 /* Memory allocation failure. */ 
# define EAI_SYSTEM  -11 /* System error returned in `errno'. */ 
# define EAI_OVERFLOW  -12 /* Argument buffer overflow. */ 

Так в основном, название или услуги, которые вы передаете в неизвестно getaddrinfo. Я бы проверял, являются ли первые два параметра разумными, если бы я был вами.

0

getaddrinfo является придирчивым относительно формата данных, при анализе файлов конфигурации убедитесь, что у вас нет лишних пробелов, обычно занимающих пробелы в параметре имени хоста, или вы получите эту ошибку, в этом случае ошибка правильная, просто нет очень информативно.