Home > Software engineering >  Why address information are not properly stored with gethostbyname and inet_pton functions?
Why address information are not properly stored with gethostbyname and inet_pton functions?

Time:12-22

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

If I execute this code, I always get:

$ ./client 
��� 0
-1

So:

  1. Why I get these random chars? Why I don't see the IP string of h_addr?
  2. Why the return of inet_pton is 0? It should be 1, 0 is for unsuccessfull, so why it fails?
  3. Obviously, the connect fails.

Also, if instead of using inet_pton, I use this line:

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

it works. BUT WHY it works this way and in the other way it doesn't??

CodePudding user response:

My English is not very good, so please understand.

See 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] is struct in_addr and h_addr_list[0] is h_addr, See below.

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]

struct in_addr

struct in_addr {
  uint32_t s_addr;
}

So, if you want to see the IP string of h_addr, see the code below.

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

And you can use it by assigning the value of s_addr as addr.sin_addr.s_addr = *(unit32_t *)server->haddr;

Or you can make it simpler using addr.sin_addr.s_addr = inet_addr("192.168.1.139");

  • Related