IP地址、子网掩码和地址分类

http://blog.csdn.net/bluishglc/article/details/47909593?utm_source=tuicool&utm_medium=referral

实际工作中用到网络知识的机会并不多,虽然以前学习过,但是许久不用自然也就生疏了。最近拿到几台云上的虚拟机,需要为它们建立一个VPC(虚拟私有云,就是一个虚拟的局域网),得益于虚拟化技术,作为用户,我们省去了绝大多数的网路配置和调试工作,唯一需要我们亲自操刀主持的就是对网络的划分了。划分网络需要清楚三个基本概念:IP地址、子网掩码和地址分类,是这三个要素一起决定了整个IP地址空间的划分。关于这些可以参考文章最后附上的资料,本文正文是从三者之间的关联关系上思考对一个网络进行划分需要解决什么问题。本文原文出处:http://blog.csdn.net/bluishglc/article/details/47909593 严禁任何形式的转载,否则将委托CSDN官方维护权益!

32位的IP地址空间总计有40多亿个可用IP地址,如果你是互联网创建之初的设计者,你会怎么分配这些IP?你可能会说一个一个地分吧,请求一个给一个。这不失为是一个方案,但是面对这么多的IP地址,这种“扁平”的管理方式真的有效吗?如果是给一个组织甚至国家批量分配P呢?就像是在一个文件夹下管理40多亿个文件一样,这种处理方式真的明智吗?显然,当时的设计者并没有采取这种简单直白的做法,而是像我们管理大多数信息一样对信息进行了“分门别类”,同样是40多亿个文件,如果按照某种规则或特征把它们分散放置到多个文件夹或子文件夹下一定会极大地方便管理。

于是问题来了:怎么分?

如果把IP地址看作是一个家庭住址,那么在家庭住址中自然有省、市、街道、小区这样的层级划分,逐级缩小范围后定位到一个门牌号上。如果我们给省、市、街道都编好号,再和门牌号拼在一起,我们得到的这样一长串数字就可以唯一地标识一个家庭住址,同样,IP地址有32位的长度,如此之长的一个编码,为什么不可以取出前几位作为一个“区域”的地址,把剩余的几位作为它在这个区域下的”相对“地址呢?这样一个IP地址就可以视作两部分,前面是它的“区域“地址,后面是它在这个”区域“内的”相对“地址,是的,这正是子网掩码所要解决的问题,按照规范的叫法,通过子网掩码标识出的所谓的“区域“地址就网络地址,也叫网络标识,网络ID或子网地址,而所谓的“相对“地址就主机地址。

这样看上去好了很多,但是不知道你有没有敏锐地察觉到子网掩码对IP地址的划分与我们举例的家庭住址的划分有一个明显的不同,那就是前者只能划分两级:网络地址和主机地址,而后者则是多级划分。子网掩码只能实现两级划分带来了一个问题,那就是同样一个IP:67.101.121.131,它的子网掩码有可能是255.0.0.0,也可能是255.255.0.0,也可能是别的什么值,于是,对于一个给定的IP,特别是公网的IP,在不知道子网掩码的时候会导致对该IP有多种不同的解读,就像上面的例子,67.101.121.131可能是子网67.0.0.0下的一个主机,也可能是子网67.101下的一个主机,很显然,这种歧义性导致这个IP还是不可用,是的,我们还是漏了点什么,让这套描述机制暂时无法工作,我们需要找到问题的原因并堵上这个窟窿。

这最后一个需要解决漏洞可以描述为:由于子网掩码只具有”两级“(网络地址和主机地址)划分能力,而它的切分粒度又可变(即如果切出的子网少,则子网可以容纳的机器数量就多,如果子网多,则可以容纳的机器数量就小)这种不确定的划分方式必然会导致IP含义的不确定性,所以要解决这个问题就必须要规定好:以哪些值为开头的IP它的子网掩码默认是255.0.0.0,以哪些值为开头的IP它的子网掩码默认是255.255.0.0,以此类推。这实际上就是IP地址分类。

补上地址分类的概念之后,我们再来重新比较一个IP地址空间的划分与我们举例使用的家庭住址这类具有典型层级关系的信息划分之间有什么不同。如前面所述,最大的不同在于IP地址空间只能划分两个层级,为了能够适应不同规模(粒度)的IP分配要求,IP地址空间必需要划分出多种不同规模(粒度)的子空间,并且规定好哪些是大规模(粒度)的子空间,哪些是小规模(粒度)的子空间。然后,再结合IP地址和子网掩码就可以准确地定位了。可以说IP地址、子网掩码和地址分类这三个要素一起实现了对IP地址空间的划分与寻址,三者任何一个元素的缺失都会带来逻辑上的漏洞。

最后一个问题:同样的,在一个局域网里,理论上我们也有需要切分出大小不等的子网的需求,这也需要对IP地址进行分类,比如在10.0.0.0/8的网路里划分10.0.0.0/16 ~ 10.127.0.0/16和10.128.0.0/24 ~10.191.255.0/24 等等 至于是否可行以及如何操作待有机会和网络管理员请教一下。

最后,附上一个非常好用的网络计算器:http://www.123cha.com/cidr/


参考资料

子网掩码

子网掩码是用来指明一个IP地址的哪几位标识的是主机所在的子网(也叫网络标识),以及哪些位标识的是主机在网络中的地址。子网掩码不能单独存在,它必须结合IP地址一起使用。

但是如果只有子网掩码, 我们可以判断出的信息是:它能表示多个子网,以及每个子网下能有多少个主机!

子网掩码通常有以下2种格式的表示方法:

1. 通过与IP地址格式相同的点分十进制表示 
如:255.0.0.0 或255.255.255.128 
2. 在IP地址后加上”/”符号以及1-32的数字,其中1-32的数字表示子网掩码中网络标识位的长度 
如:192.168.1.1/24 的子网掩码也可以表示为255.255.255.0

IP地址分类

在一个局域网里,我们完全可以按照自己的意愿和需要来切分网络地址,同样也是定义3要素, 
地址分类,子网掩码和IP地址。

IP默认分配的子网掩码每段只有255或0

A类IP地址 第一个字段的取值范围:0-127  默认的子网掩码:255.0.0.0

B类IP地址的第一个字段的取值范围:128-191  默认的子网掩码255.255.0.0

C类IP地址的第一个字段的取值范围:192-223  默认的子网掩码  255.255.255.0

已知IP地址和子网掩码,用IP地址和子网掩码相与即可得到网络号

子网掩码的最后面有几个零,比如n个,即可求出主机数:pow(2,n)-2  (全零用于网络地址,全1用于广播地址)

子网掩码中1的个数可以用于求子网的数目

比如IP地址为151.244.20.34 子网掩码为255.255.255.224,这个IP是B类IP,两者相与,

网络号为151.244.20.32

224用二进制表示为11100000,后面有5个0,则主机数为pow(2,5)-2,其中全0用作网络地址,全1为广播地址

16-5=11,则子网数目为pow(2,11)-2  其中全0用作网络地址,全1为换回测试用

下面的python程序可以判断IP的类别并求对应的网络号:

s=raw_input();
s=s.split(".");
mask=raw_input();
mask=mask.split(".");
for i in range(0,4):
s[i]=int(s[i]);
mask[i]=int(mask[i]);
if(s[0]>=0 and s[0]<=127):
print "A IP";
flag=1;
elif(s[0]<=192):
print "B IP";
flag=2;
elif(s[0]<=223):
print "C IP";
flag=3;
elif(s[0]>255):
print "error";
if(flag is 1):
i=0;
res=[];
for i in range(0,4):
res.append(mask[i]&s[i]);
print "network number is %d.%d.%d.%d" %(res[0],res[1],res[2],res[3]);
if(flag is 2):
res=[];
for i in range(0,4):
res.append(mask[i]&s[i]);
print "network number is %d.%d.%d.%d" %(res[0],res[1],res[2],res[3]); if(flag is 3):
res=[];
for i in range(0,4):
res.append(mask[i]&s[i]);
print "network number is %d.%d.%d.%d" %(res[0],res[1],res[2],res[3]);

保留地址

在IP地址中专门保留了三个区域作为私有地址,其地址范围如下:

类型 网络地址 网络数
A 10.0.0.0/8 (10.x.x.x) 1
B 172.16.0.0/12 (172.16.x.x ~ 172.31.x.x) 16
C 192.168.0.0、16 (192.168.x.x ~ 192.168.x.x) 256
上一篇:c - 字符串的反转


下一篇:libCurl的文件上传