The gethostbyname() function is used in C programming to retrieve information about a host computer given its hostname. Though this function is now considered obsolete and replaced by the getaddrinfo() function, gethostbyname() is still widely used due to its simplicity.
In this comprehensive guide, we will cover everything you need to know about using the gethostbyname() function in C, including:
- What is the gethostbyname() function and why is it used
- The syntax and parameters of gethostbyname()
- How gethostbyname() works
- The hostent structure returned by gethostbyname()
- How to check for and handle errors
- Examples of using gethostbyname()
- Why gethostbyname() is now considered obsolete
- Alternatives to gethostbyname()
What is Gethostbyname() and Why Use It?
The gethostbyname() function is used to retrieve information about a host computer based on its hostname. Specifically, gethostbyname() takes a hostname string as a parameter and returns a pointer to a hostent structure containing information such as:
- Official hostname
- Alias hostnames
- Address family (IPv4/IPv6)
- IP address(es)
- Address length
This information is useful when writing network applications, as you can lookup a computer‘s IP address and other details by hostname. The hostname is often more convenient to work with compared to directly using IP addresses.
Here are some examples of why you may use gethostbyname():
- Looking up the IP address(es) for a host to open a socket connection
- Resolving a hostname entered by the user to an IP address
- Printing out official host details given a hostname string
- Learning about a host‘s multiple alias names and addresses
So in summary, it provides a simple way to get essential host details needed for tasks like making connections by hostname.
Syntax and Parameters
Here is the syntax and parameters for the gethostbyname() function:
struct hostent *gethostbyname(const char *name);
Parameters:
name– The hostname to lookup. This should be a null-terminated string.
Return Value
- Pointer to a hostent structure on success
- NULL pointer on failure (Sets
h_errnoerror code)
To use gethostbyname() you need to include the netdb.h header which defines the hostent structure.
How Gethostbyname() Works
When you call gethostbyname() and pass a hostname string, here is a high-level overview of what happens:
- The function asks the DNS resolver subsystem to lookup the IP address for the given hostname.
- The DNS resolver queries the DNS servers to resolve the hostname to IP address(es).
- On success, gethostbyname() returns a pointer to a hostent structure containing the host details.
- On failure, gethostbyname() returns NULL and sets the
h_errnoerror code.
Internally, gethostbyname() utilizes DNS and your systems resolver configuration to retrieve the host data. The hostent structure is populated with information returned by the DNS lookup.
If multiple IP addresses exist for the hostname, the hostent structure will contain a list of addresses.
The Hostent Structure
The most essential piece to understand is the hostent structure that is returned by gethostbyname() on success.
Here is the definition of struct hostent:
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
#define h_addr h_addr_list[0] /* for backward compatibility */
Let‘s take a quick look at what each field contains:
h_name: The official/primary hostnameh_aliases: Null-terminated array of alternate hostname aliasesh_addrtype: Host address type (AF_INET for IPv4, AF_INET6 for IPv6)h_length: Length in bytes of each addressh_addr_list: Array of pointers to IP address strings (null terminated)h_addr: Pointer to first IP address (for back-compat access)
So in summary, this structure stores the primary hostname, aliases, address type/length, and contains pointers to access the IP addresses.
Accessing the hostent data is simple. For example if hostptr points to the returned structure:
hostptr->h_name– Official hostnamehostptr->h_addr_list[0]– First IP address
Now that we understand the host structure, let‘s look at some examples of using gethostbyname().
Example 1: Basic Gethostbyname Usage
This simple example demonstrates looking up the IP address for "www.google.com":
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
int main(void) {
struct hostent *host_info;
host_info = gethostbyname("www.google.com");
if(host_info == NULL) {
herror("gethostbyname");
exit(1);
}
printf("Official name: %s \n", host_info->h_name);
printf("IP Address 1: %s\n",inet_ntoa(*(struct in_addr *)host_info->h_addr));
return 0;
}
The steps are:
- Include netdb.h and declare host_info hostent pointer
- Call
gethostbyname()to lookup IP - Check if NULL and print error
- If valid, print out hostname and IP address fields
Running this should print out details for www.google.com like:
Official name: www.google.com
IP Address 1: 172.217.7.206
Easy enough! The true power though comes from accessing the other data or handling multiple addresses.
Example 2: Print Multiple IP Addresses
If a host has multiple IP addresses associated, you can print them out like this:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(void) {
int i;
struct hostent *host_info;
host_info = gethostbyname("www.example.com");
if(host_info == NULL) {
herror("gethostbyname");
exit(1);
}
printf("Host name: %s \n", host_info->h_name);
for(i = 0; host_info->h_addr_list[i] != NULL; i++) {
printf(" IP addr %d: %s\n", i+1,
inet_ntoa(*(struct in_addr *)host_info->h_addr_list[i]) );
}
return 0;
}
This loops through h_addr_list printing out each IP address for the hostname. So you may get output like:
Host name: www.example.com
IP addr 1: 93.184.216.34
IP addr 2: 2606:2800:220:1:248:1893:25c8:1946
The same concept could be used to print out alias hostnames or other fields.
Checking for Errors
Since gethostbyname() returns NULL on failure, checking if it succeeded is done like this:
hostptr = gethostbyname(hostname);
if(hostptr == NULL) {
// Handle error
} else {
// Proceed to use hostent data
}
The specific error code is set in the global h_errno variable. So you can additionally print or examine this like:
if(hostptr == NULL) {
fprintf(stderr, "Error %d looking up hostname: %s\n", h_errno, hostname);
if(h_errno == TRY_AGAIN) {
// Retry lookup
} else {
exit(1);
}
}
Some common h_errno codes you may see:
NO_RECOVERY– Non-recoverable DNS errorTRY_AGAIN– DNS query timeout, retry may workNO_ADDRESS– No IP address exists for hostname
See the netdb.h header for other codes.
Handling and logging these errors is vital to writing robust code using gethostbyname().
Why Gethostbyname() is Now Obsolete
While gethostbyname() is still in widespread use, it is technically obsolete (deprecated). There are a few core reasons a modern replacement is needed:
1. IPv6 Support – gethostbyname() pre-dates IPv6. A new function was needed with IPv6 integrated. It returns IPv4-only structures.
2. Thread-Safety – The hostent structure returned by this function is static/non-reentrant. This causes issues with thread safety.
3. Limited Error Handling – Error reporting functionality via h_errno is relatively limited.
The modern replacement function getaddrinfo() properly handles all the above issues.
Despite the technical obsolescence, many systems and codebases still rely on gethostbyname() when IPv4 support is sufficient. It may take quite some time for displacement given how widely used it is.
Alternatives to Gethostbyname()
Now we‘ll briefly cover how to modernize code to use the replacement for gethostbyname() – the getaddrinfo() function.
Getaddrinfo() Usage Example:
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(void) {
struct addrinfo hints;
struct addrinfo *result, *rp;
// Set criteria for hostname lookup
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; /* IPv4 only */
// Lookup hostname
int s = getaddrinfo("www.wikipedia.org", NULL, &hints, &result);
// Handle errors
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
return 1;
}
// Print out IP addresses
for(rp = result; rp != NULL; rp = rp->ai_next) {
void *addr;
char ipstr[INET6_ADDRSTRLEN];
// Convert IPv4/v6 binary address to string for printing
addr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
inet_ntop(rp->ai_family, addr, ipstr, sizeof(ipstr));
printf(" %s\n", ipstr);
}
// Clean up
freeaddrinfo(result);
return 0;
}
The improvements with getaddrinfo() are:
- Dual IPv4/IPv6 support
- Additional error reporting via gai_strerror()
- Threaded DNS query capability
- ai_next linked list for multiple address returns
For simple IPv4 address lookups though, gethostbyname() is still simpler compared to the more advanced getaddrinfo() interface.
So in summary – getaddrinfo() fixes technical limitations, but gethostbyname() remains the easier method in basic use cases.
Conclusion
That wraps up our deep dive on gethostbyname(). Here are some key points about this essential C networking function:
- It resolves hostnames to IP address and returns a hostent structure
- hostent contains officially assigned hostname, aliases, address type/length, and IP addresses
- Simple interface takes just a hostname string and returns host details
- Technically obsolete due to IPv6, threading, error handling limitations
- Very common in existing IPV4 applications due to simplicity
- For new code, consider the improved getaddrinfo()
I hope you found this comprehensive guide useful! You should now understand the core mechanics of gethostbyname() and how to properly utilize it within your C programs.
Let me know if you have any other questions on this or other network programming topics!


