IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。
IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)如:
01100100.00000100.00000101.00000110。
通常用“点分十进制”的方式来表示,即 a.b.c.d 的形式(a,b,c,d都是0~255之间的十进制整数)。如:100.4.5.6。
ps:IP协议有两个版本,IPv4和IPv6。我们整个的课程,凡是提到IP协议,没有特殊说明的,默认都是指IPv4。
IPv4数量=2^32,大约43亿左右,而TCP/IP协议规定,每个主机都需要有一个IP地址。对于全世界计算机来说,这个数量是不够的,所以后来推出了IPv6(长度128位,是IPv4的4倍)。但因为目前IPv4还广泛的使用,且可以使用其他技术来解决IP地址不足的问题,所以IPv6也就没有普及。
IP地址分为两个部分,网络号和主机号
网络号:标识网段,保证相互连接的两个网段具有不同的标识;
主机号:标识主机,同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号;
(我们主要讨论IPv4)
IP的报头和TCP类似,都是可变的,带有选项。
4位的取值范围是0~15,单位是4字节
如果我们取值1111>15,实际表示的首部长度就是60字节
(4*15=60)
TOS说是8位,其实只有4位是有效的:
4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本(同一时刻只能取一种状态)
最小延时:从A到B之间取一条时间最短的路径
最大吞吐量:从A到B之间取一条传输带宽最高的
最高可靠性:从A到B之间取一条最不容易丢包的
最小成本:从A到B之间取一条开销最小的
IP协议能够规划处两点之间比较合适的路径:这里的合适要看你的TOS是怎么选的
我们回想一下UDP好像也有类似情况:16位对应了一个最大长度64k。
因此,单个IP数据报最大长度确实不能超过64k
如果要构造一个更长的数据报(比如搭载的载荷部分已经超过了64k)怎么办?
IP协议自身实现了分包组包这样的操作,具体怎么实现呢?请看小节 5)
比如我们这里把它拆成2个小包:两个包两个IP报头,原有的IP数据载荷一分为二
可能会有同学问:你第二个没有TCP报头吗?
对于IP数据包来说,我们不关心载荷里面是什么,只是单纯的对数据进行了切分,我们也不用知道切分下来的哪一块有TCP报头。
举个例子:
我现在买了一个大床,卖家给我发送了床和两床被子,分开发送,难道我们快递站需要知道你哪个包裹里面是床,哪个包裹里面是被子吗?它只关心要把这些东西打包成几份来发送
可能会有同学又问:那接收方怎么区分这多个IP包是同一个IP数据分割而来的呢?
我们还是联想发快递:我们商家发快递,即使是拆成多个包裹发送,那这几个包裹快递单号也是一样的
多个被拆除的IP数据包的16位标识的值是相同的
比如我们这里两个拆下来的IP数据包标识都是1000
可能会有同学又问:粘包问题不是有个边界吗,顺序怎么排呢?
我们知道,网络上可能出现后发先置的情况,发送方后发送的,可能先被接收方收到。也就是说,接收方收到的顺序可能和发送方发送的不一样
我们通过13位片偏移,来描述这个包谁先谁后(片偏移越小,就是越靠前的包)
通过片偏移,我们就可以对里面的数据包按照顺序重组,保证顺序不会出错。
剩下的一个就是3位标志位了
3位标志位其实只有1位是好使的
这1位=0表示还有后续
这1位=1表示这是最后一个包了
ps:面试中可能会问:如何基于UDP实现分包组包?
解决方案就是照抄IP协议的分包组包——引入标识、片偏移、结束标记
表示一个IP数据报,在网络上还能存在多久,这里的单位不是s或ms,而是转发次数
IP数据报被发送的时候,就会有一个初始TTL(比如常见的取值,128或64)
IP数据报每次经过了一个路由器,TTL就会-1
如果TTL减到了0,此时收到这个包的路由器就会把这个包丢掉
主要就是有些包里面的IP地址,可能是永远也到达不了的,像这样的包,不可能在网络上无休无止的转发(占用的资源太多了)。而正常的IP数据报都会在既定的TTL内到来。
就是指传输层使用的是哪种协议,TCP或者UDP都有不同的取值,通过这个取值,我们来区分出当前我们要把这个数据交给传输层的哪个协议来处理
这个和我们UDP是一样的,都是来校验数据是否正确的
源IP表示发件人地址
目的IP表示收件人地址
对于IPv4来说,一个IP地址本质上是一个32位的整数
我们通常会使用“点分十进制”这样的方式来表示这个IP地址
三个点,把32位整数分成4个部分,每个部分1个字节(8bit)
每个部分的取值就是0~255
比如192.168.2.9这是我当前主机的IP地址
给人看的IP通常就是点分十进制表示的,
给机器存储的IP,在底层仍然是按照4个字节整数来表示的。
到这里IP协议报头就介绍的差不多了,我们再来看看关于地址管理的相关内容。
IP地址是一个点分十进制构成的数据,我们把IP地址分成两个部分,网络号+主机号
网络号:描述了当前的网段信息
主机号:描述了局域网内部的主机
规定:同一个局域网内主机之间的网络号是相同的,主机号是不同的。
两个相邻的局域网(同一个路由器连接的),网络号也是不同的。
以我家的网络环境为例:
在这个局域网中可以看到,网络号都是192.168.2,但是主机号都是不同的。
我们再来看一下我家另外一个局域网
总览图:
在当前我家的两个局域网中,一边是我的路由器构成的局域网,另一边是我的光猫构成的局域网
注:IP协议主要完成两方面工作(分别会在本文的四和五进行介绍):
1.地址管理
2.路由选择
关于到底前多少个bit位是网络号呢?固定3字节吗?
这个其实是不固定的,我们引入了“子网掩码”的概念,来表示多少bit位是网络号。
子网掩码,也是一个32位点分十进制表示的整数
比如我这里的子网掩码:
255.255.255.0
子网掩码的左侧都是1,右侧都是0(不会1 0混合排列)
比如255:1111 1111 1111 1111 1111 1111 0000 0000
一般家用的场景中,一个局域网设备很少,不会超过255,常见的子网掩码就是255.255.255.0
但如果是公司或者学校,一个局域网的设备多了,子网掩码就会出现一些其他值。
ps:需要根据实际需要来确定网段如何划分,每个设备的IP都是可以配置的,包括子网掩码什么的,都是可以修改的,但我们程序员一般不考虑改这个。这个是由网络管理员专门负责修改的,我们了解一下即可。
还有一个小小的问题
IP地址网段划分,是通过子网掩码的方式划分的,
在历史上有子网掩码之前,我们是粗暴的通过“分类”的方式来划分的,我们把IP地址分成了A、B、C、D、E这五类,每一类有多少网络号、主机号
(该种划分方式已淹没于历史长河中,但是笔试选择题可能会出现来恶心你一下,我们了解一下)
我们先来了解一下,一些特殊的IP地址:
1、如果IP的主机号全0,该IP就表示网络号(局域网里一个正常的设备,主机号不能设为0)
2、如果IP地址是以127开头的,该IP都表示“环回IP”,也就是表示主机自己,127.0.0.1(环回IP的典型)
3、如果IP地址是以10开头的,192.168开头的,172.16-172.31开头的,表示该IP地址是一个局域网内部的IP(内网IP)
除上述3种情况,剩下的IP称为外网IP(直接在广域网上使用的IP)
要求外网IP一定是唯一的,每个外网IP都会对应到唯一的一个设备,
内网IP只是在当前局域网中是唯一的,不同的局域网里,可以有相同的内网IP的设备。
可能会有同学问:“本来我们预期的IP地址就应该表示网络上的一个唯一的位置,那为啥一个IP能表示不同设备呢?”
回答:当前IPv4协议,使用的IP地址是32位的整数,32位能表示的范围是42亿9千万…那如果给每个设备都分配一个唯一的IP地址,那是不是就意味着世界上的设备不能超过42亿9千万了?所以,让每个设备都有唯一的IP地址不现实。
那如何解决这个问题呢?
让每个设备连上网的时候,才有IP,不联网的时候就没有IP(同一个IP可以给别人用)
把网络分成了内网(局域网),和外网(广域网)
要求外网IP必须表示唯一的设备
同时内网中的若干设备,可以共用一个外网IP
比如我现在要打lol,我要访问lol的服务器,那访问路径就是图中的绿色箭头
我们会经过一个运营商设备,运营商设备是有外网IP180.119.39.154(扬州市高邮市的IP)
而这个外网IP显然不是仅仅给我个人用的,而是给所有接入这个运营商设备的局域网,都在共用这同一个IP
这个时候每个外网IP都表示几千个,甚至上万个设备,这个时候IP地址的压力就缓解很多了。
这个时候可能又会有同学问了:“那如果多个来自一个外网IP的同时访问LOL的服务器,那LOL服务器怎么区分谁是谁呢?如下图:”
这里的进一步区分,就是靠端口号了。
网络的连接,是一个五元组,即使你IP相同也没有关系
比如现在lol服务器上有两个连接:
NAT机制,把IP分成了内网和外网,也就隐含了一个重要的结论:
对于一个外网IP,可以在互联网的任何位置都能访问到
对于一个内网IP,只能在当前互联网内部访问,局域网1的设备,不能使用内网IP访问局域网2的设备。
比如192.168.126.1是我电脑的IP,这个IP只有在我自己家的局域网中才能访问,你们想跨局域网来访问我这个IP是做不到的。
如果我们之间想要通信,这就需要有一个带有外网的IP的机器,比如我们通过QQ这个带有外网IP的,我们都可以访问QQ,
我这里的机器访问QQ然后向你们发送“听我说,谢谢你,因为有你…”
你那边的机器也访问了QQ,然后你们就可以从QQ那里拿到我的消息。
如果没有NAT(如果所有的IP都是唯一的),就可以做到不通过QQ,我直接在我电脑上架设一个聊天服务器,你们直接访问我的IP即可。
NAT机制就是用一个WAN IP,代表一波设备,
换句话说,我们在运营商设备这里,就会修改IP数据包,把从内网发出去的源IP改成外网IP。
带有这样功能的设备,也成为了NAT设备
综上方法2的NAP机制可以极大的解决我们IP不够用的问题,但是NAP也不是无限的啊,
NAP的极限就是端口号的个数65535(我们通过端口号区分不同的主机),
如果一个局域网里的连接数超过了65535,那么我们的NAT就不一定好使了,端口号不够用了
我们接下来介绍从根本上解决IP不够用的方法3:IPv6
IPv6在报头中使用了一个更长的字段来表示IP地址
16个字节,128位
原先IPv4是4个字节32位
看起来好像16字节比4字节也就大了四倍,其实是大了非常非常非常大的倍数,
4个字节是2^ 32,
16个字节是2^ 128,这可是指数级的增长啊。
我们要制作设备需要硅,而硅是从沙子里来的,
我们IPv6号称可以把地球上每一颗沙粒都编号,
沙漠皇帝属于是,恕瑞玛,你们的皇帝回来了
比如我这里的IPv6地址如下
既然IPv6这么香,为啥现在还是在用IPv4+NAT呢?
现在最大问题就是IPv6和IPv4是不兼容的
对于一个设备来说,支持IPv4和IPv6需要完全不同的机制,
现有的大量网络设备(路由器)都很有可能只支持IPv4而不是IPv6,
因此,想要升级到IPv6就得更换设备,可没人愿意出这个钱(IPv4也可以用,谁愿意掏钱呢)
ps:国家目前正在大力推动IPv6进程,以应对现在及将来的国防安全和科技革命,未来还是很有可能大规模实现的
路由选择,就是规划路径,
两个设备之间,要想找出一条通道,能够完成传输的过程,要想找出通道,前提是,得先认识路。
路由表内部的结构并不复杂,但是复杂的是路由表是怎么来的
(有一系列专门的路由表生成算法,也可以手动配置,了解即可,面试不会考察)