网络概览
讲了一些网络的基本概念, 没什么干货
应用层
用于传达数据
web
http1
- http1.0是短连接, 每次请求都要建立连接
- http1.1是可持续链接, 一个连接可以发送多个请求(流水线)
虽然http1.1可以发送多个请求, 但是每个请求还是要等待上一个请求的返回, 不能并行发送请求, 就会有队头阻塞的问题, 意味着后面的请求要等待前面的请求返回后才能发送, 如果前面的请求非常耗时, 那么后面的请求就卡在那里了
http2
- 二进制分帧, 因为这个技术才有了多路复用, 这个就是流的概念, 一个tcp链接中有多个流, 每个流有自己的id, 一个流就是一个请求, 每个流有不同的优先级
- 成帧是指将数据分割成多个帧(frames),每个帧携带特定类型的信息。HTTP/2 中的帧是传输数据的基本单位,帧可以包含 HTTP 头部信息、数据负载、控制信息等。帧有不同的类型,例如:
- HEADERS 帧:用于传输 HTTP 头部。
- DATA 帧:用于传输实际数据负载。
- PRIORITY 帧:用于传输优先级信息。
- SETTINGS 帧:用于传输配置信息。
- 成帧是指将数据分割成多个帧(frames),每个帧携带特定类型的信息。HTTP/2 中的帧是传输数据的基本单位,帧可以包含 HTTP 头部信息、数据负载、控制信息等。帧有不同的类型,例如:
- 响应报文的优先级
- 服务器推送
http2 从http层面解决了队头阻塞的问题, 但是在传输层面还是有队头阻塞的问题, 因为http2是基于tcp的, 而tcp是有队头阻塞的问题的. 所以QUIC是基于udp的, 也就是说QUIC是基于http2的, 但是QUIC是基于udp的, 所以QUIC是没有队头阻塞的问题的
DNS
DNS的请求过程分为没有缓存和有缓存的, 一般来说讲没有缓存的会清楚一点
没有缓存的DNS请求
- 本地DNS服务器向根DNS服务器请求
- 根DNS服务器返回顶级域DNS服务器的地址
- 本地DNS服务器向顶级域DNS服务器请求
- 顶级域DNS服务器返回权威DNS服务器的地址
- 本地DNS服务器向权威DNS服务器请求
- 权威DNS服务器返回域名对应的IP地址
- 本地DNS服务器将IP地址返回给用户
有缓存的DNS请求
其中有浏览器缓存, 操作系统缓存, 本地DNS服务器缓存, 还有中间DNS服务器缓存, 每一个被命中的话, 就都会立刻返回.
视频流
http流
Youtube用的就是这种, 由用户选择码率.
DASH流(Dynamic Adaptive Streaming over HTTP)
Netflix用的就是这种, 由服务器选择码率.
CDN
一般传输视频都要使用CDN, 有时候CDN会根据用户的地理位置选择最近的服务器, 有时候会根据用户的网络情况选择最快的服务器.
有了CDN后的DNS请求过程是
- 本地DNS服务器向根DNS服务器请求
- 根DNS服务器返回CDN的域的主机名(一般是域名)
- 本地DNS服务器向CDN的域的主机名请求
- CDN的域的主机名返回CDN的一台主机的IP地址
- 用户请求这个IP地址
运输层
这一层存在的意义是保证数据的传输安全
同时运输层也有多路复用和多路分解, 因为传输的是一根线, 但不同应用是不同端口, 所以要有多路复用和多路分解
UDP
UDP的数据包格式在这里有阐述, 里面有校验和, 别的就都没有了, 只能判断出来数据包是否损坏, 不能判断出来数据包的顺序是否正确, 也不能判断出来数据包是否丢失
可靠数据传输
- 流水线
- 滑动窗口
- 快速交付, 窗口过去的就可以交付到应用层
- 回退N步(GBN)
- 必须按照顺序来接收数据包, 如果不按照顺序来接收数据包, 那么就会丢弃这个数据包
- 比如说接收到了1, 2, 3, 5, 6, 7, 那么就会丢弃5, 6, 7, 然后重发5, 6, 7
- 选择重传(SR)
- 可以接收乱序的数据包, 但是只能接收一次, 如果重复接收, 那么就会丢弃这个数据包
- 比如说在一个窗口内有4块数据包, SR会记录哪些是被接收的, 哪些是没有被接收的, 如果没有被接收, 那么就会重发这个数据包
TCP
tcp结合了GBN和SR的优点, 既可以接收乱序的数据包, 又可以重发数据包.
SYN Flood 攻击
SYN Flood攻击是一种DoS攻击, 攻击者向服务器发送大量的SYN包, 服务器会为每一个SYN包分配一个资源, 但是不会为这个资源分配一个线程, 所以服务器会很快耗尽资源, 无法再接受新的连接, 我觉得这也是nmap扫描的原理, 但是nmap扫描是为了获取服务器的信息, 而SYN Flood攻击是为了耗尽服务器的资源.
解决方法是SYN Cookies:
- 收到 SYN 包:当服务器收到一个 SYN 包时,不分配资源,也不在半连接队列中记录状态。
- 计算 syncookie:服务器根据客户端的 SYN 包内容(如客户端的初始序列号和其他TCP头部信息)以及一个秘密的服务器密钥计算一个加密的值,称为 syncookie。
- 发送 SYN-ACK 包:服务器在 SYN-ACK 包中使用这个 syncookie 作为初始序列号(seq),并发送回客户端。
- 收到 ACK 包:当服务器收到客户端的 ACK 包时,服务器通过解码 ACK 包中的序列号,检查这个序列号是否与预期的 syncookie 匹配。如果匹配,说明这是一个合法的连接请求。
我当初看的时候有一个困惑, 就是为什么要用cookies记录状态, 后来我才发现, 你就算不用cookies记录状态, 服务器在分配资源的时候也会记录客户端发来的seq, 来确保下一个数据包是不是和上一个数据包是同一个连接.
拥塞控制
- 慢启动
- 一开始发送的数据包很少, 然后每次收到一个ACK包, 就会增加发送的数据包的数量
- 拥塞避免
- 一旦发送的数据包的数量超过了一个阈值, 就会减少发送的数据包的数量, 每次加1
- 快速重传
- 如果发送的数据包超时了, 就会重发这个数据包
- 不要等待自己发送数据时进行捎带确认, 而是立即发送确认
- 已经收到失序的数据包也要重复确认
- 收到三个重复的ACK包, 立即重传
- 如果发送的数据包超时了, 就会重发这个数据包
- 快速恢复
- 一旦收到三个重复的ACK包, 就会减少发送的数据包的数量, 但是不会减少到慢启动的阈值, 而是减少到慢启动的阈值的一半, 然后进入拥塞避免