C Programming

The sockaddr_in Structure

Socket programming in the C language uses a variety of functions, many of them are used to resolve, convert, and determine the address of the server we want to connect to. Undoubtedly, the IP address is the most important information we need when we open a socket. And dealing with these addresses requires that we know the structures in which they are stored, the type of data of each of their members, etc.

In this Linux Hint article, you will learn all about the type of socaddr_in structures used by system functions to store addresses for Internet connections.

We will see a theoretical description of its members and the type of data for each of them. We will learn how to create a sockaddr_in structure and then retrieve, convert, and store the addresses in this structure type to establish a successful socket connection.

We will also explain the similarities with the sockaddr structure and how to convert data from one to the other, as this is a necessary step to use the connect() function and connect to the server.

Syntax of the sockaddr_in structure in C language

struct sockaddr_in {

 

         short            sin_family;  
         unsigned short   sin_port;    
         struct in_addr   sin_addr;    
         char             sin_zero[8];  
         };

Description of the sockaddr_in structure in C language

Structures of type sockaddr_in are intended to store the address of the server in Internet connections and to be compatible in size and data order with a sockaddr structure used by the connect() function to connect to a server.

The data stored in these structures specifies the address family, port number, and IP address of the server. Next, we see the list of members of the sockaddr_in structure and a description of each member:

sin_family: this is a short that specifies the type of address family that the structure contains. These options of address family are as follows:

AF_INET: Specifies the iPv4 address family.

AF_INET6: Specifies the iPv6 address family.

sin_port: it is a ushort that specifies the port number that the socket will use. Like addresses, the port number is not encoded, which means that it must be specified in direct binary format, so a conversion to this data type must be done to assign a value to it.

in_add: This is a structure whose member is a uint32_t where each of its 4 bytes corresponds to a field of the IPv4 address of the Internet server with which the socket is to be opened. Like the port number, the address in this structure must be specified in pure binary format.

sin_zero: This is an 8-character array whose only purpose is to balance the size of the structure with a structure of type sockaddr.

How to Declare a sockaddr_in Structure in the C Language

To declare a sockaddr_in structure, write in one line of code “struct” followed by the type. In this case, sockaddr_in and then the “struct name” or “* structure name” to declare the pointer. The syntax for declaring a sockaddr_in structure is as follows:

struct  sockaddr_in *my_struct;

 

How to Set the Port Number in a sockaddr_in Structure in the C Language

The port number must be specified in direct binary form in the sin_port member of the structure. Therefore, it is necessary to convert the value to this data type.

The htons() function is most commonly used for this purpose. It converts the integer value contained in its input argument and returns its value in direct binary format to its output.

Next, let us see how to assign port 80 to the sin_port member of the previously declared structure:

int  port = 80;

 

my_struct.sin_port = htons(port);

How to Set the IP Address in a sockaddr_in Structure in the C Language

IP addresses are not encoded, which means that each of the numbers in their fields is represented by its binary equivalent. To work with them, in certain cases it is necessary to convert IP addresses to strings or strings to IP addresses in order to assign or query these values in the structures.

The C language provides several functions to convert strings to addresses and store the result in certain structures.

The function inet_pton() is one of the most commonly used for this purpose. It is defined in the header “inet.h” and has three input arguments. The first must specify the address family to convert, in this case AF _INET.

The second argument must be the pointer to a string specifying the IP address, with each field separated by a period.

The third argument of this function must be the pointer to a structure of type sockaddr_in where the converted address is stored.

The inet_ntop() function does the reverse task, converting the addresses stored in a sockaddr_in structure into strings.

Next, we will see how to assign an IP address to the my_struct structure of the sockaddr_in type from a string, in this case addr, using the inet_pton() function. Then, we use the inet_ntop() function to convert the address back to the string ip to display it in the command console with printf().

#include <stdio.h>

#include <string.h>

#include <netdb.h>

#include <arpa/inet.h>

 

void main ()

    {
    char ip [INET_ADDRSTRLEN] = "";
    char addr [200]="192.168.1.1";
    struct sockaddr_in  *my_struct;

      //Converts string to address.
    inet_pton (AF_INET, addr, &my_struct);
      //Converts address to string.
    inet_ntop(AF_INET, &my_struct,ip, INET_ADDRSTRLEN);

    printf ("\n\nIP address: %s\n\n", ip);
    }

The following image shows the IP address we obtained from the string addr. Then, we returned with the complementary function inet_ntop() to convert the address stored in my_struct into a string to display it in the command console.

How to Determine the IP Address of a Domain and Store it in a sockaddr_in Structure in the C Language

To connect to a host, you first need to know its address. Next, let us look at how to get the IP address of a host and store it in a sockaddr_in structure by using the gethostbyname() function.

This function takes as its only input argument a string, or a pointer to it, that specifies the hostname whose address is to be determined. As a result, gethostbyname() returns a structure of type hostent with all domain data, including the IP address.

Once the host information in the hostent structure is retrieved, the obtained address is copied to the sockaddr_in structure using the bcopy() function.

Next, we see the code where the socaddr_in and hostent type structures are defined. The IP address of “www.google.com” is determined in the last structure and copied to the sockaddr_in structure. Then, the determined address is converted into a string using the inet_ntoa() and printf() functions and displayed in the command console:

#include <stdio.h>

#include <string.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <netdb.h>

int main(){

  struct sockaddr_in my_struct;
  struct hostent *host_ent;

  host_ent = gethostbyname("www.google.com");

  bcopy((char *)host_ent->h_addr, (char *)&my_struct.sin_addr.s_addr,
         sizeof(host_ent->h_length));
  printf("IP address: %s\n",inet_ntoa(my_struct.sin_addr));
}

In this way, we have already stored the address of “www.google.com” in the structure of type sockaddr_in. The figure below shows the address of the host specified in the input argument of the gethostbyname() function.

Google.com has multiple IP addresses associated with the domain, so the result of this code may differ from the result of the image.

How to Cast a sockaddr Structure with the Data from a sockaddr_in Structure

The connect() function is the only function provided by the C language for establishing socket connections. This function uses structures of type sockaddr to specify the address to which it wants to connect.

The structure used by the connect() function has the same size in bytes as a structure of type sockaddr_in but differs in data type. This means that a structure cast must be performed to use the connection data stored in the sockaddr_in structure in this function.

This simple operation can be performed with the same call to the connect() function in the second input argument, as shown below:

connect(socket,(struct sockaddr *)&my_struct, sizeof(my_struct));

Conclusion

In this Linux Hint article, we explained everything you need to know about working with structures of type sockaddr_in. We looked in detail at the type and the data each of its members stores.

We also showed you how to declare this type of structure and how to use the necessary functions to get, convert and manipulate the different data stored by each of its members.

For more articles about the C language and Linux tips, use the search engine on our website.

About the author

Julio Cesar

Julio Cesar is a 42 years old programmer with 8 years of experience in embedded systems development, 6 years developing firmware for user interfaces in C and C++. Additionally he has 2 years of experience developing scripts for network devices and 3 years as developer of high frequency PCB (Printed Circuit Board).