Address Structures
Note: This documentation describes features available in Windows operating systems. Information about feature availability may be updated as new versions of the operating system are released. For the latest information, refer to the official Microsoft documentation.
Introduction to Address Structures
Network programming relies heavily on the ability to represent and manage network addresses. In the Windows Sockets API (Winsock), various structures are defined to hold information about socket addresses. These structures are crucial for functions like bind, connect, sendto, and recvfrom.
The specific structure used often depends on the address family (e.g., IPv4 or IPv6).
Common Address Structures
The primary structure for general socket addressing is SOCKADDR, but in practice, you'll often use more specific structures that are cast to SOCKADDR or SOCKADDR_STORAGE.
SOCKADDR Structure
This is a generic structure that can hold any socket address. It is typically used as a generic pointer, with the actual type determined by the sa_family member.
typedef struct sockaddr {
u_short sa_family; // Address family (AF_INET, AF_INET6, AF_UNSPEC, etc.)
char sa_data[14]; // Protocol-specific address information
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
The sa_data field is a generic buffer. For specific address families, specialized structures are used and then cast to SOCKADDR.
SOCKADDR_IN Structure (IPv4)
This structure represents an IPv4 socket address. It includes the address family, port number, and IP address.
typedef struct sockaddr_in {
short sin_family; // Address family (AF_INET)
unsigned short sin_port; // Port number
struct in_addr sin_addr; // IPv4 address
char sin_zero[8]; // Not used
} SOCKADDR_IN;
sin_family: Must be set toAF_INETfor IPv4.sin_port: The port number, in network byte order.sin_addr: Anin_addrstructure containing the IPv4 address.
SOCKADDR_IN6 Structure (IPv6)
This structure represents an IPv6 socket address. It is more complex than SOCKADDR_IN due to the larger IPv6 address space and additional features.
typedef struct sockaddr_in6 {
short sin6_family; // Address family (AF_INET6)
USHORT sin6_port; // Port number
ULONG sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
ULONG sin6_scope_id; // Scope ID
} SOCKADDR_IN6;
sin6_family: Must be set toAF_INET6for IPv6.sin6_port: The port number, in network byte order.sin6_addr: Anin6_addrstructure containing the 16-byte IPv6 address.sin6_flowinfo: Flow information for the IPv6 packet.sin6_scope_id: Scope identifier, relevant for link-local addresses.
SOCKADDR_STORAGE Structure
This structure is designed to be large enough to hold any sockaddr structure, including both IPv4 and IPv6 addresses. It's useful when you need to store an address without knowing its family beforehand.
typedef struct sockaddr_storage {
short ss_family; // Address family
char __ss_padding[6]; // Padding to align the structure
// The actual address data follows, which will be either SOCKADDR_IN,
// SOCKADDR_IN6, or another protocol-specific address structure.
union {
char __ss_data[128];
sockaddr_in __ss_ign_sockaddr_in; // For IPv4
sockaddr_in6 __ss_ign_sockaddr_in6; // For IPv6
};
} SOCKADDR_STORAGE, *PSOCKADDR_STORAGE, *LPSOCKADDR_STORAGE;
When using SOCKADDR_STORAGE, you must check the ss_family member to determine which type of address structure is actually contained within it.
Address Families
The sa_family (or sin_family/ss_family) member of these structures specifies the address family.
AF_UNSPEC: The address family is unknown or unsupported.AF_INET: The Internet address family (IPv4).AF_INET6: The Internet address family (IPv6).AF_NETBIOS: NetBIOS (less common now).AF_IRDA: Infrared Data Association.
The most common families for modern networking are AF_INET and AF_INET6.
Working with Addresses
You will often use helper functions to convert between string representations of addresses (like "192.168.1.1" or "::1") and their binary forms within the address structures.
inet_pton(andinet_ptrfor IPv6): Converts a string to a network address structure.inet_ntop(andinet_ntrifor IPv6): Converts a network address structure to a string.getaddrinfoandfreeaddrinfo: A more modern and flexible way to resolve hostnames and service names into a linked list of socket address structures.
Example using inet_pton and SOCKADDR_IN:
#include <winsock2.h>
#include <ws2ipdef.h> // For IN_ADDR structure
// ... initialization of Winsock ...
SOCKADDR_IN ipv4_addr;
const char* ip_string = "192.168.1.100";
int port = 8080;
memset(&ipv4_addr, 0, sizeof(ipv4_addr));
ipv4_addr.sin_family = AF_INET;
ipv4_addr.sin_port = htons(port); // Convert port to network byte order
if (inet_pton(AF_INET, ip_string, &ipv4_addr.sin_addr) <= 0) {
// Error handling: Invalid IP address string
printf("inet_pton failed.\n");
} else {
// Successfully populated the address structure
printf("Address structure populated for %s:%d\n", ip_string, port);
}