2012-04-27 61 views
13

trong mã:Làm thế nào để sử dụng getnameinfo thay vì gethostbyname?

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

Tôi đã có cảnh báo khi biên dịch chéo (kiến trúc cánh tay generic) trên 4.5.x gcc:

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

getnameinfo là:

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 
); 

Và nó có nhiều thông số hơn ... Và tôi bị nhầm lẫn với nó, tôi chỉ cần nó hoạt động như gethostbyname đang làm việc. Tham số nào để vượt qua để giữ cho nó đơn giản ngu ngốc như với gethostbyname?

Cuối cùng đây là cố gắng của tôi:

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; 

Nó biên dịch tốt và không có lỗi segmentation trên khởi động nhưng tôi không thể kết nối máy chủ của tôi với nó :(

+1

Khi bạn đã đánh dấu câu hỏi bằng [tag: C++], tôi khuyên bạn nên sử dụng [boost.asio] (http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio.html) . – Griwes

+0

Cảm ơn bạn. nhưng tôi không muốn liên lạc. Nhưng tôi nghĩ không có lý do để không sử dụng tăng, vì vậy tôi nghĩ rằng tôi sẽ xem xét. – Cynede

+0

https://www.google.com/search?btnG=1&pws=0&q=winsock+getnameinfo+tutorial Số 3. – dutt

Trả lời

12

gethostbyname() thực hiện một tên → tra cứu IP. Nó phải được thay thế bằng getaddrinfo(), có thể thực hiện tương tự.

Điều này có nghĩa là cảnh báo hoàn toàn sai. getnameinfo() là sự thay thế của gethostbyaddr(), cả cho IP → tra cứu tên. Điều ngược lại.

tên → IP: gethostbyname(), getaddrinfo() tên
IP →: gethostbyaddr(), getnameinfo()

Các chức năng mới có thể làm nhiều hơn nữa: họ xử lý IPv6 có thể dịch chuỗi như 'http' đến 80 (cổng). Trong tương lai, họ cũng có thể xác định xem ví dụ: TCP nên được sử dụng cho dịch vụ được đề cập hoặc SCTP. Giao diện đã sẵn sàng.

11

Beej của giải thích nó khá tốt gethostbyname(). không hoạt động tốt với IPV6 và do đó bạn nên sử dụng getnameinfo() thay thế. Tất cả những gì bạn phải làm là điền thông tin được yêu cầu, tức là

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 
); 

Sửa: Sau khi một số nghiên cứu, tôi đã phát hiện ra rằng

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

nên là đủ.

Chỉnh sửa # 2 Tôi nhận thấy bạn đang cố gắng sử dụng giá trị trả lại là getnameinfo làm tên máy chủ. Nhưng điều đó không đúng, tên máy chủ được lưu trong con trỏ host được cung cấp. Giá trị trả về cho biết liệu thao tác có đủ hay không. Ngoài ra, hãy xem the man page.

+0

Nếu bạn đang in thông tin về máy chủ lưu trữ của mình, nghĩa là '* máy chủ' và của' * dịch vụ', bạn có nhận được nội dung chính xác trong chuỗi không? –

+0

nó đã làm việc tốt với gethostbyname, nhưng tôi không thể bắt lỗi ở đây. – Cynede

+0

nhưng đó là ví dụ getaddrinfo và tôi đang cố gắng sử dụng getnameinfo. – Cynede

Các vấn đề liên quan