通用套接字地址结构
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family; //协议族
char sa_data[4];
};
因为有不同的网络协议,对于bind函数时,就需要通用的套接字地址结构
IPv4套接字地址结构
struct in_addr
{
in_addr_t s_addr //32位的ipv4地址(网络字节序存放)
};
struct sockaddr_in
{
uint8_t sin_len; //结构体长度
sa_family_t sin_family; //AF_INET
in_port_t sin_port; //16位的端口号
struct in_addr sin_addr; //32位ipv4地址
};
网络字节序,主机字节序
网络字节序就是大端模式。
主机字节序就是主机自己存放模式,即是大端模式,还是小端模式。
因为在网络中统一用网络字节序,所以必要时需要进行网络字节序与主机字节序的互相转换。
转换函数:
#include <netinet/in.h>
//host to network
uint16_t htons(uint16_t host16bitvalue);
unit32_t htonl(uint32_t host32bitvalue);
//netword to host
uint16_t ntohs(uint16_t net16bitvalue);
unit32_t ntohl(uint32_t nett32bitvalue);
点分十进制与二进制IP地址的转换
对于ipv4地址
#include <arpa/inet.h>
int inet_aton(const char *strptr, struct in_addr *addrptr);
in_addr_t inet_addr(const char *strptr);
char *inet_ntoa(struct in_addr inaddr);
- inet_addr函数在出错是会返回INADDR_NONE,通常是32位均为1。
- inet_ntoa返回再静态内存中,所以不可以重用
- inet_aton将strptr所指向的点分十进制转成二进制ip地址,并存放在addrptr所指向的内存区域。
ipv4与ipv6都可用
int inet_pton(int family, const char *strptr, void *addrptr);
//成功返回1,若输入不是有效的表达格式则为0,出错返回-1
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
//成功返回指向结果的指针,否则返回NULL
- inet_pton:指定了协议族family之后,将点分制strptr,转为二进制ip地址,并存放到addrptr所指向内存中。注意这里addrptr是一个void *指针。
- inet_ntop将二进制ip地址转为数值格式,二进制ip地址存放在addrptr中,strptr存放的是装换后的数值格式ip地址,len 表示目标存储单元大小,一般是strptr的大小。