地址信息表示
struct sockaddr_in 
{
    sa_family_t     sin_family;     // 地址族
    uint16_t        sin_port;       // 16位TCP/UDP端口号
    struct in_addr  sin_addr;       // 32位IP地址
    char            sin_zero[8]     // 不使用
};
struct in_addr
{
    in_addr_t       s_addr;         // 32位IPv4地址
};
| 地址族 | 含义 | 
|---|---|
| AF_INET | IPv4网络协议使用的地址族 | 
| AF_INET6 | IPv6网络协议使用的地址族 | 
| AF_LOCAL | 本地通信中采用的UNIX协议的地址族 | 
struct sockaddr
{
    sa_family_t sin_family; // 地址族
    char        sa_data;    // 地址信息
};
其中,成员sa_data保存的地址信息中需包含IP地址和端口号,剩余部分填充0,这也是bind函数要求的。
关于sin_family
sockaddr_in是保存IPv4地址信息的结构体。那为何还需要通过sin_family单独制定地址族信息呢?这与之前讲过的sockaddr有关。结构体sockaddr并非只为IPv4设计,为了与sockaddr保持一致,sockaddr_in要求在sin_family中指定地址族信息。
字节序转换
在实际代码编写中,字节序转换过程是自动的。除了向sockaddr_in结构体变量填充数据外,其他情况均无需考虑字节序问题。
inet_addr
#include <arpa/inet.h>
in_addr_t inet_addr(const char* string);
成功则返回32位大端序整数值,失败则返回INADDR_NONE. 
inet_aton
#include <arpa/inet.h>
int inet_aton(const char *string, struct in_addr *addr);
成功则返回1(true),失败则返回0(false)
inet_ntoa
#include <arpa/inet.h>
char * inet_ntoa(struct in_addr addr);
成功则返回转换的字符串地址,失败则返回-1
INADDR_ANY
每次创建服务器端套接字都要输入IP地址会有些繁琐,此时我们可以利用常数INADDR_ANY分配服务器端的IP地址。此法,可自动获取运行服务器的计算机IP地址,不必亲自输入。