IP的作用
上一篇文章提到TCP的可靠传输机制,那么TCP有把数据从主机A到主机B的能力吗?答案是没有。而IP有这个能力,IP能够将数据从主机A跨网络传输到主机B的能力。那么一定能传输成功吗?答案肯定是否定的,会因为各种原因导致传输失败。而这就又要依赖到TCP的可靠性,一旦发生丢包变会进行重传(网络正常的情况)。 所以,IP有把把数据从主机A到主机B的能力,而TCP则是保证IP一定能传输成功。
打个比方,张三是校长的儿子,校长说张三每次考试都必须考100分。而张三大部分考试也都是考100分,可是有一次却突然考了99。这时候校长就不乐意了,校长要求必须每次考100分,所以就让考试重考。如果还没拿到100分就继续重考!直到张三拿到100分为止! 这里面的校长冲当的就是TCP的角色,进行决策。而张三冲当IP的角色,进行行动。重考这个过程对应的是TCP的可靠机制。校长要确保张三每次都能考到100分,而TCP也要确保IP的数据一定能传输成功。 所以TCP和IP合起来,就能保证数据从一台主机到另一台主机!这也就是为什么叫做TCP/IP网络模型的原因。
而在传输数据的过程中,目标IP也非常重要,决定了我们的路径如何走。而IP也分为2部分,前面部分是网络号,后面部分是主机号。
**IP = 网络号 + 主机号 **
IP的报头
介绍了IP之后,我们再来看看IP的报头。
4位版本: IP协议版本,IPV4或者IPV6,两者不兼容。
4位首部长度: 和TCP报头的四位首部长度一致,4位首部长度 * 4 = 报头总大小。报头基础长度20字节,所以四位首部长度默认为5。
**8位服务类型:**3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位 TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于 ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要.
16位总长度: IP报文整体占多少字节。
第二行下面再说,关于IP的分片和组装。
8位生存时间: 报文跳转次数,达到一定次数后对报文直接丢弃。
8位协议: 报文需要向上交付,需要知道交付给哪一层协议,UDP还是TCP还是?
16位首部校验和: 检验报头字段是否正确。
32位源IP地址: 发送端的IP地址,该地址是会变化的。
32位目的IP地址: 接收端的IP地址,该地址一样会发生变化。
IP的分片与组装
根据数据链路层的MAC帧协议,自己的报头 + 有效载荷是不能超过1500字节的(MTU,可以随意修改)。
但是IP能决定单个报文的大小吗?答案是不能!因为单个报文的大小的是由TCP决定的!因为发送多少数据是由TCP决定的!一般来说,TCP报文是不会超过1500字节的。但是为了以防万一,IP层还是出了一个分片与组装的策略。用来解决万一TCP层发送的数据超了的问题。
如何分片 && 如何组装
分片分片,就是把报文分成多个去发送,要理解如何分片,我们可以从下面几个角度去理解。不过在此之前,我们需要先将IP报文中第二行未讲解的部分进行补充。
3位标志位,这个3位标志位中的第一个比特位是保留位。第二个比特位则是是否禁止分片,为1则是禁止分片,如果此时报文大小超过1500则直接丢弃报文。第三个比特位则是"更多分片"位,为1则说明后面还有分片,为0则说明后面没有分片了。
16位标识则是标识报文的唯一性。
13位片偏移则是当前报文的有效载荷在原报文的偏移量是多少。
1. 你怎么知道一个报文被分片了?
很简单,如果13位片偏移量 = 0 , 并且给更多分片标志位被置为0。则说明这是一个完整的报文,否则则是被分片过。
2. 如何识别同一个报文的所有分片?
16位标识是标识报文的唯一性,而报文被分片后,16位标识都是一样的。所以通过找到相同的16位标识的报文就相当于找到了该报文的分片。
3. 哪一个分片是第一个分片,哪一个分片是最后一个分片,有没有收全或者丢失?
当片偏移量为0的时候,那么可以说明这是第一个报文,如果此时的"更多分片"标志位为1,则说明后面还有分片,那么当前分片就是第一个分片。 最后一个分片报文因为后面没有分片了,所以它的"更多分片"标志位为0,并且片偏移量一定大于0。那么此时这个分片报文就是最后一个分片。
有没有收全或者丢失?
我们只需要把这些分片报文根据片偏移排序,然后根据当前报文的有效载荷 + 自己的片偏移量 = 下一个分片的片偏移。 来判断是否有分片丢失
4. 哪一个在前,哪一个在后,如何按正确顺序进行组装
我们的分片是在IP层进行的,那么对端收到分片后组装,也一定是在IP层进行的!这是网络分层的特点!谁分片谁就来组装。 在第3点我们提到过如何判断分片是否丢失,也对所有分片进行了排序。而接下来把所有分片的IP报头取出来接在前一个报文后面即可。因为已经排好序了,所以可以直接接在后面进行组装。
IP分片全过程
首先我们的IP原报文总共大小3000字节,有效载荷为2980字节。
随后进行第一次分片,我们只需要把前1500字节取出即可。并设置片偏移为0,更多分片标志位为1。
随后我们对1500字节加上20的IP报头,因为分片报文每次发送时也必须携带IP报头。加上报头后总大小1520字节,继续取1500字节。并设置片偏移为1500,更多分片标志位为1。
随后我们对剩余的20字节有效载荷继续加上一个IP报文,最后总大小40字节。因为后面没有分片了,所以该IP报文的更多分片标志位为0,片偏移为2980(上一个分片的有效载荷 + 上一个分片的片偏移)。
至此我们的IP分片就完成了。组装只需要把所有16位标识相同的报文进行升序排序,随后去掉IP报头拼接即可。如果中间有分片缺失则直接丢弃所有分片。
不建议使用分片
为什么不建议使用分片?有以下几点。
1. 提高了丢包率
假如我们1个报文的丢包率是99%, 那么我们分片成10份发送,那么我们的丢包率将近10%。丢失一个分片,就相当于整个报文丢失。
2. 效率问题
每次分片都要进行分片和组装的过程,尤其是组装的过程,还需要对分片报文进行排序。所以效率也会受到一定影响。
…
网段划分
IP地址分为两部分,网络号 + 主机号。
网络号: 保证相互连接的两个网段具有不同的标识。
主机号: 同一网段内的主机必须要有不同的主机号。
为什么要有子网划分?
举个例子:
你们学校有个校学生会的群,里面有计算机学院学生会主席,法学院学生会主席…等其他学院的学生会主席。这时候你捡到了一个钱包,钱包里面有1W大洋。但是只有失主的学号信息,这时候你捡到了这个钱包。你能否根据学号判断失主是否是你们计算机学院的?当然可以!但如果不是计算机学院的,你就不知道失主是哪个学院的了。所以这时候你把钱包交给了你们计算机学院的主席。这个计算机学院主席一看这个学号,这不是经管学院的人吗?于是在校学生会的群里艾特经管学院的学生会主席,说他们学院XXX学号的学生钱包掉了。让他赶紧联系一下失主。于是经管学院拿到学号一看,还真是经管学院的。然后再看后面的编号,这不是李四的学号吗?(实际上可能还要专业,班级…继续划分,这里简略一下。)于是就去联系李四。
所以,每一个学号其实就是一个IP地址!每个学生被归类到一个学院。这个学院就是网络号!
每一个学生隶属于一个学院,而每一台主机也一定隶属于一个子网!
为什么要隶属于每一个子网?
我们可以通过学号快速定位到一个学生,所以隶属到每一个子网,也是为了快速定位到这台主机!这样排除效率非常的高。
如何进行子网划分
我们都知道IP地址是一个32位比特位,我们可以用前8位来表示国家,次八位表示省份…。直到最后的主机号
当然,思想是这么个思想,但是方案绝对不是这种方案,因为这样划分IP地址是不够用的!
所以,我们使用的IP地址是被设计过的
上面说的只是一个理念版的网络划分,而具体的网络划分会在下面讲解。
DHCP技术(网段划分)
路由器至少要桥接两个子网,所以路由器是被桥接的所有子网所共享的。而因为路由器自己本身也是一台主机,所以路由器也要有自己的IP地址,一般路由器的IP通常是网络标识.1。
在一个子网中,管理子网内IP的设备就是路由器!在我们的手机或者电脑没有联网时,其实是没有IP地址的。而当我们连上WIFI时,就自动有了IP地址。这个地址是由路由器动态分配的,这种技术就是DHCP。
特殊的IP地址
将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数 据包;
127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
NAT技术(网段划分)
我们都知道IP地址其实是不够用的,因为IP地址是一个32位的无符号整数。也就是最多也只有42亿多。如果每台主机都要安排一个IP地址,那么IP地址是远远不够的。为了解决IP地址不够用的情况,就有了NAT技术的诞生。当然该技术也是治标不治本,真正治本的还得是普及IPV6协议。
而路由器不仅仅可以进行数据包转发,还可以自建局域网(动态分配的IP就是在该局域网内)。而局域网内的地址是不直接连接到公网的。理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组件局域网的私有IP地址。
10.*,前8位是网络号,共16,777,216个地址 *
172.16.到172.31.,前12位是网络号,共1,048,576个地址
192.168.,前16位是网络号,共65,536个地址 包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公网IP);
这也就是为什么我们经常查自己的IP时,都是这三个开头的原因了。因为我们的主机其实是处于在一个局域网中,此时我们的IP地址也被称为内网IP(私网IP)。在不同局域网内,内网IP是可以相同的。
一般来说,一个路由器都会配置2个IP地址,一个是WAN口IP(对外),一个是LAN口IP(对内,子网IP)。当我们要发送的数据报不在当前居于内时,会把数据报内的源IP地址替换成当前路由器的WAN口IP 。 然后交付给上一层路由器,因为你当前的路由器也可能是另一个路由器的子网。直到有一个路由器的WAN口IP为公网IP,此时这个路由器也被称之为公网入口。此时报文的源目的IP就是这个公网入口的WAN口IP,随后就是上面学生会的那一套逻辑,找到报文中目的IP所处的公网IP地址处。这就是我们的私网IP -> 目的IP的过程。那么目的的公网IP,怎么回到你这个私网IP呢?这个后面再说。