Merge pull request #97 from BaiMeow/master

加强速通章节,添加IP协议章节
This commit is contained in:
camera-2018
2023-08-03 01:45:09 +08:00
committed by GitHub
6 changed files with 271 additions and 4 deletions

View File

@@ -661,8 +661,12 @@ export function chapter9() {
text: '9.计算机网络',
collapsed: false,
items: [
{ text: '9.计算机网络', link: '/9.计算机网络/9.计算机网络' },
{ text: '9 计算机网络', link: '/9.计算机网络/9.计算机网络' },
{ text: '9.1 计网速通', link: '/9.计算机网络/9.1计网速通' },
{ text: '9.2.1 物理层' },
{ text: '9.2.2 链路层' },
{ text: '9.2.3 网络层' , link: '/9.计算机网络/9.2.3网络层'},
{ text: '9.2.3.1 IP 协议', link: '/9.计算机网络/9.2.3.1IP协议' },
]
}
]

View File

@@ -277,6 +277,67 @@ TLS 建立在 TCP 的基础上,他会通过加密来确保传输过程中数
| RDP | 3389 | 默认UDP |
| Redis | 6379 | TCP |
## 公网与内网 --- 真实环境分析
基本的内容介绍的差不多了,下面分析一个简单的网络案例,顺带介绍公网和内网的概念。
相信在看这篇文章的大家都正在使用互联网如果你正在使用windows设备你可以先按 `win`+`R` ,输入 `cmd`,在弹出的窗口输入 `ipconfig` 你可以看到里面有一串类似于下文的内容:
```
无线局域网适配器 WLAN:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::4835:c258:e07d:acc3%24
IPv4 地址 . . . . . . . . . . . . : 192.168.0.109
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.0.1
```
IPv4 地址一栏有一个形似 `192.168.XXX.XXX`的地址,这是一个典型的内网地址,类似的还有很多,比如说
- 192.168.0.0 - 192.168.255.255
- 10.0.0.0 - 10.255.255.255
- 172.16.0.0 - 172.31.255.255
看到以上任意一个都是非常合情合理的,虽然还有其他内网地址,但是那些都比较冷门,可能一辈子碰不到,不用记忆。
因此,除了上面列出的 IP 地址,请将他们一律视为公网地址,公网地址是独一无二的,绝对的,内网地址在不同的子网里可以重复使用,是相对的。
此外下面还有子网掩码和默认网关,掩码会在后续的内容中介绍,现在知道你只需要知道:
- 上面显示的 `IPv4 地址` 是你这台设备的 IP 地址
- 家庭和寝室网络子网掩码默认 `255.255.255.0`
- 默认网关是路由器在内网的 IP你的设备需要路由器的帮助将数据包从内网转发到公网
此刻你可能会有一个疑问作为一台联网的计算机设备我可以把数据发送到公网的服务器上因为我知道他的公网IP而且这是独一无二的只要我联网互联网上的路由设备会尽力帮我把数据送到地方。
### 但是,返回的数据该怎么办?
显然,对面不可能把数据包发给一个内网地址,他只有发给一个公网地址,互联网上的路由设备才知道他要去哪,才能帮他将数据送到地方。
问题的答案很简单,我们的路由器,他通过 PPPoE 拨号的方式向运营商拿到了一个公网IP。他在把数据包转发到互联网上前做了一个网络地址转换的操作把数据包的源地址替换成了他的公网IP再找了一个随机端口号在那里将修改后的数据发送到公网**这个转换的操作会被路由器记录**。
这样公网上的服务器在收到数据包后也能知道这个包来自于哪个公网IP的哪个端口回复的时候就知道发到什么地方了。
路由器拿到公网上的服务器回复的数据包后,可以根据做网络地址转换时的记录,逆向推导出他应该将包发送到内网的哪台机器的哪个端口,就完成了数据的收发。
绝大多数的家庭或者寝室网络都遵循着这个规则。
### 那为什么要这么做呢?
对于一般家庭网络,有两个简单的理由
- 安全,只有你主动连接才能拿到回复,互联网上的设备无法主动访问你的设备
- IPv4 不够用啦
### 其他特殊IP地址
- 127.0.0.1 本机,用于自己的设备给自己的设备另一个端口发送数据
- 169.254.x.x 保留地址,向路由器获取内网地址前会临时使用这个地址,如果你发现你的电脑正在使用这个地址,路由器可能坏了
- 198.18.x.x 保留地址但是有些软件会使用这个地址来实现透明代理tun
好,我们的计网速通章节,到此结束,这些计算机网络知识应该足够你做简单的 Web 开发了
## 参考资料
- HTTP 教程 <https://www.runoob.com/http/http-tutorial.html>

View File

@@ -0,0 +1,185 @@
# IP协议
> Author: 柏喵樱
>
> copyright reserved
## IP 协议数据包结构
IP 协议是网络层最主要的协议几乎所有的上层数据包都需要IP协议的承载我们网络层的第一块内容将从 IP 协议讲起。
下图展示了 IP 协议的报文头部格式,这张图每行代表 32 个 bit也就是 4 个字节byte。如果不计算 Options 这种可选项的话IP 协议的报头长度为 20 个字节。
在头部的后面会携带负载payload这个词可能略显晦涩但实际上就是我们需要发送的数据。
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Example Internet Datagram Header
</pre>
## 版本
第一个字段是IP协议版本号用于标识IPv4和IPv6两个版本这两个版本的报文格式是不同的。上图展示的是 IPv4 的报文格式
## IHLInternet Header Length
就是IP协议的头部部分的长度单位是 4byte由于 IP 头一般长度为 20byte所以这个值一般为 5。如果存在Options字段这个值会相应增加。
## Type of Service
服务类型,标记服务类型最初是为了对不同服务的数据包做不同的转发策略,比如说哪些数据包应该被优先转发,应该更注重转发延时还是更注重吞吐量一类的问题,除非到运营商层面一般接触不太到。
## 数据包总长度
Total Length 很好理解就是包括 IP 头在内的 IP 报文的总长度,报文长度上限就是 MTU。
## Identification & Flags & Fragment Offset
这三个字段放在一起讲,他们都是用于控制分片的。
我们的 MTU 他一般是 1500去除 20 bytes 的头部他还能够携带 1480 bytes 的数据,但是现实中的负载很容易就能够超出这个大小,这时候就需要将内容切片分块发送。
切片时,会切出许多 1480 bytes 的切片,和剩下的不足 1480 bytes 的部分。对于以上的所有切片,都会给他们加一个自己的 IP 头。这些 IP 头有一个共同点,就是他们具有一个相同的 Identification 用于识别identify他们原先是一块的。
现在还存在两个问题,
1. 服务器接收到一个分片后,不知道要不要继续接收
2. 分片很有可能乱序抵达,服务器不知道分片的顺序
对于第二个问题,引入了 Fragment Offset分片偏移量他的单位是 byte用于标识这一个分片的数据是从原来超长负载的哪个位置开始的。比如对于一个长度为 5000 bytes 的负载,他的几个分片的 Fragment Offset 依次为 0,1480,2960,4440。在收到数据后服务器只需要按照这个字段重新组装即可。
对于第一个问题,引入了 Flags标志位, Flags 里有三个 Flag其中最后一位的意义是“后面还有更多分片“这就相当于告诉服务器你要继续等待接收其他分片。而当最后的分片抵达时服务器在知道这是最后的分片的同时他也能从这个分片的 Fragment Offset里得知前面应该有多少数据如果缺失服务器也能继续等待接收。
关于Flags的其他两位最高位是目前保留不使用永远为0。后面那位的意义是不要分片这一般是不设置的他这句话是对传输过程中的路由设备讲的因为如果途径 MTU 低于当前包长度的链路可能会进行二次分片。如果设置了这个 Flag转发时再碰到 MTU 低的链路这种包会被直接丢弃同时返回一个 ICMP 包告诉源IP地址的设备发生了什么。
## TTL(Time To Live)
TTL 是一个unsigned int代表数据包的剩余生存时间指的是数据包在互联网中还能转发多少时间单位是秒。
虽然单位是秒,但是一般情况下转发耗时是远远低于一秒的,根据 IP 协议的规定无论转发耗时多少TTL 应当至少 -1所以在实践中 TTL 往往指的是转发了几次。
一般发往互联网的数据包初始 TTL 为 64 或 128你可以试试 ping 命令他会显示一个TTL这是对面服务器回复的包到自己的设备的时候的 TTL。
```powershell
PS C:\Users\bs> ping baidu.com
正在 Ping baidu.com [39.156.66.10] 具有 32 字节的数据:
来自 39.156.66.10 的回复: 字节=32 时间=43ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=144ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=43ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=42ms TTL=47
39.156.66.10 Ping 统计信息:
数据包: 已发送 = 4已接收 = 4丢失 = 0 (0% 丢失)
往返行程的估计时间(以毫秒为单位):
最短 = 42ms最长 = 144ms平均 = 68ms
```
TTL 减少到 0 的时候这个数据包会被丢弃所以如果互联网中出现路由配置错误以至于产生了一个环TTL 能够帮助数据包及时停止转发,避免事故扩大最终导致网络设施瘫痪。
当路由设备由于 TTL 为 0而丢弃这个数据包的时候路由设备还会向源 IP 回复一个 `TTL超时`的 ICMP 报文
```powershell
PS C:\Users\bs> ping baidu.com -i 2
正在 Ping baidu.com [39.156.66.10] 具有 32 字节的数据:
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
39.156.66.10 Ping 统计信息:
数据包: 已发送 = 4已接收 = 4丢失 = 0 (0% 丢失)
```
traceroute 就是利用这个性质来实现的,通过从 0 开始遍历 TTL 的方式,可以拿到转发过程中的所有路由器的 ICMP 回复,从这些回复中可以读取到这些路由器的 IP。
当然 traceroute 不是万能的,真实互联网中广泛存在拦截,不响应 ,改写等等行为,会导致 traceroute 产生丢失或者藏跳等等比较迷惑的结果。
```powershell
PS C:\Users\bs> TRACERT.EXE bilibili.com
通过最多 30 个跃点跟踪
bilibili.com [8.134.50.24] 的路由:
1 8 ms 13 ms 2 ms 192.168.0.1 [192.168.0.1]
2 1 ms 1 ms 2 ms 192.168.1.1 [192.168.1.1]
3 8 ms 8 ms * 100.66.0.1
4 * * * 请求超时
5 * * * 请求超时
6 * * * 请求超时
7 * * * 请求超时
8 * * 8 ms 61.139.121.77
9 * * * 请求超时
10 78 ms * * 113.96.5.134
11 * 83 ms 43 ms 121.14.50.241
12 45 ms 42 ms 41 ms 121.14.24.82
13 * * * 请求超时
14 * * * 请求超时
15 * * * 请求超时
16 * * * 请求超时
17 42 ms 50 ms 40 ms 8.134.50.24
跟踪完成
```
上面就是一个真实案例,有很多路由设备在丢弃数据包时并没有给出 ICMP 回复。
## 协议
协议Protocol指的是负载中的数据所使用的协议。这就很广泛了比如
- TCP
- UDP
- ICMP
- Telnet
- OSPF
具体可以参考 [List of IP protocol numbers - Wikipedia](https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers)
## 头部校验和
头部校验和Header Checksum用于检验传输的数据是否出错一旦出错直接丢弃。
在计算头部的校验和的时候,头部校验和这个字段会被置零,再使用特定算法计算得到校验和,填写到这个位置。
这个校验和算法比较简单,就是头部以 16 bits 为单位,取补码再求和
注意,由于 TTL 在每次转发中都会改变,所以实际上,每次转发都会重新计算校验和。
## IP地址
正如上图的 `Source Address``Destination Address` 字段所展示的一样,一个 IP 地址占用 4 byte 的存储空间。在书面的写法上,我们用 `.` 将每一个 byte 分割开,例如 `1.1.1.1` 这样更便于人类处理和分类。
有一些 IP 地址被用作特殊用途,除了这些 IP 地址外的地址都是公网 IP一个公网 IP 在整个互联网范围内按照规范来说只能由一台网络设备占有也有例外anycast。但互联网是复杂的也有人占用这些地址作为自己的内网地址例如 tr069这个由网络运维人员自行分析情景把握。
网络地址的分类需要更多的前置知识,我们后续再介绍。
## 可选项
可选参数Options比较繁琐一般没啥用有兴趣的可以看看下面参考资料中 RFC 791 对此的描述。
## 参考资料
- [RFC 791 - Internet Protocol (ietf.org)](https://datatracker.ietf.org/doc/html/rfc791)
- [Reserved IP addresses - Wikipedia](https://en.wikipedia.org/wiki/Reserved_IP_addresses)
- [List of IP protocol numbers - Wikipedia](https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers)

View File

@@ -0,0 +1,18 @@
# 9.2.3 网络层
> Author: 柏喵樱
>
> copyright reserved
本章节是网络层的开篇章节,我们先做两个约定:
- 没有提及IP协议版本都是IPv4 IPv6 会单独介绍不详细展开)
- 路由表已经配置好了给IP地址就能发到正确的地方路由技术参照“路由与交换”章节
以上两个约定适用于所有网络层章节。
在链路层我们已经实现了两个直接相连的设备之间的数据收发,也可以在总线类型的网络上完成数据手法,更成熟一点,可以借助交换机来构建一个具有一定规模的中心化网络。
但中心化是有极限的这必然无法承载这个整个互联网因此我们需要再往上一层定义一个新的概念IP 地址,并完成实现数据包的转发操作,将互联网推向去中心化。

View File

@@ -1 +0,0 @@
# 9.2计网基础

View File

@@ -95,7 +95,7 @@
链路层 ---> 数据帧/MAC/CRC
链路层 ---> PPP
链路层 ---> ARP
网络层 ---> IP地址
网络层 ---> IP 协议
网络层 ---> 子网/掩码/CIDR
网络层 ---> IPv6概述
传输层 ---> 端口