IP地址在代码中的应用

 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_insockaddr_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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值