最核心的就是 IP 协议,是一个相当复杂的协议
TCP 详细展开讲解,是因为 TCP 确实在开发中非常关键,经常用到,IP 则不同,和普通程序猿联系比较浅。和专门开发网络的程序猿联系比较紧密(开发路由器,开发交换机,开发防火墙…)
网络层的 IP 协议,主要干两个事:
实际上只有两个取值
4
==> IPv4
(主流)6
==> IPv6
IPv2
,IPv5
在实际中是没有的,可能是理论上/实验室中存在
IP 协议报头也是变长的,因为选项个数不确定,所以报头长度也不确定。因此就需要使用 4 位首部长度进行区分
4 位首部长度范围:0~15,所以报头长度 *4
才是实际的长度
15*4=60
type of service
3位优先权字段(已经弃⽤),4位 TOS
字段,和 1位保留字段(必须置为 0)。4位 TOS
分别表⽰:
IP 数据报的长度
UDP 也是 16 位(2 个字节,64KB
)。但并非 IP 协议报头最多能携带的数据就是 64KB
IP 协议内置了拆包组包机制,单个 IP 数据报确实没法超过 64KB
,但是不代表 IP 协议不能传输超过 64KB
的数据。IP 协议会自动把大的数据包,拆成多个 IP 数据报携带传输,在接收方再进行拼装
装修的时候,装柜子/床,进不了电梯,也进不了房门,怎么办?
IP 协议会自动拆包,统一个载荷的数据,会被分成多分,交给多个 IP 数据报来携带。多个 IP 数据包之间:
最后组包的时候,根据 16 位标识 确定哪些数据包放在一组,然后根据 13位片偏移 决定顺序,最后根据 3位标志位 决定是不是最后一个
如果就是想使用 UDP 实现传输找过 64KB 的数据,该怎么做呢?
描述了一个数据包在网络上存活的最长时间
TTL
就是约定了一个传输时间的上限,当达到上限之后,数据包就会被自动丢弃掉
s
或者 min
,而是次数(经过路由器转发的次数)发送一个 IP 数据报的时候,会有一个初识的 TTL
的值(32,64,128…)。数据包每次经过一个路由器转发,TTL
就会 -1
(经过交换机不减)。一旦 TTL
减到 0
了,此时这个数据包就会被当前的路由器直接丢弃掉
ping命令
:用来检测网络的连通性
64
这样的TTL
够用吗?
64
这样的 TTL
是非常充裕的 128
这样的 TTL
IP 数据包中,携带的载荷,是哪种传输层协议的数据包
通过这里的不同数值,感知到接下来要把数据给 TCP 解析,还是 UDP 解析,还是其他协议解析
具体的数值这里不谈,这里暂时只聊作用
验证数据在传输中是否出错(只是针对首部,IP 报头)
TCP/UDP
都有自己的校验和,此处就不需要再次进行验证了IP 数据报中最关键的信息:数据包从哪里来,到哪里去
ipconfig
,就可以看到当前机器的 ip 地址 0-255
(只要有一个部分不在这个范围,就可以认为是一个非法/错误的 IP)IP 地址,用来标识网络上的一个设备。期望 IP 地址是唯一的
就是为了解决 IP 不够用的问题
一个设备上网就分配 IP,不上网就先不分配(权宜之计)
网络地址转换
以一当千,使用一个 IP,代表一大波设备
NAT 把 IP 地址分为两大类:
10.*
172.16~172.31.*
192.168.*
要求公网 IP 必须是唯一的,但是私网 IP 在不同的局域网中是允许重复的
NAT 网络地址转换
一个设备在进行上网的时候,IP 数据报中的 IP 地址,就会被 NAT 设备(通常就是路由器)进行自动修改
之前写
UDP
回服务器的时候,我这台电脑上启动UDP
服务器,你使用UDP
客户端是不能访问的
NAT
机制下,一个局域网中的主机 A 是无法访问领一个主机但凡是搭建一个服务器给别人使用,都是需要公网 IP 的
CCtalk
这个服务器,就要构造一个 IP 数据报NAT
设备)之后,就会进行网络地址转换 CCtalk
看到的数据包,源 IP 不是 192.168.111.222
,而是 1.2.3.4
为什么进行这样的 IP 地址的替换就能提高 IP 地址的利用率呢?
运营商的公网 IP,不是服务一个设备,而是服务一个片区,可能有上万个设备。此时一个 IP 就代表了上万个设备,此时 IP 的利用率就大大提高了
CCtalk 的响应如何正确地返回到我的电脑上呢?
NAT
设备能在发出和收回的时候都进行 IP 替换,就能使内网设备和外网设备进行连接在网络通信中,不仅仅只有 IP 信息,还有一个关键的是端口号
旧 IP | 旧端口 | 新 IP | 新端口 | |
---|---|---|---|---|
192.168.111.222 | 1234 | 1.2.3.4 | 1234 | |
192.168.333.444 | 1235 | 1.2.3.4 | 1235 |
返回数据包的时候
1234
,就是传给我1235
,就是传给你此处就是通过端口号,来区分不同主机的不同程序
是否可能出现:你和我的电脑上 CCtalk 源端口恰好是一样的?
NAT
既能替换 IP
中的 IP
,也能替换 TCP/UDP
中的端口。这个就是 NAPT
我们当前的网络世界,主要就是 NAT
机制的支撑
从根本上解决了 IP 地址不够用的问题
IPv4
使用 32 位 4 个字节表示 IP 地址IPv6
使用 128 位 16 个字节表示 IP 地址
16 个字节表示的 IP 地址数目,比 4 个字节的 IP 地址大:。这个地址空间非常大,大到可以给地球上的每一粒沙子都分配一个唯一的 IPv6
地址
IPv6 提出的时间是在上个世纪 90 年代,时间上和 NAT 其实是差不多的。之所以 IPv6 举步维艰,因为 IPv6 和 IPv4 不兼容!
IPv6
,就要更换新的设备(能支持 IPv6 的设备)IPv6
提出的当年,显然是不具备这样的条件的。换设备就得花钱,但花钱了网速又不会变快(用户感知不到好处)
NAT 机制,只要给路由器设备更新升级软件即可,硬件不需要改变(成本非常低)组网的时候,就需要我们针对每个上网设备 IP 地址(包括路由器的 IP)进行设置
我没设置过,好像插上网线就能上网,这是为什么呢? 对于家庭网络这种比较简单的网络结构来说,路由器都有“自动分配 IP”的功能(
DHCP
)。但在公司、学校、商场、宾馆… 这些更复杂的场景,网络需求更复杂,就需要进行手动设置了。
IP 地址,32 位整数,一分为二
子网掩码也是 32 位整数。左半部分都是 1
,右半部分都是 0
(二进制数)
255.255.0.0
就是 11111111.11111111.00000000.00000000
10.61
就是网络号,15.237
就是主机号网络中规定:
在这个局域网中,某个设备号不相同的话,就无法上网;某个设备的网络号虽然相同,但主机号和别的设备重复,也无法上网
路由器上有两种网络接口:
LAN
口WAN
口此时这个路由器就连接了两个局域网。这两个局域网的 IP 网络号是不能重复的。一旦重复,也上不了网 同一个路由器连接的两个局域网,就叫相邻局域网
LAN
口接设备(你的电脑、电视…),WAN
口接上层路由器
0.0.0.0
~127.255.255.255
128.0.0.0
~191.255.255.255
192.0.0.0
~223.255.255.255
224.0.0.0
~239.255.255.255
240.0.0.0
~247.255.255.255
此时这个 IP 就是表示当前网段(相当于网络号) 因此,给局域网中的某个设备分配 IP 地址的时候,不能把主机号全设为 0
比如子网掩码为 255.255.255.0
,IP 地址为 192.169.0.255
。这里我们可以看到,IP 地址前三个字节为网络号,后一个字节 255
为主机号(11111111
)
主机号为 11111111
就是广播 IP,往这个 IP 地址上发送数据包,就相当与给整个局域网中所有设备都发了一次数据包(针对一个局域网中的对象)。我们很多看到的“业务上的广播”,都是通过应用层编写代码来实现的,而不是借助广播 IP
以 CCtalk 为例,CCtalk 会维护出很多的“教室信息”,你上课的时候就是在其中一个教室,一个教室会涉及到很多同学(教室数据中就包含所有同学的数据)。此时,老师进行直播的时候,老师那边的画面和声音就会发送给 CCtalk 服务器对应的教室那里,CCtalk 服务器就会根据教室中同学的列表,依次遍历每个列表元素,把数据发送出去 机房上课、地震预警大概率都是这样的实现原理
什么时候是真用到广播 IP?(手机,电视投屏)
手机上如何知道局域网中有多少设备允许投屏,这样的功能就可以基于广播 IP 实现
127.*
自发自收,给这个 IP 发送一个数据,设备就会从这个 IP 上再收到同一个数据(自己发给自己)
你踢球的时候,自己射门又自己补射(自射自补)
使用环回 IP 一般进行测试。写的网络程序,大多数情况都是为了跨主机通信。但在此之前,往往需要先自行测试,一台测试客户端和服务器之间能否正常交互
一般使用的环回 IP 是
127.0.0.1
,虽然其他的127
开头的 IP 也是可以的,但是很少见
网络是复杂的网状结构,从一个节点到另一个节点之间,可能会存在很多条线路(交通网)
你想从北京去上海,你打开高德地图,会给你提供很多条路线让你选择
你想从陕科大去邮电大学
每次在进行问路的时候,每个人都是没法知道西安市的完整地图详细信息的,只能知道其中的一部分信息。但他能给我指出一个方向,我按照这个方向走,就会越来越接近,当足够接近的时候,总是可以遇到一个人能告诉我精确目标地点的。
这就和 IP 协议路由选择非常相似。
hash
,key
就相当于 IP 地址(网络号),value
就是对应的网络接口(往哪个方向走)真是的转发过程,会更加复杂