网络层
网络层主要做的事情:
1.路径规划(路由器选择)
2.地址管理
IP协议
1)4位版本
指定IP协议的版本, 4 => ipv4 , 6 => ipv6
2)4位首部长度
4位bit能表示0-15, 单位也是4字节, 所以IP报头最长60字节, 最短20字节
3)8位服务类型(TOS)
type of service, 3位优先权字段(已经弃⽤), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最⼩延时, 最⼤吞吐量, 最⾼可靠性, 最⼩成本. 这四者相互冲突, 只能选择⼀个.只能有一个置为0
- 16位总长度
整个IP数据包的长度, 报头 + 载荷, 最大64KB
但是TCP协议是不限制数据包大小的, 所以IP自身实现了拆包组包这样的功能, 如果携带的载荷超出长度上限, IP就会自动拆分成多个数据包, 每个数据包携带一部分, 发送到对方之后, 再拼接好
(IP并不关心传输的内容是啥应该怎么分, 只是粗暴地分成多份)
IP数据包会根据上述三个属性进行拆包组包
16位标识: 用来区分哪些数据包要合并, 用来区分哪些数据包是一组的
3位标志位: 只有两个位有效
一个用来表示, 该数据包是否触发了拆包, 是否需要组包
另一个用来表示, 结束标记, 当前包就是最后一个需要组包的部分
13位片偏移: 若干个要拼接数据包的先后顺序
6)8位生存时间(TTL)
IP数据包要在网络上转发, 但是转发的次数是受限的
一个IP数据包, 初始情况下, 有一个TTL的值(32/64/128…这样的整数)
这个次数每经过一个路由器的转发, 就要 -1, 减到0, 这个数据包就会被丢弃
7)8位协议
这里就描述了载荷部分, 是哪种协议的数据包, 再分用的时候, 要交给上层的哪个协议, 都是有明确声明的
传输层 => 应用层: 端口号区分
网络层 => 传输层: 报头中有这个 8位协议 字段, 不同的取值就对应不同的传输层协议
数据链路层 => 网络层: 报头中的类型字段, 用来区分是IP数据包, 还是其他的
8)16位首部校验和
只针对IP首部进行校验, 载荷部分不关心
9)
一个IP地址, 是一个32位的整数, 能表示的范围是 0-42亿6千万
NAT机制
原则上来说, 不同的设备, IP地址应该是唯一的, 显然这个数字, 在移动互联网的时代, 是不够用的
IP地址不够有, 有两个方案:
方案一: 动态分配IP地址
某个设备, 上网就分配IP, 不上网就不分配IP
这样的办法, 没法从根本上解决问题
方案二: NAT机制, 网络地址映射
首先, 把IP地址, 分成两大类:
公网IP(广域网使用的) 和 私网IP(局域网内部使用的)
私网IP:
10.*
172.16-172.31.*
192.168.*
私网IP允许在不同的局域网中重复, 但公网IP是唯一的
那么设备之间的通信就分成了下述几种情况:
1)同一个局域网内部, 设备之间通信
由于一个局域网内部设备之间的IP是不能重复的, 此时这些数倍都能正常相互交互
2)广域网设备和广域网设备之间通信
要求广域网中的设备IP本身就是唯一的
3)局域网1中的设备A尝试访问局域网2中的设备B
这种情况是不允许访问的!!
如果需要进行上述操作, 往往需要搭配广域网中的服务器, 进行数据转发
4)广域网设备主动访问局域网设备
这种情况是不允许访问的!!
5)局域网中的设备主动访问广域网设备
这个过程中, NAT机制就开始发挥作用了
(我们为了简化过程, 省去了中间结点)
此时的运营商路由器, 就可以认为是一个NAT设备, 它就会对中间经过的数据包, 进行网络地址转换
当内网设备经过运营商路由器访问外网的时候, 就会把IP数据包中的源IP, 替换成他自己的IP
目的就是让自己的外网IP, 取代之间的内网IP
此时这个数据包到达cctalk服务器之后, cctalk就会看到一个5.6.7.8这样的设备给他发的一个请求, 但是cctalk对于我的电脑的内网ip,是一无所知的
这样的一个运营商路由器, 一般是按片区的, 这个运营商服务器的局域网中的几千台内网设备, 都是通过同一个外网IP, 在公网上进行传输的
你的电脑插到哪个路由器上, 你的私网IP就是由哪个路由器给你分配的
我们上网上搜索IP查询, 查到的就是你公网ip地址, 就是你运营商服务器的ip地址
现在cctalk服务器要返回给我相应的数据, 此时cctalk构造的数据包:
这个数据包就会返回给运营商路由器
在运营商路由器内部, 维护了一个"映射关系"
记录当前这个对应的请求时从哪个内网设备发过来的
从而把目的IP替换回最初的内网IP
查询到结果后, 就把IP和端口替换过来了
如果此时, 我们家的另一台电脑B也要访问cctalk(和我的电脑A同一个运营商路由器)
此时路由器就会将私网IP改成公网IP
此时站在cctalk的角度, 虽然这两个数据包来自同一个IP, 但是是不同的端口号, 就能够根据端口号来区分要把数据交给哪个客户端
cctalk返回的数据包:
这时在运营商路由器中, 就会维护这样的表:
此时, 运营商根据表, 就能找到私网IP
这样, 数据就能找到对应的主机啦
如果碰巧A和B的cctalk端口号相同, 那么运营商就会在映射表中将端口号也进行修改, 修改成唯一的端口号, 为了让服务器进行区分
注意: 中间结点的路由器, 有可能也是没有公网IP的, 但是也可以NAT, 直到找到有公网IP的路由器, 才能访问服务器
我们的私网IP, 是路由器提供的, 路由器有一个功能DHCP, 可以分配IP地址
NAT机制, 一个公网ip就可以表示很多个主机, 一定程度上解决了IP不够用问题
但是, 也并未从根本上解决问题
方案三:ipv6
ipv6引入了更长的字节数来表示IP地址, 用16个字节, 128位来记录
可以表示的范围就超级超级大了
足以给地球上每一粒傻子分配唯一一个IP!!!
但是, 我们当前的版本ipv4和ipv6不兼容!!!
我们大家用的路由器, 交换机, 网卡…各种设备, 都支持ipv4
如果要升级成ipv6, 就要更换所有的设备
况且ipv6从来没有使用过, 存在一定的风险
谁都不愿意花钱冒险!!