struct sockaddr { // generic socket
unsigned short sa_family; // protocol family for socket
char sa_data[14];
// address data (and defines full size to be 16 bytes)
};sockaddr_in is used to model IPv4 address/port pairs.
sin_family field should always be initialized to be AF_INET, which is a constant used to be clear that IPv4 addresses are being used. If it feels redundant that a record dedicated to IPv4 needs to store a constant saying everything is IPv4, then stay tuned.sin_port field stores a port number in network byte (i.e. big endian) order.sockaddr_in field stores an IPv4 address as a packed, big endian int, as you saw with gethostbynameand the struct hostent.sin_zero field is generally ignored (though it's often set to store all zeroes). It exists primarily to pad the record up to 16 bytes.struct sockaddr_in { // IPv4 socket address record
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};struct sockaddr_in6 { // IPv6 socket address record
unsigned short sin6_family;
unsigned short sin6_port;
unsigned int sin6_flowinfo;;
struct in6_addr sin6_addr;
unsigned int sin6_scope_id;
};sockaddr_in6 is used to model IPv6 address/port pairs.
sin6_family field should always be set to AF_INET6. As with the sin_family field, sin6_family field occupies the first two bytes of surrounding record.sin6_port field holds a two-byte, network-byte-ordered port number, just like sin_port does.struct in6_addr is also wedged in there to manage a 128-bit IPv6 address.sin6_flowinfo and sin6_scope_id are beyond the scope of what we need, so we'll ignore them.struct sockaddr { // generic socket
unsigned short sa_family; // protocol family for socket
char sa_data[14];
// address data (and defines full size to be 16 bytes)
};struct sockaddr_in { // IPv4 socket address record
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};struct sockaddr_in6 { // IPv6 socket address record
unsigned short sin6_family;
unsigned short sin6_port;
unsigned int sin6_flowinfo;;
struct in6_addr sin6_addr;
unsigned int sin6_scope_id;
};struct sockaddr is the best C can do to emulate an abstract base class.
struct sockaddr, but many system calls will accept parameters of type struct sockaddr *.struct sockaddr_in or a struct sockaddr_in6. The system call relies on the value within the first two bytes—the sa_family field—to determine what the true record type is.struct sockaddr { // generic socket
unsigned short sa_family; // protocol family for socket
char sa_data[14];
// address data (and defines full size to be 16 bytes)
};struct sockaddr_in { // IPv4 socket address record
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};struct sockaddr_in6 { // IPv6 socket address record
unsigned short sin6_family;
unsigned short sin6_port;
unsigned int sin6_flowinfo;;
struct in6_addr sin6_addr;
unsigned int sin6_scope_id;
};