2012-04-27 1376 views
13

代碼:如何使用getnameinfo而不是gethostbyname?

if ((host = (struct hostent*) gethostbyname(address)) == 0) // address is a string 

我已經得到警告,當交叉編譯(通用ARM架構)在4.5.x GCC:

(.text+0x1558): warning: gethostbyname is obsolescent, use getnameinfo() instead. 

getnameinfo是:

int WSAAPI getnameinfo(
    __in const struct sockaddr FAR *sa, 
    __in socklen_t salen, 
    __out char FAR *host, 
    __in DWORD hostlen, 
    __out char FAR *serv, 
    __in DWORD servlen, 
    __in int flags 
); 

它得到更多的參數......而我很困惑,我只需要它工作,因爲gethostbyname工作。通過什麼參數來保持它簡單愚蠢,因爲它與gethostbyname?

最後,這裏是我的嘗試:

struct sockaddr_in servAddr; 
struct hostent *host;  /* Structure containing host information */ 

/* open socket */ 
if ((handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 
    return LILI_ERROR; 

memset(&servAddr, 0, sizeof(servAddr)); 
servAddr.sin_family  = AF_INET; 
servAddr.sin_addr.s_addr = inet_addr(address.ptr()); 
servAddr.sin_port  = htons(port); 

char servInfo[NI_MAXSERV]; 
if ((host = (hostent*) getnameinfo(
       (struct sockaddr *) &servAddr 
       ,sizeof (struct sockaddr) 
       ,address.ptr(), address.size() 
       ,servInfo, NI_MAXSERV 
       ,NI_NUMERICHOST | NI_NUMERICSERV) ) == 0) 
    return LILI_ERROR; 

if (::connect(handle, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) 
    return LILI_ERROR; 

它編譯良好,在啓動時沒有分割的錯,但我不能用它在我的服務器連接:(

+1

當你用[tag:C++]標記問題時,我建議使用[boost.asio](http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio.html) 。 – Griwes 2012-04-27 07:04:15

+0

謝謝。但我不想觸摸提升。但我認爲沒有理由不使用提升,所以我想我會看看。 – Cynede 2012-04-27 07:07:22

+0

https://www.google.com/search?btnG=1&pws=0&q=winsock+getnameinfo+tutorial 編號3. – dutt 2012-04-27 07:22:16

回答

12

gethostbyname()做一個名字→IP查找。它應該替換爲getaddrinfo(),它可以這樣做。

這意味着警告是完全錯誤的。 getnameinfo()是用於IP→名稱查找的gethostbyaddr()的替換。相反。

名→IP:gethostbyname()getaddrinfo()
IP→名稱:gethostbyaddr()getnameinfo()

較新的功能,可以做更多的:它們處理IPv6 可以如 'http',以80(端口)轉換字符串。在將來,他們還可以確定是否例如TCP應該用於有問題的服務或SCTP。界面已準備就緒。

11

Beej的解釋是相當不錯的gethostbyname()。不與IPV6效果很好,因此你應該使用getnameinfo()來代替。所有你所要做的就是填寫所需信息,即

getnameinfo(
    &sa,    // Pointer to your struct sockaddr 
    sizeof sa,  // Size of this struct 
    host,   // Pointer to hostname string 
    sizeof host,  // Size of this string 
    service,   // Pointer to service name string 
    sizeof service, // Size of this string 
    0    // No flags given 
); 

編輯:經過一番研究,我發現,

getnameinfo(&sa, sizeof(sa), hostname, size_hostname, NULL, NULL, 0); 

應該足夠了。

編輯#2我注意到您正在嘗試使用getnameinfo作爲主機名的返回值。但是,這是不正確的,主機名保存在提供的host指針。返回值表示操作是否足夠。也看看the man page

+0

如果您打印主機的信息,例如'* host'和'* service',您是否在字符串中獲得正確的內容? – 2012-04-27 10:47:44

+0

它與gethostbyname一起工作得很好,但我無法趕上這裏的錯誤。 – Cynede 2012-04-27 11:06:03

+0

但它是getaddrinfo的例子,我試圖使用getnameinfo。 – Cynede 2012-04-27 11:58:54