网络原理 - 8
目录
补充
网络层
IP 协议
基本概念:
协议头格式
地址管理
如何解决 IP 地址不够用呢???
1. 动态分配 IP 地址:
2. NAT 机制(网络地址映射)
3. IPv6
网段划分
一些特殊的 IP 地址
路由选择
完!
补充
上篇文章我们介绍了一些 TCP 中一些核心的机制特性~~~
TCP 特点:有连接,可靠传输,面向字节流,全双工
UDP 特点:无连接,不可靠传输,面向数据报,全双工
应用场景:如果需要可靠传输,当然首选 TCP,如果需要传输的数据包很大,也首选 TCP。即,绝大部分的场景,都可以优先考虑 TCP~~ UDP 相比于 TCP,最大的有点是传输效率,比如有的场景中,对于效率要求很高,但是对可靠性要求不高,就可以优先选择 UDP~~
有些情况,既对可靠性有要求,又对性能有要求,那选择 TCP 还是 UDP 呢???(比如一些竞技类游戏~~~) ==》此时 TCP 和 UDP 就都不是很合适了,实际上,大佬们还发明了一些其他的协议,来解决上面的问题 ==》 KCP 协议(TCP 是高可靠性,低效率。UDP 是无可靠性,高效率。 KCP 是低可靠性,较高效率~~)
UDP 是不可靠传输的,那如何使用 UDP 来实现可靠传输呢???(经典面试题~~~)
其实,这道题实际考察的是 TCP~~~ UDP 本身是不可靠的,要想使用 UDP 还可靠,就需要成需要自己在应用程写代码,实现可靠传输~~~ 即 TCP 内核保证可靠性是怎么实现的,我们成需要就可以在应用代码中自己实现。
网络层
IP 协议
IP 协议,主要完成的工作,是两方面:
1. 地址管理,使用一套地址体系(即 IP 地址),来描述互联网上每个设备所处的位置~~(注意:不仅仅是电脑 / 手机,路由器,服务器等等,也会有 IP 地址~~~)
2. 路由选择,即,一个数据包,如何从网络中的某个地址,传输到另一个地址,也就是说,在复杂的网络环境中,为数据包确定一个合适的路径。
基本概念:
主机:配有 IP 地址,但是不进行路由控制的设备。
路由器:既配有 IP 地址,又能进行路由控制
结点:主机和路由器的统称
协议头格式
理解协议头中的各个概念:
4 位版本号(version):取值只有两种,4 和 6,指定 IP 协议的版本,4 就是 IPv4(当前主流的 IP 协议版本),6 就是 IPv6(下一代版本)
4 位首部长度(header length):IP 头部的长度是多少个 32bit(4 字节),也就是 length * 4 的字节数,4 位表示的最大的数字是 15,因此 IP 头部最大长度是 60 字节,即 IP 报头也是可变长的~
8 位服务类型(type of service):8 位中,有3 位是优先权字段(如今已经弃用),4 位 TOS 字段,和 1 位保留字段(必须置为 0),4 为 TOS 分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。注意,这四位是互相冲突的,只能选择其中的一个~~~(最高可靠性:IP 并非像是 TCP 一样,提供了很多机制来提供强可靠性,但是内部也是有一些考虑来能够减少丢包的概率~~)
16 位总长度(total length):IP 数据报整体占多少个字节。即,描述了一个 IP 数据报的长度(包含 报头 + 载荷)。看到这个 16 位总长度,我们会想到,64 KB 的限制~~~
那是否就意味着,IP 协议的载荷也就只能长度有限了呢???如果构造一个非常大的 TCP 数据,IP 是否就无法进行传输呢???
虽然 IP 自身有长度限制,但是 IP 也提供了拆包 / 组包 这样的功能。此时,载荷就可以搞一个很大的,超过 64KB 也没关系,在 IP 这一层会自动拆成很多个 IP 数据报,每个 IP 数据报来携带载荷的一部分~~
例如:构造如下图一样,一个很大的,超过 64KB 的 TCP 数据报
一个 IP 数据包无法全部放入,就会进行拆分:
将一个大的 TCP 数据报,分成多个 IP 数据报,携带一个 TCP 数据~
上述的拆包过程,都是 IP(系统内核)自动完成的,程序员没办法通过软件代码干涉到~~~
IP 的拆包其实也并不是因为 64KB 大小的限制,在数据链路层还有限制~~
拆包之后,未来该如何组装呢???(就比如,我们要进行搬家,将能组装的家具,先拆成零件进行运输,等到达新家之后,再重新组装起来~~)
16位标识(id):唯一的标识主机发送的报文。如果 IP 报文在数据链路层被分片了,那么每一一个片里面的这个 id 都是相同的~~ 即,说明了那些 IP 数据报的载荷应该往一起组装~~
3位标志:第一位保留(保留的意思是现在不用,但是还没想好,以后说不定要用~~)第二位,如果为1,就表示禁止分片,如果这个时候报文的长度超过 MTU,IP 模块就会丢弃报文。第三位,表示“更多分片”,如果分片了的话,最后一个分片置为 1,其他是 0,类似是一个结束标志~~
13 位分片偏移(framegament ):是分片相对于原始 IP 报文开始处的偏移,其实就是表示当前分片在原报文中的那个位置。实际偏移的字节数就是这个值 * 8 得到的。因此,除了最后一个报文之外,其他报文的长度必须是 8 的整数倍(否则报文就不连续了)
8位生存时间(TTL):这里的单位并不是 s / ms,而是“次数”,这里存储的是一个整数,一个 IP 数据报,每次经过一个路由器转发,TTL 就 -1。当这个数据减到 0 了,此时就说明数据包要被丢包了~~~ 一般来说 TTL 值为 32 / 64。
这个机制是防止某个数据在网络上被无限的转发下去(防止路由循环)~~
比如说,如果指定的 IP 地址,是一个错误的 IP 地址,此时,就不能让这个数据包无限的被找下去,找到一定程度还没有找到,就应该放弃了~~
8位协议:表示在传输层中使用那个协议~
16 位头部校验和:使用 CRC 针对 IP 数据包的首部进行校验,载荷部分就不管了。(载荷部分中的 TCP / UDP 其中的协议都自带了校验和~~)
32 位源 IP 地址 和 32 位目的 IP 地址:表示了发送端的地址和接收端的地址~~
地址管理
IP 地址本质上就是一个 32 位整数(int),为了方便,我们会把 IP 表示成 点分十进制的方式,通过三个点分成四部分,每个部分 1 字节,每个部分的取值都是 0 - 255。
IP 地址的存在,目的就是为了能够区分网络上的不同设备,希望每个网络设备上都有唯一的一个 IP 地址~~
32 位的整数,能表示的数据范围,是 2^32 ==> 42 亿 9 千万 ==》 看起来非常大,但是在现在万物互连的时代,这个数字似乎还有些不够用~~
如何解决 IP 地址不够用呢???
1. 动态分配 IP 地址:
全世界的设备,也不是同一时刻都在一起上网,我们就可以动态的进行分配,充分的利用现有的 IP。
2. NAT 机制(网络地址映射)
我们可以对 IP 地址分成两个大类 ==》 私网 IP 地址 / 局域网 IP 地址 和 公网 IP 地址 / 广域网 IP 地址
如果一个组织内部组建局域网,IP 地址只用于局域网内的通信,而不直接连到 Internet 上,理论上,使用任意的 IP 地址都是可以的~~~ RFC 1918 规定了用于组建局域网的私有 IP 地址:
10.* and 172.16 - 172.31 and 192.168.*
包含在上面的范围中的,都是私有 IP,其余的称为 全局 IP
要求:公网上的设备,对应的公网 IP,都必须是唯一的,但是私网上的设备,谁用私网 IP,只要保证局域网内部的 IP 不重复即可,不同的局域网之间的 IP 允许重复。
- 公网设备访问公网设备,没有问题,可以直接访问
- 同一个局域网中,局域网设备访问局域网设备,也没有问题,可以直接访问
- 不同局域网中,局域网设备访问局域网设备,不允许访问
- 局域网设备访问公网设备,就需要对局域网设备的 IP 进行地址转换
- 共网设备访问局域网设备,不允许主动访问
- 一个路由器可以配置两个 IP 地址,一个是 WAN 口 IP(公网 IP),一个是 LAN 口 IP(子网 IP)。路由器的核心作用,就是把这两个局域网给连接起来
- 路由器 LAN 口连接的主机,都是从属于当前这个路由器的子网中
- 不同的路由器,子网 IP 其实都是一样的(通常都是 192.168.1.1),子网内的主机 IP 地址不能重复,但是子网之间的 IP 地址就可以重复了~
- 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点,这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN 口 IP 就是一个公网 IP 了
- 子网内的主机需要和外网进行通信的时候,路由器就将 IP 首部中的 IP 地址进行替换(替换成 WAN 口 IP),这样逐级替换,最终数据包中的 IP 地址称为一个公网 IP
大概模型如下图所示:(此处简化模型,只考虑主机经过一个路由器,把数据转入公网,最终到达了服务器,中间构建的路由器所作的事情比较复杂,此处暂不关注~~)
假设我们的电脑 IP 为 192.168.2.10 像 公网服务器(IP 地址为 1.2.3.4)发送请求,数据包先到达路由器。路由器启动 NAT 功能,将数据包中的源 IP 地址(私有地址 192.168.2.10)转换为路由器的公网 IP 地址,并记录转换映射关系。转换后的数据包继续发往公网服务器。
公网服务器收到请求后做出响应,将响应数据包发回给路由器的公网 IP。路由器依据之前记录的 NAT 映射关系,把数据包中的目的 IP 地址(路由器的公网 IP)转换回我的电脑的私有 IP 地址(192.168.2.10),再将数据包发送给我的电脑,从而实现了内外网的通信过程~~
大概过程如下:
当这个数据包到达服务器之后,服务器看到的 IP 就是 5.6.7.8,感知不到之前的局域网的 IP
上面路由器中的地址修改,也并不是每个路由器都会替换,局域网中的路由器会替换,一旦这个数据包源 IP 成为公网 IP,就不会再进行替换了~~
进行了上述的替换操作,本质上就是让一个公网 IP 能够对应到多个设备,从而起到节省 IP 地址的效果~~
两台主机(网络拓扑结构):
路由器进行 NAT 的时候,就会把这次通信的相关信息记录下来,将这个通信过程中的,替换之前的 IP,替换之后的 IP,服务器 IP,源端口,目的端口...
服务器返回响应的时候,源 IP 和 目的 IP 就就和请求是反过来的了:
然后经过路由器,路由器再根据具体的端口,根据 NAT 表找到对应的替换前的 IP 和 端口~
客户端的端口号,一般都是系统随机分配的,两个主机之间的端口,大概率是不会相同的~~
但,万一,正好局域网中的某两台设备,分配的端口号相同,此时也不要慌,路由器会对端口号进行映射~~
例如: 此时两个局域网中 IP 不同的设备,源端口号相同
路由器会自动的进行映射,当服务器返回的时候,再重新进行对应~
大部分情况下,局域网中的不同设备,访问的是不同网站,这个时候直接通过服务器 IP 就能区分,其次情况,如果访问的是同一个服务器,就可以按照端口号来区分,再极少数情况下,碰巧访问的是同一个服务器,并且端口号相同,就可以在路由器这边自动映射成不同的端口号了,仍然能够进行区分~
3. IPv6
IPv4 使用 4 个字节表示 IP 地址 ==》 2^32 42亿9千万~~
IPv6 使用 16 个字节表示 IP 地址 ==》 2^128 == 》 天文数字~~~
但 IPv6 的报头结构和 IPv4 是不兼容的~~~ 引入 IPv6 就意味着当前网络通信(路由器不支持)就需要更换支持 IPv6 的设备 ==》 花钱!!!
网段划分
IP 地址分为两个部分,网络号和主机号
网络号:保证相互连接的两个网段具有不同的标识
主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号~~
不同的子网,其实就是把网络号相同的主机放到一起
如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号要保持一致,但是主机号必须不能和子网中的其他主机重复
通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的 IP 地址都不相同
那么问题来了,我们平时上网,也并没有配置呀,都是插好网线就 ok 了~~(手动管理子网内的 IP,是一个相当麻烦的事情)
有一种技术叫做 DHCP,能够自动的给子网内新增的主机节点分配 IP 地址,避免了手动管理 IP 的不便~
过去也曾经提出过一种划分网络号和主机号的方案,把所有的 IP 地址分为五类
随着网络的迅速发展,上面的划分方案的局限性很快显示出来,大多数组织均使用 B 类网络地址,导致 B 类地址很快就分配完了,而 A 类(24 位主机号,一般局域网没有这么多主机)却浪费了大量的 IP 地址。
针对这种情况,提出了心的划分方案,CIDR(Classless Interdomain Routing)
引入一个额外的子网掩码(subnet mask)来区分网络号和主机号,子网掩码也是一个 32 位的正整数(一般也以点分十进制标识),将 IP 地址和子网掩码进行”按位与“的操作,得到的结果就是网络号。
表示方法:使用斜线符号( / )标识网络前缀的长度,如 192.168.1.0/24,其中 192.168.1 是网络前缀,24 表示网络前缀占 32 位 IP 地址中的前 24 位,子网掩码为 255.255.255.0,剩余的 8 位用于标识主机,可分配 256 个主机地址(一般家用宽带的子网掩码都是 255.255.255.0,剩余 256 个地址足够家里的联网设备使用~~)
一些特殊的 IP 地址
将 IP 地址中的主机地址全部设为 0,就成为了网络号,代表这个局域网,也就不能够分配给某个主机了。
将 IP 地址中的主机地址全部设为 1,就成为了广播地址,用于给同一个链路中相同连接的所有主机发送数据包(广播地址)(注意,在广播地址上发消息,局域网中的所有设备都能收到,但一定要发 UDP 的消息,TCP 是不支持广播的~)
127.* 的 IP 地址用于本机环回(loop back)测试,通常是 127.0.0.1,即表示字节本机(我们当时回显服务器的时候,传入的 IP 就是 127.0.0.1)
路由选择
网络的具体结构是十分复杂的,每个路由器都无法掌握全局的信息,只能掌握一部分的局部信息,此时路由器规划出来的路线,只能是一个”较优解“~~(也就是一种 探索式 / 启发式 / 渐进式的路线规划,无法在最开始就找到”最优解“路线,确定好,而是”走着看“~~)
路由的过程,是”一跳一跳“的”问路“的过程。所谓”一跳“,就是数据链路层中的一个区间,具体在以太网中指从源 MAC 地址到目的 MAC 地址之间的帧传输区间
IP 数据包的传输和问路一样
当 IP 数据包,到达路由器的时候,路由器会先查看目的 IP,路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器,依次反复,一直到达目的 IP 地址