文章目录
- 一、内网ip简介
- 二、特殊IP地址
- 三、代码示例
-
- 3.1 代码测试
- 3.2 函数说明
-
- 3.2.1 inet_pton函数
- 3.2.2 ntohl函数
- 3.2.3 inet_addr函数
一、内网ip简介
内网IP地址是指在局域网中使用的IP地址,不同于公网IP地址,不向互联网开放,只在局域网内有效。内网IP地址通常由路由器或交换机等网络设备动态分配或静态分配,用于局域网内的设备互相通信,不需要向外部网络公开。
在IPv4地址中,有三个私有地址段专门用于内网IP地址,它们是:
10.0.0.0 到 10.255.255.255(10.0.0.0/8)
172.16.0.0 到 172.31.255.255(172.16.0.0/12)
192.168.0.0 到 192.168.255.255(192.168.0.0/16)
特殊的内网ip地址:
169.254.0.0 到 169.254.255.255
169.254.0.0 到 169.254.255.255 之间的地址是一个特殊的保留地址范围,也称为APIPA地址(Automatic Private IP Addressing)。APIPA地址是一种用于自动分配IP地址的机制,通常用于在缺乏DHCP服务器的情况下,允许设备自动配置自己的IP地址。
二、特殊IP地址
如下所示:
(1)通配符地址
(2)环回地址
(3)D/E类地址
0.0.0.0 // 通配符地址
127.0.0.0 - 127.255.255.255 // 本地环回地址
224.0.0.0 - 255.255.255.255 // D/E class 地址
三、代码示例
3.1 代码测试
#include
#include
#include
#include
//检查字符串IP是否合法
//如果合法,获取该字符串IP的:host byte order
bool _is_check_ip_true(const std::string& string_ip, uint32_t& host_num)
{
struct in_addr addr; // IPv4地址结构体
if (inet_pton(AF_INET, string_ip.c_str(), &addr) != 1) {
return false;
}
host_num = ntohl(addr.s_addr);
return true;
}
//判断是否是内网ip
bool isInternalIP(uint32_t& host_num) {
if ((host_num >= ntohl(inet_addr("10.0.0.0"))) && (host_num ntohl(inet_addr("10.255.255.255")))) {
return true;
}else if ((host_num >= ntohl(inet_addr("172.16.0.0"))) && (host_num ntohl(inet_addr("172.31.255.255")))) {
return true;
}else if ((host_num >= ntohl(inet_addr("192.168.0.0"))) && (host_num ntohl(inet_addr("192.168.255.255")))) {
return true;
}else if ((host_num >= ntohl(inet_addr("169.254.0.0"))) && (host_num ntohl(inet_addr("169.254.255.255")))) {
return true;
}
return false;
}
//过滤掉一些特殊的ip地址
bool FilterIP(uint32_t& host_num) {
if ((host_num == ntohl(inet_addr("0.0.0.0")))) {
return true;
}else if ((host_num >= ntohl(inet_addr("127.0.0.0"))) && (host_num ntohl(inet_addr("127.255.255.255")))) {
return true;
}else if ((host_num >= ntohl(inet_addr("224.0.0.0"))) && (host_num ntohl(inet_addr("255.255.255.255")))) {
return true;
}
return false;
}
int main()
{
std::string ip;
uint32_t host_num = 0;
bool ret = false;
while(1){
std::cout "Please enter an IP address: ";
std::getline(std::cin, ip);
if(ip.empty()){
std::cout "IP string is empty" std::endl;
continue;
}
if("quit" == ip){
break;
}
ret = _is_check_ip_true(ip.c_str(), host_num);
if(!ret){
std::cout "IP addresses is not vaild: " ip std::endl;
continue;
}
ret = FilterIP(host_num);
if(ret){
std::cout "Filtered IP addresses: " ip std::endl;
continue;
}
ret = isInternalIP(host_num);
if(ret){
std::cout " IP isInternalIP:" ip std::endl;
continue;
}
std::cout "IP isOutternalIP:" ip std::endl;
}
return 0;
}
# g++ test.cpp
# ./a.out
Please enter an IP address: 1.1.1.1
IP isOutternalIP: 1.1.1.1
Please enter an IP address: 0.0.0.0
Filtered IP addresses: 0.0.0.0
Please enter an IP address: 10.0.0.0
IP isInternalIP: 10.0.0.0
Please enter an IP address: 125.1.1.10
IP isOutternalIP: 125.1.1.10
Please enter an IP address: 2.2.2.2.2
IP addresses is not vaild: 2.2.2.2.2
Please enter an IP address: quit
3.2 函数说明
3.2.1 inet_pton函数
(1)
NAME
inet_pton - convert IPv4 and IPv6 addresses from text to binary form
SYNOPSIS
#include
int inet_pton(int af, const char *src, void *dst);
DESCRIPTION
This function converts the character string src into a network address structure in the af address family, then copies the network address structure to dst. The af
argument must be either AF_INET or AF_INET6.
inet_pton函数是一个用于将一个IPv4或IPv6地址的点分十进制字符串转换为一个网络字节序二进制值的函数。它可以在IPv4和IPv6之间进行自适应转换。
该函数可以用来判断一个字符串ip格式是否正确。
一个简单的测试代码:
#include
#include
int main() {
const char *ipaddr_str = "192.168.1.1";
struct in_addr ipaddr;
if (inet_pton(AF_INET, ipaddr_str, &ipaddr) 0) {
printf("无效的IPv4地址字符串n");
} else {
printf("转换后的IPv4地址为:%sn", inet_ntoa(ipaddr));
}
return 0;
}
在Linux系统的C编程中,struct in_addr是一个用于表示IPv4地址的结构体类型,它定义在头文件中。其定义如下:
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
其中,in_addr_t类型是一个无符号32位整数类型,用于存储IPv4地址的二进制形式。而struct in_addr结构体则包含一个in_addr_t类型的成员s_addr,用于存储IPv4地址的二进制形式。
需要注意的是,struct in_addr结构体和in_addr_t类型都使用网络字节序(大端字节序)来表示IPv4地址,因此在使用struct in_addr结构体中的成员变量s_addr时,需要使用类似于htonl和ntohl这样的函数进行字节序转换,以确保正确地表示和处理IPv4地址。
(2)
其中inet_ntoa函数:
/* Convert Internet number in IN to ASCII representation. The return value
is a pointer to an internal array containing the string. */
char *inet_ntoa(struct in_addr in);
inet_ntoa函数用于将一个IPv4地址的网络字节序二进制值转换为一个点分十进制字符串表示。该函数的返回值是一个指向缓冲区的指针,其中包含了转换后的点分十进制字符串表示。
#include
#include
int main() {
uint32_t uint_host = 0xC0A80101;
struct in_addr in;
in.s_addr = htonl(uint_host);
printf("转换前的IPv4地址主机字节序为:%08Xn", uint_host);
printf("转换前的IPv4地址网络字节序为:%08Xn", in.s_addr);
printf("转换后的IPv4地址点分十进制字符串为:%sn", inet_ntoa(in));
return 0;
}
$ ./a.out
转换前的IPv4地址主机字节序为:C0A80101
转换前的IPv4地址网络字节序为:0101A8C0
转换后的IPv4地址点分十进制字符串为:192.168.1.1
与之相同功能的还有inet_ntop函数。
NAME
inet_ntop - convert IPv4 and IPv6 addresses from binary to text form
SYNOPSIS
#include
const char *inet_ntop(int af, const void *src,
char *dst, socklen_t size);
DESCRIPTION
This function converts the network address structure src in the af address family into a character string. The resulting string is copied to the buffer pointed to
by dst, which must be a non-NULL pointer. The caller specifies the number of bytes available in this buffer in the argument size.
inet_ntop() extends the inet_ntoa(3) function to support multiple address families, inet_ntoa(3) is now considered to be deprecated in favor of inet_ntop(). The
following address families are currently supported:
AF_INET
src points to a struct in_addr (in network byte order) which is converted to an IPv4 network address in the dotted-decimal format, "ddd.ddd.ddd.ddd". The
buffer dst must be at least INET_ADDRSTRLEN bytes long.
AF_INET6
src points to a struct in6_addr (in network byte order) which is converted to a representation of this address in the most appropriate IPv6 network address
format for this address. The buffer dst must be at least INET6_ADDRSTRLEN bytes long.
inet_ntoa函数和inet_ntop函数,这两个函数将网络字节序的32位整数转换为点分十进制字符串。
其中,inet_ntoa函数的返回值是一个指向缓冲区的指针,其中包含了转换后的点分十进制字符串表示。但是,由于inet_ntoa函数在内部使用一个静态缓冲区,因此不能保证线程安全,而且每次调用此函数时,它都会返回一个指向同一静态缓冲区的指针,因此在多个线程中同时使用此函数可能会导致竞争条件。
相比之下,inet_ntop函数则更加灵活,它可以将转换结果存储到指定的缓冲区中,并指定缓冲区的大小。这样可以避免由于使用静态缓冲区而导致的线程安全问题。因此,建议使用inet_ntop函数进行转换操作。
#include
#include
int main() {
uint32_t uint_host = 0xC0A80101;
struct in_addr in;
in.s_addr = htonl(uint_host);
char buf[INET_ADDRSTRLEN];
const char *ipaddr_str = inet_ntop(AF_INET, &in, buf, INET_ADDRSTRLEN);
if (ipaddr_str == NULL) {
printf("转换失败n");
} else {
printf("转换前的IPv4地址主机字节序为:%08Xn", uint_host);
printf("转换前的IPv4地址网络字节序为:%08Xn", in.s_addr);
printf("转换后的IPv4地址点分十进制字符串为:%sn", ipaddr_str);
}
return 0;
}
$ ./a.out
转换前的IPv4地址主机字节序为:C0A80101
转换前的IPv4地址网络字节序为:0101A8C0
转换后的IPv4地址点分十进制字符串为:192.168.1.1
3.2.2 ntohl函数
ntohl函数用于将一个32位无符号整数(从网络字节序(大端字节序)转换为主机字节序(小端字节序)。该函数返回转换后的32位无符号整数。
uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
#include
#include
int main() {
uint32_t netlong = 0x0101A8C0;
uint32_t hostlong = ntohl(netlong);
printf("网络字节序的32位整数为:%08Xn", netlong);
printf("主机字节序的32位整数为:%08Xn", hostlong);
return 0;
}
$ ./a.out
网络字节序的32位整数为:0101A8C0
主机字节序的32位整数为:C0A80101
3.2.3 inet_addr函数
/* Convert Internet host address from numbers-and-dots notation in CP
into binary data in network byte order. */
in_addr_t inet_addr (const char *__cp) __THROW;
inet_addr函数用于将一个IPv4地址的点分十进制字符串转换为一个网络字节序的32位整数。
其中,cp参数是一个指向点分十进制字符串的指针,表示要转换的IPv4地址。返回值是一个网络字节序的32位整数,表示转换后的IPv4地址。
#include
#include
int main() {
const char *ipaddr_str = "192.168.1.1";
in_addr_t ipaddr = inet_addr(ipaddr_str);
if (ipaddr == INADDR_NONE) {
printf("无效的IPv4地址字符串n");
} else {
printf("转换后的IPv4地址为:%08Xn", ipaddr);
}
return 0;
}
在这个示例中,我们将点分十进制字符串”192.168.1.1″转换为一个网络字节序的32位整数。
$ ./a.out
转换后的IPv4地址网络字节序为:0101A8C0
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: 基于ARIMA、SVM、随机森林销售的时间序列预测|附代码数据
原文链接 http://tecdat.cn/?p=1130 最近我们被客户要求撰写关于时间序列预测的研究报告,包括一些图形和统计输出。 如今DT(数据技术)时代,数据变得越来越重要,其核心应用“预测”也成为互联网行业以及产业变革的重要力量。 对于零售行业来说…