2011-07-13 29 views
7

Tôi đang sử dụng đoạn mã này tôi tìm thấy trong http://www.kutukupret.com/2009/09/28/gethostbyname-vs-getaddrinfo/ để thực hiện tra cứu dnsCó vấn đề gì với gethostbyname?

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[ ]) { 
    struct hostent *h; 

    /* error check the command line */ 
    if(argc != 2) { 
     fprintf(stderr, "Usage: %s hostname\n", argv[0]); 
     exit(1); 
    } 

    /* get the host info */ 
    if((h=gethostbyname(argv[1])) == NULL) { 
     herror("gethostbyname(): "); 
     exit(1); 
    } 
    else  
     printf("Hostname: %s\n", h->h_name); 

    printf("IP Address: %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));  
    return 0; 
} 

Tôi đang phải đối mặt với một thực tế lạ

./test www.google.com 
Hostname: www.l.google.com 
IP Address: 209.85.148.103 

hoạt động tốt, nhưng nếu tôi cố gắng giải quyết một địa chỉ IP không đầy đủ tôi có được điều này

./test 10.1.1 
Hostname: 10.1.1 
IP Address: 10.1.0.1 

tôi mong chờ một lỗi như sau

./test www.google 
gethostbyname(): : Unknown host 

nhưng chương trình có vẻ hoạt động.

Bất kỳ ý tưởng nào tại sao?

+0

Tôi vừa thử mã từ http://en.wikipedia.org/wiki/Getaddrinfo cho getaddrinfo, nhưng 10.1.1 sill giải quyết trong 10.1.0.1 ... Có phải là lỗi không? Tui bỏ lỡ điều gì vậy? –

Trả lời

17

Nó không phải là một lỗi mà là một tính năng của inet_aton() chức năng:

MÔ TẢ

Các inet_aton() chức năng chuyển đổi chuỗi chỉ định, trong Internet chuẩn ký hiệu dấu chấm, đến một địa chỉ mạng và lưu trữ địa chỉ trong cấu trúc được cung cấp.

giá trị quy định sử dụng ký hiệu dấu chấm lấy một trong các hình thức sau:

abcd Khi bốn phần được quy định, mỗi được hiểu như là một byte dữ liệu và phân công, từ trái sang phải, với bốn byte địa chỉ internet.

a.b.c Khi một địa chỉ ba phần được chỉ định, phần cuối được hiểu là số 16 bit và được đặt ở hai byte bên phải của địa chỉ mạng. Điều này làm cho định dạng địa chỉ ba phần thuận tiện cho việc xác định địa chỉ mạng lớp B là 128.net.host.

Bạn có thể đọc thêm về ví dụ này there.

+0

Có điều gì có nghĩa là 'gethostbyname' được gọi là' inet_aton'? – cHao

+1

@ cHao: khi gethostbyname() được đưa ra một ip chấm như một tham số (như trong kịch bản của OP) thì nó sử dụng inet_aton(): "Nếu tên là địa chỉ IPv4 hoặc IPv6, không tra cứu được thực hiện và gethostbyname() chỉ cần sao chép tên vào h_name fi và cấu trúc in_addr tương đương của nó vào trường h_addr_list [0] của cấu trúc máy chủ được trả về " –

7

POSIX.2004 nói:

Đối số tên của GetHostByName() sẽ là một tên nút; hành vi của gethostbyname() khi truyền một chuỗi địa chỉ số không được chỉ định. Đối với IPv4, một chuỗi địa chỉ số phải có ký hiệu chấm thập phân được mô tả trong inet_addr().

Vì vậy, khi nhìn từ điểm POSIX, bạn không thể mong đợi bất cứ điều gì khi chuyển địa chỉ IP.

Trên hệ thống của tôi, man page nói điều này:

Nếu tên là một địa chỉ IPv4 hoặc IPv6, không tra cứu được thực hiện và GetHostByName() chỉ đơn giản là bản sao tên vào trường h_name và nó struct in_addr tương đương vào trường h_addr_list [0] của cấu trúc máy chủ được trả về.

Nó không nói bất cứ điều gì về những gì sẽ xảy ra nếu bạn vượt qua nó một địa chỉ IP không đầy đủ, vì vậy bất cứ điều gì có thể xảy ra, bao gồm cả hành vi mà bạn quan sát.

Để biết thêm thông tin về cách gethostbyname được triển khai trên hệ thống của bạn, bạn có thể kiểm tra tài liệu về chức năng và/hoặc mã nguồn (nếu có).

+3

Ngoại trừ từ 'inet_addr'," abc Khi một địa chỉ ba phần được chỉ định, phần cuối cùng sẽ được hiểu là số lượng 16 bit và được đặt ở hai byte bên phải của địa chỉ mạng. Điều này làm cho địa chỉ ba phần định dạng thuận tiện cho việc xác định địa chỉ mạng lớp B là "128.net.host". Vì vậy, Linux cho biết cách xử lý địa chỉ IP rải rác và 'inet_addr' xác định rằng' 10.1.1' là một địa chỉ rải rác có nghĩa giống như '10.1 .0.1', và do đó hành vi được quan sát của người được hỏi được xác định và mong đợi trên Linux –

+0

@Steve: thú vị Rất vui vì tôi đã học được một điều gì đó mới mẻ –

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