TCP/IP 五层协议
前言
最近在极客时间学习刘超老师的趣谈网络协议,对 TCP/IP 有了更深的了解与感触,记录下学习的心得与体会
什么是 TCP/IP 五层协议
TCP/IP 五层协议是在一定程度上参考了 OSI 7层模型 的体系结构,将 OSI 7层模型简化为了五层(也有将链路层和物理层合并后简化为四层的)
五层协议:应(应表会)传网数物
- 应用层:HTTP,FTP 等协议
封装请求正文 - 传输层:TCP/UDP 协议
将端口信息(当前应用监听端口、目标应用监听端口)等封装 - 网络层:ICMP,IP 等协议
封装 IP 地址(当前主机 ip 地址、目标主机 ip 地址) - 数据链路层:以太网等协议
封装 MAC 地址(当前主机的 MAC 地址、网关的 MAC 地址),通过 ARP 协议在局域网广播找到网关后,通过网关发送出去 - 物理层:
将数据转换为二进制,作为电信号发送出去
五层协议中协议有哪些:
物理层
物理层就是网线,中间传输的是光信号
两台电脑通过网线直接连接,就可以组成一个最小的 局域网,即 LAN,Local Area Network
如果多台电脑需要组成一个局域网,就需要一个设备来控制数据传输的目的地和先后顺序,比如交换机
数据链路层
数据链路层包格式:
在数据链路层(MAC 层)需要解决 3 个问题:
- 数据的先后顺序
MAC 层全称 Medium Access Control,即媒体访问控制。控制如何进行 多路访问 - 数据的目的地
这就需要一个物理地址,叫作 链路层地址,也即 MAC 地址 - 发送错误的处理方式
对于以太网,第二层的最后面是 CRC,也就是循环冗余检测。通过 XOR异或 的算法,来计算整个包是否在发送的过程中出现了错误
MAC 地址
MAC 地址更像是身份证,是一个唯一的标识。它的唯一性设计是为了组网的时候,不同的网卡放在一个网络里面的时候,可以不用担心冲突。从硬件角度,保证不同的网卡有不同的标识。
MAC 地址的通信范围比较小,局限在一个子网里面。例如,从 192.168.0.2/24 访问 192.168.0.3/24 是可以用 MAC 地址的。一旦跨子网,即从 192.168.0.2/24 到 192.168.1.2/24,MAC 地址就不行了,需要 IP 地址起作用了
交换机
交换机是二层转发设备,主要作用就是获取到网络包之后,检查包的目标 MAC 头,再根据策略进行转发,避免主机每次都进行广播发送网络包
ARP 协议
当局域网中如果有多台机器,知道目标 IP 地址而不知道 MAC 地址时,就需要使用 ARP 协议来获取。
已知 IP 地址,求 MAC 地址的协议
原理是向局域网发出 ARP 协议进行广播,等待目标主机回应
具体询问和回答的报文:
ARP 表
主机不可能每次都通过 ARP 协议来广播查找 MAC 地址,这样会极大降低效率,所以当主机通过 ARP 协议获取了 MAC 地址之后,就会在本地缓存一个 ARP 表,存储 IP-MAC 的映射。
只有当 ARP 表没有对应的 MAC 地址时,主机才会通过 ARP 协议去获取 MAC 地址并更新 ARP 表
因为主机的 IP 和 MAC 可能会改变,所以 ARP 表是有过期时间的。
RARP 协议
RARP 协议即 Reverse ARP 协议
已知 MAC 地址,求 IP 地址的协议
转发表
当源主机发出了数据报文之后,数据报文其实只知道 MAC 地址,而不知道具体路径,就像你要到一个地方去,但是你不知道如何去一样
当主机通过网线向连接的设备发送请求时
- 设备为 hub 集线器:
hub 集线器是一层设备,只会简单的完全复制,会向所有非源设备广播转发请求,通过其他主机自己来确认数据包是否应该接受 - 设备为交换机:
交换机刚开始也不会知道所有主机的 MAC 地址,但是当 主机 A 发送一个请求到达交换机时,交换机会记录下该请求的主机的 MAC 地址,当有其他请求目标地址为主机 A 时,会只转发给主机A,不再进行广播。
然后过一段时间之后就会记录下局域网下所有主机的 MAC 地址,这个就是 转发表
因为主机的 MAC 可能会改变,所以转发表是有过期时间的。
拓扑结构
当局域网中主机过多,比如办公室场景,可能有几十几百个网口,这时候一个交换机是不够用的,就需要多台交换机,这时候交换机连接起来就是 拓扑结构
当交换机过多时,不可避免的会出现 环路问题,例如下图:
- 当机器 1 发送 ARP 广播寻找机器 2 的 MAC 地址时,交换机 A 和交换机 B 都会收到这个广播,此时,都会记得 机器 1 是在左边这个网口
- 然后都同时向 LAN2 转发这条广播消息,当交换机 A 收到交换机 B 转发的消息时,会发现是机器 1 在寻找机器 2,这时候就会发现机器 1 位于右边这个网口,于是更新自己的记录,将这个消息转发到 LAN1。
- 同理,交换机 B 也会更新自己的记录,然后转发消息到 LAN1
- 然后这个广播请求会来回转发,就会堵塞网络
这时候需要破除环路
STP 协议
STP:Spanning Tree Protocol,是一个生成树的算法,用来破解环路
Root Bridge,也就是根交换机。这个比较容易理解,可以比喻为“掌门”交换机,是某棵树的老大,是掌门,最大的大哥。
Designated Bridges,有的翻译为指定交换机。这个比较难理解,可以想像成一个“小弟”,对于树来说,就是一棵树的树枝。所谓“指定”的意思是,我拜谁做大哥,其他交换机通过这个交换机到达根交换机,也就相当于拜他做了大哥。这里注意是树枝,不是叶子,因为叶子往往是主机。
Bridge Protocol Data Units (BPDU) ,网桥协议数据单元。可以比喻为“相互比较实力”的协议。行走江湖,比的就是武功,拼的就是实力。当两个交换机碰见的时候,也就是相连的时候,就需要互相比一比内力了。BPDU只有掌门能发,已经隶属于某个掌门的交换机只能传达掌门的指示。
Priority Vector,优先级向量。可以比喻为实力 (值越小越牛)。实力是啥?就是一组ID数目,[Root Bridge ID, Root Path Cost, Bridge ID, and Port ID]。为什么这样设计呢?这是因为要看怎么来比实力。先看Root Bridge ID。拿出老大的ID看看,发现掌门一样,那就是师兄弟;再比Root Path Cost,也即我距离我的老大的距离,也就是拿和掌门关系比,看同一个门派内谁和老大关系铁;最后比Bridge ID,比我自己的ID,拿自己的本事比。
STP的工作过程是怎样的?
一开始,江湖纷争,异常混乱。大家都觉得自己是掌门,谁也不服谁。于是,所有的交换机都认为自己是掌门,每个网桥都被分配了一个ID。这个ID里有管理员分配的优先级,当然网络管理员知道哪些交换机贵,哪些交换机好,就会给它们分配高的优先级。这种交换机生下来武功就很高,起步就是乔峰
(图中圆圈内数据代表优先级,线上数字代表传输距离,优先级越小越优先,距离越小越优先)
既然都是掌门,互相都连着网线,就互相发送 BPDU 来比功夫呗。这一比就发现,有人是岳不群,有人是封不平,赢的接着当掌门,输的就只好做小弟了。当掌门的还会继续发 BPDU,而输的人就没有机会了。它们只有在收到掌门发的 BPDU 的时候,转发一下,表示服从命令。
数字表示优先级。就像这个图,5 和 6 碰见了,6 的优先级低,所以乖乖做小弟。于是一个小门派形成,5 是掌门,6 是小弟。其他诸如 1-7、2-8、3-4 这样的小门派,也诞生了。于是江湖出现了很多小的门派,小的门派,接着合并。
合并的过程根据传输距离会出现以下四种情形
情形一:掌门遇到掌门
当 5 碰到了 1,掌门碰见掌门,1 觉得自己是掌门,5 也刚刚跟别人PK完成为掌门。这俩掌门比较功夫,最终 1 胜出。于是输掉的掌门 5 就会率领所有的小弟归顺。结果就是 1 成为大掌门。情形二:同门相遇
同门相遇可以是掌门与自己的小弟相遇,这说明存在“环”了。这个小弟已经通过其他门路拜在你门下,结果你还不认识,就 PK 了一把。结果掌门发现这个小弟功夫不错,不应该级别这么低,就把它招到门下亲自带,那这个小弟就相当于升职了。我们再来看,假如 1 和 6 相遇。6 原来就拜在 1 的门下,只不过 6 的上司是 5,5 的上司是 1。1 发现,6 距离我才只有 2,比从 5 这里过来的 5(=4+1)近多了,那 6 就直接汇报给我吧。于是,5 和 6 分别汇报给 1。
情形三:掌门与其他帮派小弟相遇
小弟拿本帮掌门和这个掌门比较,赢了,这个掌门拜入门来。输了,会拜入新掌门,并且逐渐拉拢和自己连接的兄弟,一起弃暗投明情形四:不同门小弟相遇
各自拿掌门比较,输了的拜入赢的门派,并且逐渐将与自己连接的兄弟弃暗投明。例如,5 和 4 相遇。虽然 4 的武功好于 5,但是 5 的掌门是 1,比 4 牛,于是 4 拜入 5 的门派。后来当 3 和 4 相遇的时候,3 发现 4 已经叛变了,4 说我现在老大是 1,比你牛,要不你也来吧,于是 3 也拜入 1。
VLAN
当交换机过多时,虽然 STP 解决了环路问题,避免了广播风暴,但是在同一个局域网中,总有些数据是想在小黑屋里单独交流的,不希望被人给抓包了。
这时候可以有两个解决方案:
- 物理隔离
交换机隔离,不在同一个拓扑网络下。 - 虚拟隔离 VLAN,也就是常说的虚拟局域网
在同一个交换机上形成多个局域网
交换机如何区分机器属于哪个局域网呢?通过 VLAN ID
VLAN 下的网络结构:
网络层
ICMP 协议
ICMP 协议介于网络层和传输层之间,普遍认为属于网络层,ICMP 通常用于 ping 检测网络连通
ICMP:Internet Control Message Protocol,就是互联网控制报文协议
ICMP 报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为 8,主动请求的应答为 0
报文类型,可以大致分为两类:查询报文 和 差错报文
查询报文
ping 就是使用查询报文的一种
- ping 的主动请求,被称为 ICMP ECHO REQUEST,类型为 8,
- 主动请求的响应,被称为 ICMP ECHO REPLY,类型为 0
比起原生的 ICMP,这里面多了两个字段,一个是标识符,另一个是序号,在选项数据中,ping 还会存放发送请求的时间,来计算响应时间
ping 的收发过程:
- 源主机首先会构建一个 ICMP 请求数据包,ICMP 数据包内包含多个字段。
- 最重要的是两个,第一个是类型字段,对于请求数据包而言该字段为 8;
- 另外一个是顺序号,主要用于区分连续ping的时候发出的多个数据包。每发出一个请求数据包,顺序号会自动加 1。
- 为了能够计算往返时间 RTT,它会在报文的数据部分插入发送时间
差错报文
差错报文的类型为有:
- 终点不可达,类型为 3
- 网络不可达:代码为 0,对方局域网无响应
- 主机不可达:代码为 1,对方局域网响应了,但是找不到这个 ip 对应的主机
- 协议不可达:代码为 2,对方主机响应了,但是对方不接受这个协议
- 端口不可达:代码为 3,对方主机响应了,但是没有程序监听这个端口
- 需要进行分片但设置了不分片:代码为 4,中间某个网关需要对长度进行限制,但是源主机不允许
- 源站抑制:类型为 4,需要源主机放慢发送速度
- 路由重定向:类型为 5,下次发送时发给另一个路由器
- 时间超时:类型为 11,超过网络包生命周期还是未到达目标
差错报文的结构相对复杂一些。除了前面还是 IP,ICMP 的前 8 字节不变,后面则跟上出错的那个 IP 包的 IP 头和 IP 正文的前8 个字节
Traceroute 使用差错报文:
- 故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器
- 故意设置不分片,从而确定路径的 MTU
TTL:Time To Live。最大值为 255。该字段指定IP包被路由器丢弃之前允许通过的最大网段数量,每个路由器要将 TTL 减1,TTL 通常表示被丢弃前经过的路由器的个数。当 TTL 变为 0 时,该路由器丢弃该包,并发送一个 ICMP 包给最初的发送者
网关
网关往往是一个路由器,是一个三层(网络层)转发的设备。
当服务器 A 需要访问服务器 B 时:
- 如果目标 ip 地址是本网段主机,所以直接发给目标主机,封装目标主机的 MAC 地址
- 如果目标 ip 地址是外网主机,则将请求发给网关,封装网关的 MAC 地址
当网关收到了一个请求时
- 取下 MAC 头
- 如果 MAC 头不是本主机,则通过转发表将请求转发到本网段其他主机上
- 如果 MAC 头是本主机,则取下 IP 头,查看目标 IP 地址
- 如果是本主机,则由本主机程序处理
- 如果不是本主机,则查看路由表,查询应该由哪个 LAN 口处理,并封装好下一跳(可能是对应主机,也可能是网关)的 MAC 地址,这时包的 目的 MAC 地址 变为了路由规则匹配的下一跳的 MAC 地址,源 MAC 地址 变为了网关的 MAC 地址
网关分为两种类型:
- 转发网关:不修改目标 IP 地址和源 IP 地址的网关
- NAT(Network Address Translation) 网关:修改目标 IP 地址和源 IP 地址的网关
和路由器的关系
很多情况下,人们把网关就叫作路由器。其实不完全准确,而另一种比喻更加恰当:路由器是一台设备,它有五个 LAN 网口或者网卡,相当于有五只手,分别连着五个局域网。每只手的 IP 地址都和局域网的 IP 地址相同的网段,每只手都是它握住的那个局域网的网关
静态路由
当网关收到一个外网的请求时,就会通过 静态路由 和 动态路由 规则修改 MAC 头(和 IP 头),将包发出去
静态路由,其实就是在路由器上,写死配置一条一条规则。
这些规则包括:想访问 BBS 站(它肯定有个网段),从 2 号口出去,下一跳是 IP2;想访问教学视频站(它也有个自己的网段),从 3 号口出去,下一跳是 IP3,然后保存在路由器里
动态路由
网络环境复杂多变时,静态路由手动修改太麻烦,所以需要动态路由通过一定算法进行自动配置
动态路由算法:
- 链路状态路由(link state routing),基于 Dijkstra 算法
- 距离矢量路由(distance vector routing),基于 Bellman-Ford 算法,只适用于小型网络
动态路由协议:
- 基于链路状态路由算法的 OSPF(Open Shortest Path First,开放式最短路径优先),广泛应用在数据中心中的协议。由于主要用在数据中心内部,用于路由决策,因而称为内部网关协议(Interior Gateway Protocol,简称 IGP)
- 基于距离矢量路由算法的 BGP(Border Gateway Protocol,边界路由协议)
- eBGP:在多个 AS(独立的内部网络,如家庭网络) 之间进行路由交换的协议
- iBGP:在多个 edge touter(AS 面向外界的出口路由器) 之间进行路由交换的协议
传输层
UDP 协议
UDP 协议:数据报协议,不需要接收方确认消息。
特点:面向无连接,无状态,不保证不丢失,不保证到达顺序
- 优点是速度快
- 缺点是可能会丢包
应用场景:
- 流媒体,比如直播
- 实时游戏
- loT物联网
- 移动通信
- 需要低时延的 http 访问
TCP 协议
TCP 协议:流式 stream 协议,通过双向管道传输数据,发送请求之后必须收到确认消息,安全但效率稍低
特点:面向连接,有状态,保证无差错,无重复,并按序到达
- 优点是稳定可靠
- 缺点是速度较慢,需要维护状态机
建立连接:
TCP三次握手:- client 发送管道建立请求(syn)给 server。
- server 同意建立 client 到 server 管道(ack),及管道建立请求(syn)给 client。
- client 同意建立 server 到 client 管道给 server(ack)。TCP 双向管道连接建立成功
断开连接:
TCP四次挥手:- client 发送数据发送完毕并请求断开管道(FIN)给 server。
- server 同意断开管道(ack),client 单向断开管道。
- 数据接收完毕后,server 发送数据接收完毕并请求断开管道(FIN)给 client。
- client 同意断开管道(ack),server 单向断开管道。TCP 双向管道连接断开
握手和挥手整体流程状态图:
- 加粗的实线是客户端 A 的状态变迁,是主要流程
其中阿拉伯数字的序号,是握手过程中的顺序
而大写中文数字的序号,是挥手过程中的顺序 - 加粗的虚线是服务端 B 的状态变迁
- 点线是非主要流程
TCP 状态机
为了实现 TCP 协议的可靠性,TCP 协议规定两端必须实现一个状态机,对每一个发出包与接受包进行记录
TCP 发送方状态机的数据结构:
- 第一部分:发送了并且已经确认的。
- 第二部分:发送了并且尚未确认的。
- 第三部分:没有发送,但是已经等待发送的。
- 第四部分:没有发送,并且暂时还不会发送的。
第三部分和第四部分的区别是,接收方会返回给发送方一个窗口大小,表示接收方处理数据的能力大小,叫 Advertised window,超过这个窗口大小的包,发送方会暂缓发送
- LastByteAcked:第一部分和第二部分的分界线
- LastByteSent:第二部分和第三部分的分界线
- LastByteAcked + AdvertisedWindow:第三部分和第四部分的分界线
TCP 接收方状态机的数据结构:
- 第一部分:接受并且确认过的。
- 第二部分:还没接收,但是马上就能接收的。
- 第三部分:还没接收,也没法接收的。
- LastByteRead:之后是已经接收了,但是还没被应用层读取的;
- NextByteExpected:是第一部分和第二部分的分界线。
- MaxRcvBuffer:最大缓存的量;
累计应答
为了保证顺序性,发送方的包都有一个序号,并且按照序号挨个发送。对于接收方,应答却不是挨个应答,会应答一个序号,表示这个序号之前的包都已收到。
确认与重发机制
因为底层 IP 协议的不可靠性,无法保证网络包的不丢失与按序到达,TCP 协议自己实现了确认与重发机制来保证顺序问题和丢包问题
- 超时重试:对于每一个发送了,但是没有 ACK 的包,都设有一个超时时间,超过时间则重新尝试。
- 超时时间:是 TCP 通过采样 RTT 的时间,然后进行加权平均算出的,这个值是不断变化的。这个算法被称为自适应重传算法
当一个数据包再次超时时,TCP 的策略是超时间隔加倍。每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送 - 快速重传:当接收方收到一个序号大于下一个所期望的序号时,就检测到了数据流中的间隔,于是发送三个冗余的 ACK,发送方收到后就会在超时时间之前提前重传
比如,接收方收到了 6、8、9,发现 7 没来,于是发送三个 6 的 ACK。发送方收到 3 个 ACK 后,就会立刻重传 7 的报文
- 超时时间:是 TCP 通过采样 RTT 的时间,然后进行加权平均算出的,这个值是不断变化的。这个算法被称为自适应重传算法
- Selective Acknowledgment(SACK):这种方式需要在 TCP 头里加一个 SACK 的东西,可以将缓存的地图发送给发送方。例如可以发送 ACK6、SACK8、SACK9,有了地图,发送方一下子就能看出来是 7 丢了
流量控制
- 在每一个包的确认中,都会返回一个 AdvertisedWindow(rwnd) 大小。
- 当接受端处理信息过慢时,这个窗口会一直缩减直到 0,发送方就会停止发送。
- 这时,发送方会定时发送窗口探测数据包,看窗口是否有空余
- 接收方为了避免低能窗口综合征,会在窗口达到一定大小,或者缓冲区一半时才会通知发送方窗口有空余了
拥塞控制
TCP 的拥塞控制就是在不堵塞,不丢包的情况下,尽量发挥带宽
拥塞也是通过窗口来控制,这个窗口被称为 cwnd (Congestion Window),有一个公式 LastByteSent - LastByteAcked <= min {cwnd, rwnd} 共同来控制带宽
如果一个设备如上图所示,只能同时处理 8 个包,如果再调大窗口,就会出现丢包,不想丢包的话就得在中间设备增加缓存,这样就会增加时延
TCP 的拥塞控制就是来避免出现上述问题
BBR 算法
TCP 的拥塞控制有两个问题:
- 丢包不代表通道已满,有可能是管子本身就漏水。例如公网本身就有丢包问题
- TCP 的拥塞控制会等中间设备的缓存都填充满之后才降速
BBR 拥塞算法:企图找到一个平衡点,就是通过不断的加快发送速度,将管道填满,但是不要填满中间设备的缓存,因为这样时延会增加,在这个平衡点可以很好的达到高带宽和低时延的平衡
Socket 接口
因为 TCP/IP 协议过于复杂,如果程序员每开发一个程序都需要自己处理报文的发送与接受等问题,效率太低了,于是由操作系统封装了一套接口,便于快速处理数据包的发送与接受
基于 TCP 协议的 Socket
函数调用过程:
服务端调用 socket 流程:
- 调用 bind 监听 ip 和 端口
- 调用 listen 进入监听状态(监听 socket)
- 调用 accept,当 TCP 连接成功时,accpet 返回另一个 socket(已连接 socket)进行处理
- 和客户端进行通信
重点:监听的 socket 和通信使用的 socket 不相同,一个连接对应一个 socket
客户端调用 socket 流程:
- 调用 connect 连接 ip 和 端口
- 和服务端进行通信
socket 在内核中读写过程:
基于 UDP 协议的 Socket
函数调用过程:
UDP 无连接,所以只需要一个 socket 就可以和多个客户端通信,每次通信的时候都会调用 sendto 和 recvfrom,都可以传入 IP 地址和端口
应用处理 scoket 连接方式
单体应用可以承载的 socket 连接数是有限的,如何在资源有限的情况下,尽可能多的处理连接
- 多进程
- 多线程
- IO 复用(select):一个线程通过 select 轮询的方式检查 socket
- IO 复用(epoll):采用事件通知的方式
应用层
DHCP 协议
DHCP:Dynamic Host Configuration Protocol,动态主机配置协议
因为网络中的每一个主机都需要 ip,而在复杂公共环境下,不可能让管理员来手动给每一个设备分配 ip,所以出现了 DHCP。
DHCP 工作方式:
- 新主机使用 0.0.0.0 向 255.255.255.255 发送 DHCP Discover 广播
- DHCP Server 监听到这个广播,判断如果是新主机的话,通过 DHCP Offer 方式将 ip 池里的随机 ip 发送过去(也是广播形式)
- 新主机发送 DHCP Request 广播数据包,包中包含客户端的 MAC 地址、接受的租约中的 IP 地址、提供此租约的 DHCP 服务器地址等
- DHCP Server 收到 DHCP Request 后,会返回 DHCP ACK 消息包,表明新主机已被加入网络
- 租约达成后,广播通知其他 DHCP Server
HTTP 协议
目前大部分的 HTTP 协议是 1.1,默认开启了 Keep-Alive 的,实现了连接复用
HTTP 请求的报文格式:
请求行
HTTP 请求常用的请求方法:- get
- post
- put
- patch
- delete
首部
常用的 request headers:- Accept-Type
- Content-Type
- Cache-control
- Last-Modified | If-Modified-Since
- Etag | If-None-Match
正文实体
一个完整的 HTTP 请求:
HTTP 2.0
HTTP 2.0 为了尝试解决 HTTP 1.1 的实时性、并发性等问题,进行了以下操作:
- 对头部进行压缩:将每次都携带的 k-v 结构建立索引,每次只发送索引
- 将一个连接切分成多个流
- 将所有传输信息分割为更小的帧:header 帧,data 帧
HTTP 2.0 解决了
- HTTP 1.1 的队首阻塞问题,同时,也不需要通过 HTTP 1.x 的 pipeline 机制用多条TCP连接来实现并行请求与响应;
- 减少了 TCP 连接数对服务器性能的影响,同时将页面的多个数据 css、js、 jpg 等通过一个数据链接进行传输,能够加快页面组件的传输速度
QUIC 协议
因为 HTTP 协议底层是基于 TCP 协议的,严重依赖于包的串行处理,所以 google 出了一个基于 UDP 的 QUIC 协议,尝试解决 HTTP 的一些问题
QUIC 的机制:
- 自定义连接机制
TCP 基于 [源 IP,端口,目的 IP,目的端口] 的四元数组进行连接握手,如果四元数组进行了 wifi 切换等,就会导致重连。
QUIC 以一个 64 位的随机数作为 ID 标识,只要 ID 不变,不需要重新连接 - 自定义重传机制
- 无阻塞的多路复用
- 自定义流量控制
HTTPS 协议
HTTP 协议在网络中由于是明文信息,容易遭到恶意份子的篡改,所以有了 TLS 协议对其进行加密,保证内容安全。
HTTP + TLS = HTTPS
TLS 加密原理:首先使用非对称加密协商出公钥,然后再使用这个公钥对内容进行对称加密
- 对称加密:公钥机制,由公钥加密的内容也能由公钥解开
- 非对称加密:公私钥机制,只有对应的私钥才能解开公钥加密的内容。服务端公钥的正确性由 CA 证书来保证
DNS 协议
在正常的用户上网过程中,用户是不可能能记住每一个网站的 ip 地址的,而且 ip 地址经常会因为 NAT、负载均衡等问题发生改变,这时候我们需要一个方便记忆 ip 的方法,DNS 协议就是当用户使用某个域名(比如 baidu.com)时,获取域名对应的 ip 地址的协议
已知域名,求 IP 的协议
DNS 服务器结构:
DNS 递归查询过程:
DNS 负载均衡:
HTTPDNS 协议
传统 DNS 存在以下问题:
- 域名缓存:缓存是为了降低递归查询的次数,提高查询效率。
但是带来的问题是- 服务器地址更改后没有及时刷新缓存,导致访问失败
- 客户端地址更改后导致全局负载均衡失败,缓存的并不是最优服务器地址
- 域名转发:权威域名服务器的负载均衡会根据运营商的不同返回不同的服务器地址,但是域名查询由 A 运营商转发给 B 运营商查询,就会导致运营商判断错误
- 出口 NAT:NAT 会导致权威域名服务器判断运营商错误
- 域名更新:IP 更新后重新解析 DNS 会导致一定时间的延迟乃至服务不可用
- 解析延迟:DNS 查询需要递归遍历多个 DNS 服务器,延迟较高
HTTPDNS 就是不走传统的 DNS 解析,而是应用自己搭建基于 HTTP 协议的 DNS 服务器集群,分布在多个地点和多个运营商。当客户端需要 DNS 解析的时候,直接通过 HTTP 协议进行请求这个服务器集群,得到就近的地址