为什么使用 gethostbyname 和 inet_pton 函数没有正确存储地址信息?

Why address information are not properly stored with gethostbyname and inet_pton functions?

int main (int argc, char **argv){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    
    struct sockaddr_in addr;
    bzero(&addr,sizeof addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    struct hostent *server = gethostbyname("192.168.1.139");
    printf("%s %d\n",server->h_addr,inet_pton(AF_INET,server->h_addr,&addr.sin_addr.s_addr));
    int res = connect(sockfd,(struct sockaddr *)&addr,sizeof addr);
    printf("%d\n",res); 

    while (1){
        char buf[100] = "";
        fgets(buf,100,stdin);
        send(sockfd,buf,sizeof buf,0);
    }
}

如果我执行这段代码,我总是得到:

$ ./client 
��� 0
-1

所以:

  1. 为什么我得到这些随机字符?为什么我看不到 h_addr 的 IP 字符串?
  2. 为什么inet_pton的return是0?应该是1,0是不成功,为什么会失败呢?
  3. 很明显,连接失败了。

此外,如果不使用 inet_pton,我会使用这一行:

bcopy((char *)server->h_addr,(char *)&addr.sin_addr.s_addr,h_length);

有效。但为什么它以这种方式工作,而以另一种方式却没有?

我的英文不是很好,请理解。

gethostbyname() man page

The gethostbyname() function returns a structure of type hostent for the given host name. Here name is either a hostname or an IPv4 address in standard dot notation (as for inet_addr(3)). If name is an IPv4 address, no lookup is performed and gethostbyname() simply copies name into the h_name field and its struct in_addr equivalent into the h_addr_list[0] field of the returned hostent structure.

h_addr_list[0] 是结构 in_addr 而 h_addr_list[0] 是 h_addr,见下文。

struct hostent

struct  hostent {
 char *  h_name;     
 char ** h_aliases; 
 int     h_addrtype;  
 int     h_length;    
 char ** h_addr_list;
};

#define h_addr  h_addr_list[0]

结构in_addr

struct in_addr {
  uint32_t s_addr;
}

所以,如果你想看到h_addr的IP字符串,请看下面的代码。

printf("%s\n", inet_ntoa(*(struct in_addr*)server->h_addr));

并且您可以通过将 s_addr 的值分配为 addr.sin_addr.s_addr = *(unit32_t *)server->haddr;

来使用它

或者您可以使用 addr.sin_addr.s_addr = inet_addr("192.168.1.139");

使其更简单