IP地址的表现形式
关于字节序的问题看这个:大端/小端字节序与网络字节序。
1、点分十进制
这是我们最常见的表示格式,比如某机的IP地址可能为“202.101.105.66”。

2、网络字节序
在网络传输中,TCP/IP协议使用网络字节序格式保存IP地址。

3、主机字节序
在主机内部,使用主机字节序保存和处理IP地址。

IP地址在代码中的应用
1、因特网地址
1.1 IPv4
#include <netinet/in.h>
struck in_addr {
in_addr_t s_addr; //IPv4 address
};
1.2 IPv6
struct in6_addr {
uint_8 s6_addr[16]; //IPv6 address
};
2、Socket网络通信地址
在网络通信中,一个地址标识一个特定通信域的套接字端点,为了使不同格式的地址都能够传入套接字函数,地址会被强转成一个通用的地址结构体,sockaddr:
套接字实现可以自由地添加额外的成员并定义sa_data成员的大小。(具体看APUE 478页)
//Linux中对sockaddr的定义
struct sockaddr {
sa_family_t sa_family; // address family 协议族
char sa_data[14]; // variable-length address 端口和ip等信息
};
总结来说,使用套接字函数如bind、connect等套接字函数时需使用通用结构体sockaddr。
而使用internet下的ip地址结构体sockaddr_in 、sockaddr_in6用来赋值后再强转成通用结构体进行套接字通信。
因特网地址定义在<netinet/in.h>头文件中。在IPv4因特网域(AF_INET)中,套接字地址用sockaddr_in表示。在IPv6因特网域(AF_INET6)中,套接字地址用sockaddr_in6表示。
网络通信三要素:ip、端口、协议。
2.1 IPv4
#include <netinet/in.h>
struct in_addr{ /* IPv4 4-byte address */
in_addr_t s_addr; /* Unsigned 32-bit integer */
}
struct sockaddr_in { /* IPv4 socket address */
sa_family_t sin_family; /* Address family(AF_INET) */
in_port_t sin_port; /* Port number */
struct in_addr sin_addr; /* IPv4 address */
__int8_t sin_zero[8]; /* Same size as struct sockaddr */
}
2.2 IPv6
#include <netinet/in.h>
struct in6_addr {
union {
uint8_t __u6_addr8[16];
uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
} __u6_addr; /* 128-bit IP6 address */
};
struct sockaddr_in6 { /* IPv6 socket address */
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* Port number*/
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* Scope ID */
};
相关转换函数
1、字节序转换函数
#include <arpa/inet.h>
//htons函数 发 将主机字节序的端口 转换成 网络字节序的端口
uint16_t htons(uint16_t host16bitvalue); //返回网络字节序的值
//ntohs函数 收 将网络字节序的端口 转换成 主机字节序的端口
uint16_t ntohs(uint16_t net16bitvalue); //返回主机字节序的值
//htonl函数 发 将主机字节序的IP地址 转换成网络字节序的IP地址
uint32_t htonl(uint32_t host32bitvalue); //返回网络字节序的值
//ntohl函数 收 将网络字节序的IP地址 转换成主机字节序的IP地址
uint32_t ntohl(uint32_t net32bitvalue); //返回主机字节序的值
2、ip地址转换函数
2.1 IPv4
#include <arpa/inet.h>
// 将一个十进制网络字节序转换为点分十进制IP格式的字符串
char* inet_ntoa(struct in_addr in); //正确执行返回一个字符指针(十进制ip字符串);错误返回NULL;
// 将一个点分十进制IP地址转换为一个32位的网络序列IP地址。
int inet_aton(const char *string, struct in_addr *addr); //成功执行返回值非零,如果输入地址不正确则会返回零;
in_addr_t inet_addr(const char* string); // 成功执行返回in_addr_t类型的网络字节序ip地址
in_addr_t inet_network(const char *string); // 成功执行返回in_addr_t类型的主机字节序ip地址
2.2 IPv4、IPv6
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
/*
* int inet_pton(int domain, const char *src, void *dst);
*
* 函数功能:
* 将一个点分十进制字符串IP地址转换为一个网络序列IP地址。
* 参数:
* domain: 协议族 AF_INET、AF_INET6
* src:点分十进制字符串IP地址存储缓冲区
* dst:二进制网络字节序IP地址存储缓冲区
*返回值:
* 若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
*/
int inet_pton(int domain, const char *src, void *dst);
/*
* const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);
*
* 函数功能:
* 将一个十进制网络字节序转换为点分十进制IP格式的字符串。
* 参数:
* domain: 协议族 AF_INET、AF_INET6
* src:传入的网络字节序IP地址存储缓冲区
* dst:点分十进制IP地址存储缓冲区
* size:传入网络字节序IP地址src的大小。
*返回值:
* 若成功则返回一个指向缓冲区的指针,该缓冲区包含标准格式的IP地址的字符串表示形式,若出错则为NULL
*/
const char *inet_ntop(int domain, const void *src,char *dst, socklen_t size);

664

被折叠的 条评论
为什么被折叠?



