1. 输入网址,会发生什么
第一步: 浏览器输入一个url,第一步解析url,得到发送给web的请求信息,主要是得到web服务器和文件名
第二步: 利用DNS解析器,根据web域名得到对应的IP地址
第三步: 得到IP后,协议栈就会开始进行HTTP的传输工作;首先就是TCP三次握手,建立连接;给http请求加tcp头部信息。生成TCP报文,头部中有两个端口号
第四步: 利用IP协议给TCP报文封装成网络包。ip头部中有两个ip地址。
第五步: 网络包还需要在头部加MAC头部,用于点到点之间的传输。(利用ARP协议,以广播形式在以太网中找到对应ip的MAC地址)
第六步: 经过以上的数据包装,得到了mac头部、ip头部、tcp头部、http请求组成的网络包。此时就是将这个二进制数据包转换为电信号,就可以真正在网线上传输了。网卡驱动会在网络包头部加上报头和起始帧分界符,末尾加上校验序列FCS。
第七步: 交换机将网络包转发至目的地,在mac地址表中查找目的MAC地址,找到对应端口,然后转发
第八步: 路由器收到网络包后,检查MAC地址,如果是自己的,那就接受数据包,否则丢弃。然后去掉数据包中的mac头部信息,根据ip头部信息进行转发。所以MAC头部只是为了将包送达到路由器,根据路由表查询转发目标。
第九步: 根据路由器的转发,到达目标主机,主机层层解析,然后得到http请求。然后回应发送http响应报文。又层层加头部信息进行发送。
所以,整个发送过程中,两个IP是不会变的,只有MAC地址会在层层转发中不断变化。
1. 静态路由和动态路由
-
静态路由是由系统管理员设计与构建的路由表规定的路由。适用于网关数量有限的场合,且网络拓朴结构不经常变化的网络。其缺点是不能动态地适用网络状况的变化,当网络状况变化后必须由网络管理员修改路由表。
-
动态路由是由路由选择协议而动态构建的,路由协议之间通过交换各自所拥有的路由信息实时更新路由表的内容。动态路由可以自动学习网络的拓朴结构,并更新路由表。其缺点是路由广播更新信息将占据大量的网络带宽。
3. UDP
UDP只提供了复用分用、差错检测功能
特点:
- 无连接的,减少了开销和延迟
- 最大努力交付,不保证可靠交付
- 面向报文,适合传输少量的数据的应用
- 无拥塞控制,适合实时应用
- 首部开销少
首部格式:源端口号、目的端口号;UDP长度(用户数据报长度),UDP检验和;数据字段
**如何基于 UDP 协议实现可靠传输?**
常规做法就是再UDP协议上加可靠传输机制,例如TCP的序列号、拥塞控制,流量控制,确认号,重传机制等等。将UDP包装成TCP,但这样没有意义,不如直接使用TCP。TCP连接本身就存在缺点,连接建立有时间延迟,因为字节流,存在对头阻塞,网络迁移需要重新建立连接。因此将UDP实现可靠连接的同时,需要解决这几个问题——QUIC协议
可靠传输:首先明确,QUIC也需要三次握手进行连接,但这是为了商量出连接ID,存储在packet header中,有了连接ID,后续传输只需要依据该ID即可,可就解决了TCP网络迁移时需要重新建立连接的问题,QUIC迁移后只需要采取原本的连接ID即可。还有一个packet number,类似于TCP中的syn,不过这个num,在重发packet时,也会+1,TCP重发报文段syn会保持一致。因为,RTO超时时间根据RTT决定的,RTT是每次都会记录的,但TCP对于重发报文段的RTT计算存在歧义,到底是第一次发的开始记录,还是记录重发的,存在很多问题,因此QUIC这里重发packet的num也不同,计算的RTT就不会出现差错。支持乱序确认,也就*解决了TCP对头堵塞问题*,重发的packet因为num不同,也会发送并接受。一个 Packet 报文中可以存放多个 QUIC Frame。每个frame又有类型,类型不同,功能不同,例如Stream类型的Frame格式,其中有个Offset,类似于tcp中的报文syn序列号,保证数据的可靠性 。之前知道packet num控制严格递增,那数据有序性怎么保证呢?-通过stream id+offset实现数据有序性,这两个字段一直,就说明数据是相同的。
QUIC 通过单向递增的 Packet Number,配合 Stream ID 与 Offset 字段信息,可以支持乱序确认而不影响数据包的正确组装,
解决队头阻塞:HTTP/2抽象出stream概念,实现http并发传输,一个stream就代表一个请求和响应。QUIC 给每一个 Stream 都分配了一个独立的滑动窗口,这样使得一个连接上的多个 Stream 之间没有依赖关系,都是相互独立的,各自控制的滑动窗口。
流量控制: QUIC 是基于 UDP 传输的,而 UDP 没有流量控制,因此 QUIC 实现了自己的流量控制机制,QUIC 的滑动窗口滑动的条件跟 TCP 有一点差别,但是同一个 Stream 的数据也是要保证顺序的,不然无法实现可靠传输,因此同一个 Stream 的数据包丢失了,也会造成窗口无法滑动。QUIC 的 每个 Stream 都有各自的滑动窗口,不同 Stream 互相独立,队头的 Stream A 被阻塞后,不妨碍 StreamB、C的读取。
- Stream 级别的流量控制:Stream 可以认为就是一条 HTTP 请求,每个 Stream 都有独立的滑动窗口,所以每个 Stream 都可以做流量控制,防止单个 Stream 消耗连接(Connection)的全部接收缓冲。与TCP的流量控制区别是,tcp会要保证有序收到后才能够移动缓冲指针。而QUIC不用等待,即使前面有部分缺失数据,只看最大偏移字节数,也就是收到的哪个字节,接受窗口就移动到那,不管前面是否收到。当已被上层应用接受的数据超过最大接收窗口的一半后,最大接收窗口向右移动,接收窗口的右边界也向右扩展,同时给对端发送「窗口更新帧」,当发送方收到接收方的窗口更新帧后,发送窗口的右边界也会往右扩展,以此达到窗口滑动的效果。
- Connection 流量控制:限制连接中所有 Stream 相加起来的总字节数,防止发送方超过连接的缓冲容量。
拥塞控制:慢开始-拥塞避免-快重传-快恢复;而改进快主要是因为QUIC是应用层的,可以随着软件步段更新,而TCP是传输层协议,需要网络协议栈支持,因此更新成本很高。
4.TCP
- 面向连接的,传输层协议
- 端到端服务
- 可靠交付:无差错、不丢失、不重复、按序到达
- 双工通信(发送缓存、接收缓存)
- 面向字节流-把数据看作一连串的无结构字节流
首部格式:

- 源端口号、目的端口号
- 序号:tcp传送字节流,每一个字节都按顺序编号,序列号表示本报文段发出的数据中第一个字节的序号
- 确认号:期望收到对方下一个报文段的序号号
- 数据偏移(首部长度):报文段数据起始处距离头部的距离
- 6个控制位:紧急位URG-报文段中有紧急数据,不应该再缓冲区排队,需要尽快发送;确认位ACK-回复收到的报文的,连接后所有报文段都要设置;推送位PSH-提醒接收方尽快交付数据,不再等接受缓冲区满了再交付;复位RST-本次tcp连接出现差错,需要释放连接,重新建立连接;同步位SYN-表示一个请求连接报文;终值位FIN:数据已发送完,要求释放连接
- 窗口:发送方的接受缓冲区,提醒另一方注意发送的数据量大小
- 检验和:检验首部和数据
- 紧急指针:配合URG,指出紧急数据的字节数
- 选项:MSS,时间戳等等
TCP协议的三次握手建立连接过程
客户端(2023)给服务器(1031)发送TCP报文段,seq=00001,因为不知道服务器段会发什么序列号,因此ack为空。SYN=1,表示请求建立连接
服务器(1031)给客户端(2023)发送TCP报文段,回应客户端的请求连接,seq=6666,ask=00002,因为客户端发的上一个序列号是00001,因此服务器希望下次接受00002,ACK=1,表示确认收到请求,SYN=1,表示请求建立链接
客户端(2023)给服务器(1031)发送TCP报文段,seq=00002, ask=6667;ACK=1,表示收到请求;
四次挥手断开连接:
- 客户端(2023)给服务器(1031)发送TCP报文段, seq=x, ack=y, FIN=1;
- 服务器(1031)给客户端(2023)发送TCP报文段, seq=y, ack=x+1, ACK=1;此时处于半关闭状态,因为还有一些数据没有发送完毕
- 服务器(1031)给客户端(2023)发送TCP报文段, seq=z, ack=x+1, FIN=1;此时全关闭,所有数据传送完毕,申请断开连接
- 客户端(2023)给服务器(1031)发送TCP报文段, seq=x+1, ACK=1;表示收到断开请求
可靠连接:
- 校验位,增加伪首部
- 序号:字节有序
- 确认:累计确认
- 重传:超时重传-没有得到对应的报文段的确认信息;冗余确认-如果收到了1,该收到2,却收到了3、4、5,此时会不断发送1的确认报文,这就是冗余确认,另一方收到1的多次确认报文,就知道2没有收到,就会重传2. 收到2后,就会发一个5的确认报文(累计确认)
流量控制:
利用滑动窗口实现流量控制,根据接收方自身接受缓存大小,动态调整对方发送缓存大小,通过报文段中的窗口字段发送。
TCP连接中也有持续计时器,如果接收方收到了对方的零窗口通知,就会启动持续计时器,时间到后,会发送一个零窗口探测报文段,等待对方回应,如果还是零窗口,那就重新启动计时器,如果不是,那继续传输数据
拥塞控制:
接收窗口: 接收方根据自身缓存大小,利用报文段窗口告知发送方
拥塞窗口: 发送方根据自己估算的网络拥塞程度规定的窗口值
慢启动: 开始传输报文,拥塞窗口以指数形式增长大小
拥塞避免:等达到ssthresh,拥塞阈值时,变为线性增长
网络拥塞:等增长到网络拥塞,再此从零开始,并且,拥塞阈值减半,重新慢启动
以上是旧版本的拥塞控制算法Tahoe
新版本Reno-快重传:接收方每收到一个失序的报文段后就会立刻发出重复确认,正常下是会等到和回复数据一起发送给发送方。快重传要求立刻发送,如果发送方收到了三个重复确认,就说明有报文丢失,会立刻重传报文,不用等重传计时器。
快恢复:发送方收到三个重复确认,就执行乘法减小算法,ssthresh减半,然后开始线性增长。

为什么连接握手是三次,不能是两次?四次?
三次是为了保证双方安全都明确建立连接。客户端发起连接请求-第一次握手,服务端会在第二次握手时回应ack,表示已经收到了连接请求,并准备了对应资源。客户端收到第二次握手信息时,就已经明确,服务端做好了连接准备,但服务端不清楚客户端是否收到第二次报文段,已经需要第三次握手,客户端再回复一个ack,表示已经收到你得回复,并且我也准备好了资源。服务端收到第三次握手后就明确客户端也准备好了,就开始正常通信了。
为什么挥手要四次
首先就是保证北东断开连接的一方,成功传输所有数据,并且对方成功接受到所有数据,如果只有三次,比如没有最后一次,服务器无法知道客户端是否收到最后发的所有数据。这就违背了tcp可靠传输的性质,因此需要第四次挥手,安全断开连接。
第四次挥手:客户端会进入 TIME_WAIT 状态,确保服务端关闭连接后,自己再关闭连接。为了保证客户端发送的最后一个 ACK 报文段能够到达服务端。 这个 ACK 报文段有可能丢失,因而使处在 LAST-ACK 状态的服务端就收不到对已发送的 FIN + ACK 报文段的确认。服务端会超时重传这个 FIN+ACK 报文段,而客户端就能在 2MSL 时间内(超时 + 1MSL 传输)收到这个重传的 FIN+ACK 报文段。接着客户端重传一次确认,重新启动 2MSL 计时器。最后,客户端和服务器都正常进入到 CLOSED 状态;
防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。
TIME_WAIT为什么要2MSL

首先MSL表示报文的最大生存时间。第一个MSL保证自己的第四次挥手到服务端。如果没到,服务端就会重发FIN报文,要确保这个重发的报文客户端也能收到。因此就是两个MSL,这是等待的最大时间,如果这段时间之间,要么会收到服务端重发的第三次挥手内容,此时客户端会重发第四次挥手,然后重新计时两个MSL。如果没收到重发的第三次挥手报文,那就说明服务器成功收到了第四次报文,连接成功断开。再极端的情况,服务端重发报文也没了,那就只能异常断开。
TCP如何保证可靠性
- 三次握手和四次挥手保证连接和断开的可靠
- 滑动窗口机制要求数据的按序到达,保证数据传输安全
- 流量控制、拥塞控制、超时重传等都保证数据安全可靠,不丢包
超时重传
在发送数据报文时,设定一个定时器,每间隔一段时间,没有收到对方的ACK确认应答报文,就会重发该报文。
RTT-往返时间
RTO-超时重传时间,略大于RTT
快速重传: 连续收到三个ACK=2,就知道之前发的报文段丢失了,就会立刻重发,不用等RTO计时器了。
SACK: 带选择确认的重传,在快速重传的基础上,接收端返回最近收到的报文段的序列号范围,这样发送端就知道接收端哪些数据包没收到
D-SACK: 重复SACK,在SACK的基础上做了一些扩展,主要用来告诉发送方,有哪些数据包自己重复接受了。DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传。
滑动窗口
TCP引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。
TCP头部有个字段叫win,也即那个16位的窗口大小,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
TCP 滑动窗口分为两种: 发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:
- 已发送且已收到ACK确认
- 已发送但未收到ACK确认
- 未发送但可以发送
- 未发送也不可以发送

接收方的滑动窗口包含三大部分,如下:
- 已成功接收并确认
- 未收到数据但可以接收
- 未收到数据并不可以接收的数据

Nagle 算法与延迟确认
TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块
任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。
- 如果包长度达到MSS,则允许发送;
- 如果该包含有FIN,则允许发送;
- 设置了TCP_NODELAY选项,则允许发送;
- 未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
延迟确认:
接收方收到数据包后,如果暂时没有数据要发给对端,它可以等一段时再确认(Linux上默认是40ms)。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,而不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免对端以为丢包。
Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,酱紫就会造成更大的延迟,会产生性能问题。
粘包和拆包
TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
MSS:一个网络包能容纳得TCP数据最大长度。(不含TCP、IP头部信息,纯数据得最大长度)
**MTU:**一个网络包的最大长度,包含TCP头部、IP头部后的最大长度。
因此一个HTTP请求消息如果比较长,超过了MSS,就会被拆解成若干个小数据包进行发送,每个小部分会被放进单独的网络包中。
5. 在浏览器中输⼊URL并按下回⻋之后会发⽣什么
- 输入URL并解析,得到主机、IP、路径等信息
- DNS域名解析,根据url地址获得要访问的页面IP地址
- 三次握手建立TCP连接
- 发送HTTPP请求到web服务器
- 服务器处理http请求,返回http报文
- 解析http报文,得到数据
- 断开连接,四次挥手
6.域名解析协议DNS
将域名解析对应的IP地址。
过程:
- 现根据浏览器缓存查询是否有对应IP地址
- 如果浏览器缓存没有,那就查主机缓存是否有
- 如果本记host缓存也没有,那就想本地DNS服务器发起查询请求
- 本地DNS没有,那就向根DNS服务器发起查询请求,根DNS服务器并不负责解析域名,但它能告诉本地DNS解析器应该向哪个顶级域发起请求
- 本地DNS解析器向指定的顶级域名DNS服务器发起请求,顶级域DNS服务器也不负责具体的域名解 析,但它能告诉本地DNS解析器应该前往哪个权威DNS服务器查询下⼀步的信息。
- 本地DNS解析器最后向权威DNS服务器发送查询请求,当权威DNS服务器收到查询请求时将结果返回给本 地DNS解析器。
- 本地DNS解析器将收到的IP地址返回给浏览器,并且还会将域名解析结果缓存在本地
- 浏览器根据得到的IP地址发起连接
以上描述的是迭代查询,每级DNS服务器会把上一级DNS服务器地址返回给本地DNS服务器;如果采用递归查询(转发模式),每级DNS服务器不会返回下一级地址,而是自己将请求转发给下一级,逐级转发,然后把结果逐级传递下来,最后给本地DNS,由根DNS解析器传递给本地DNS服务器请求结果。
7. HTTP协议
超文本传输协议
特点: 简单:头+body,容易理解;易扩展:加状态码、加SSL;无状态、不安全:服务器不会去记忆HTTP的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担。但它在完成有 关联性的操作时会⾮常麻烦。 (Cookie解决)
版本:http9.0只支持get请求,没有请求头,只能返回body内容;
http1.0header+body,支持多种请求方法,但不支持长连接,每次请求都要建立连接;
http1.1支持长连接,只要没提出断开连接,就保持tcp连接状态。如果传输相同的数据,每次头部信息相同,造成头部冗余。支持管道传输,只要发送请求,就可以继续发送第二个请求,不用等第一个请求的回复,而之前是发出请求必须等回复,才能再发请求。服务器必须按照接收请求的顺序发送对这些管道化请求的响应。如果果服务端在处理 A 请求时耗时⽐较⻓,那么后续的请求的处理都会被阻塞住,响应队头阻塞。
优点:长连接、管道传输、
缺点:头部冗余、响应队头阻塞、无状态、明文传输
http2.0基于 HTTPS 的, 所以HTTP/2的安全性也是有保障的;首先1.1中如果传输相同的数据,每次头部信息相同,造成头部冗余,每个请求和响应都需要带有⼀定的头部信息,每次互相发送相同的⾸部造成的浪费较多;2.0利用头部压缩解决了这个问题。1.1要求服务端必须按顺序处理管道中的请求,然后以此回应,2.0引出了 Stream 概念,对不同的个http请求进行划分,并⾏交错地发送请求和响应;2.0服务器可以额外的向客户端 推送资源,⽽⽆需客户端明确的请求。
优点:头部压缩、二进制密文、并发传输、主动推送资源
缺点:tcp的队头阻塞
http3.0利用UDP,因为2.0依旧存在头部阻塞问题,这里的阻塞指的是TCP连接中的阻塞,因为TCP是面向字节流的,要求字节按序到达,如果前一个字节没有到达,后续到达的字节会放在接收缓存中,并不会实际接受,也就不会发送给上级业务。必须等按顺序的下一位字节到达,才能接受之后的。而3.0利用UDP协议,也就没有了这个头部阻塞问题。
优点:UDP连接解决了队头阻塞、更快建立连接、连接迁移
缺点:
8.Linux接受网络包过程
当主机收到一个网络包后,通过DMA技术将网络包写入指定内存地址中,一片环形缓冲区。然后告知操作系统网络包已经到达。那么怎么告知呢,直观地做法就是中断,但高性能场景下,网络包接受频率高,频繁中断导致CPU性能降低。因此Linux采用NAPI机制,混合中断和轮询方法:
当网络包达到,先通过DMA技术将网络包写入缓存,然后会发起中断,CPU收到中断请求后,会执行相应的中断处理函数;
中断处理函数中,首先会暂时屏蔽中断,告知操作系统,下次有数据直接写入内存就好,不需要再发起中断,也就减少了中断次数,提升CPU性能;
之后发起软中断,恢复刚才的中断;内核中专门有线程处理软中断,轮询处理数据,从缓冲区中获取数据包,然后逐层处理。
处理过程是:先判断接收得到报文是否合法,然后网络层根据IP包头,确定是否接受,接收会将网络包传给传输层。传输层根据TCP报头,得到两个IP和两个sort,四元组确定一个socket,将数据放入socket缓冲区。最后应用层根据socket接口获得缓冲区数据,唤醒处理进程。
接受包:
应用程序首先调用socket发送包的接口,内核会申请一个内核态内存,将用户数据写入该内存块,将内存块加入到发送缓冲区,如果是TCP协议,会将该内存块复制一份,因为涉及重传,需要副本,该副本会等到收到ACK确认后才会释放。再给内存块填充TCP头部信息。给网路层,增加IP头部;这里注意,在整个传递过程中,使用的都是同一个内存结构,通过其data指针的移动来增加各种头部信息,如果每一层结构不相同,那岂不是需要复制,太浪费资源了,因此采用最原始内核申请的内存块。网络接口层增加MAC头部信息,将内存块放入网卡的发送队列中,然后触发软中断告知网卡驱动程序,驱动程序会在发送队列中读取内存块,然后放到缓冲区,最后发送。发送之后,网卡会出发一次硬中断释放内存,主要是释放内存块副本和缓冲区内存。等收到ACK回应报文,原始内存块也会释放掉
内存拷贝问题:
发送数据包一共涉及三次内存拷贝问题:第一次在内核开辟内存块时,将数据拷贝至内存块然后发送缓冲区;第二次是tcp的可靠传输,为了重传会拷贝一个内存块副本;第三个是分包,如果数据包过大,会拷贝成多个小的内存块分别传输。
9.Keep-Alive和Keepalive
HTTP的Keep-Alive叫作http的长连接,由应用程序实现,使得同一个TCP连接发送/接收多个http请求。而http短链接,每个TCP连接只能发送和接受一个http请求,之后就会断开连接,第二次请求需要重新建立连接。
TCP的Keepalive是TCP的保活机制,由内核实现,当客户端和服务端长时间没有数据传输时,内核为了检测该tcp连接是否有效,就会发送tcp探测报文,来验证对方主机是否在线。如果对端正常相应,那说明连接有效,会重启TCP保活时间。如果探测报文没有相应,重复多次后,该tcp连接死亡,断开。
10. GET与POST
GET:从服务器获取指定资源,对于url有长度限制,因为只读操作,所以操作安全且是幂等的,即多次操作结果一样 ,并不会修改服务器数据。因此可以对GET请求做缓存。
POST:根据请求表单对指定资源作出处理,对于body没有大小限制。因为会修改服务器数据,所以是不安全的。其次,每次访问都会创建不同数据,因此不是幂等的。
11. HTTP缓存技术
避免发送HTTP请求的方法————缓存技术
强制缓存: 客户端浏览器只要判断缓存没有过期,就直接利用浏览器的本地缓存,不与服务端商量;第一次服务器返回资源,会在response头部加Cache-Control字段,表示过期时间。之后每次请求都会先与该时间进行对比,判断缓存是否过期。
协商缓存:客户端浏览器给服务端发送请求,服务端回复响应304,表示,可以使用本地缓存资源。这种方式是由服务端决定浏览器是否使用缓存。有两种头部信息实现。响应头部Last-Modified表示资源最后修改时间,根据请求时间与被访问资源最后修改时间做对比,如果修改时间大,说明资源更新过,就不能使用缓存,返回新资源。如果小,则响应304;第二种是ETag字段,唯一标识响应资源。来准确判断资源是否被修改过,不依赖于时间。ETag优先级高于时间标志,
协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求。
12. RPC远程过程调用
不调用本地方法,而是调用远端服务器某个方法,但屏蔽掉中间细节。
与HTTP区别:
- RPC更多用于CS框架,先主流的BS框架主要采用HTTP协议
- HTTP需要利用DNS服务获取服务端IP;RPC需要中间服务保存服务端IP,包括但不限于DNS;
- HTTP1.1之后采取长连接,实现多次数据请求;RPC采用连接池,需要发送数据时,从连接池取tcp连接,用来发送数据。
- HTTP数据格式复杂,头部+body;RPC数据体积更小,更简洁。
13. WebSocket
实际业务中,有一种需求是服务端主动发数据给客户端,这怎么办?HTTP只能客户端发请求,服务端回应,但服务端不能主动发请求。
两种方法:
- http不断轮询:**网页的前端代码里不断定时发 HTTP 请求到服务器,服务器收到请求后给客户端响应消息。**很明显的问题就是服务器压力过大。
- 长轮询:HTTP 请求将超时设置的很大,比如 30 秒,在这 30 秒内只要服务器收到了请求,就立马返回给客户端网页。如果超时,那就立马发起下一次请求。
但是不管那种轮询,本质还是客户端发请求。
TCP连接采取全双工形式,双方都可以主动发数据。HTTP1.1采用半双工,同一时间里只能有一方主动发现数据;因此基于HTTP,就有了WebSocket。一个普通的浏览器访问都是采用HTTP协议,一旦打开网络游戏,那就要使用WebSocket。同时需要在原本的http连接基础上进行升级,大致步骤就是,客户端发送的http请求包含几个特殊字段,其中有一个Key字符串。服务端收到后,如果也想升级协议,就会对Key字符串进行进行公开加密,响应给客户端(101状态码,标识协议升级),如果客户端收到了,加密后的字符串与自己加密后的字符串一致,就表示验证通过,协议升级成功
14. IP
IP协议在网络层,用于主机和主机之间的通信,点到点通信;上层传输层TCP协议实现了端到端(应用程序)的通信,到这层就是具体的主机之间的通信。在网络中又会跨域很多路由,交换机。因此又需要MAC地址实现连个设备之间的通信。这样tcp、ip、mac之间的关系就清楚了。
IPv4: 32位,计算机内是二进制方式处理的,采用点分十进制方式标记,32位每8位分为一组,共分8组。

IP地址分类:A、B、C、D、E;每类地址最多有2^主机号位数^-2个主机,因为全零和全1不能用,全1用于网络中的广播。本地网络内的广播称为本地广播;不同网络之间的广播叫作直接广播。
D类地址没有主机号,用于多播;E类也没有主机号,未被使用。
IP分类缺点
- 同一网络下没有地址层次,比如C类地址后不能再划分;
- 不能与现实需求相匹配,实际应用需要根据需求划分不同数量的ip地址,但C类只有254太少了,B类有太多,因此无法满足实际需求。
CIDR无分类地址:
将32位IP地址划分为两部分,前面网络号,后面主机号。
比如 10.100.122.2/24,这种地址表示形式就是 CIDR,/24 表示前 24 位是网络号,剩余的 8 位是主机号。
或者采用子网掩码方法,将子网掩码和 IP 地址按位计算 AND,就可得到网络号。
主机通信首先看是否在同一个广播域内,也就是网络地址是否相同,相同就可以直接发数据。如果不相同,就需要跨网络,需要路由器寻址,找到对应的网络,然后转发到该网路路由器中,再把数据传送到目标主机。每个路由控制表中记录着网络地址和对应该发送的的路由器地址,每次转发都查询路由控制表找到对应路由器。
MTU: 数据链路最大传输单元
如果IP数据包大于MTU,就会进行IP切片, 经过分片之后的 IP 数据报在被重组的时候,只能由目标主机进行,路由器是不会进行重组的。在分片传输中,一旦某个分片丢失,则会造成整个 IP 数据报作废,所以 TCP 引入了 MSS 也就是在 TCP 层进行分片不由 IP 层分片,那么对于 UDP 我们尽量不要发送一个大于 MTU 的数据报文。

- 取消了首部校验和字段。 因为在数据链路层和传输层都会校验,因此 IPv6 直接取消了 IP 的校验。
- 取消了分片/重新组装相关字段。 分片与重组是耗时的过程,IPv6 不允许在中间路由器进行分片与重组,这种操作只能在源与目标主机,这将大大提高了路由器转发的速度。
- 取消选项字段。 选项字段不再是标准 IP 首部的一部分了,但它并没有消失,而是可能出现在 IPv6 首部中的「下一个首部」指出的位置上。删除该选项字段使的 IPv6 的首部成为固定长度的
40字节。
15. ARP
网络传输中,根据目标IP地址确定下一跳主机,传给数据链路层中,会加MAC地址,网络路由可以有路由表找到每一跳的目标地址。那么MAC也需要找到下一跳MAC地址,通过ARP协议。
主机通过广播发送ARP请求,询问目标IP地址对应的MAC地址是什么。链路中的设备收到ARP请求后,进行解析,如果其中查询IP是自己的,就会把自己的MAC地址打包成ARP响应包返回给主机。操作系统通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。不过,MAC 地址的缓存是有一定期限的,超过这个期限,缓存的内容将被清除。
RARP: 通过已知 MAC 地址求 IP 地址。某个设备加入网络中,会利用RARP协议,发一个请求信息,告知RARP服务器,自己的MAC地址,应该配置哪个IP。根据回应报文设置IP。
16.DHCP
动态主机配置协议DHCP 动态获取 IP 地址
- 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将帧广播到所有的网络中设备。
- DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期。
- 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 DHCP 请求报文(DHCP REQUEST进行响应,回显配置的参数。
- 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。
客户端就可以使用DHCP服务器分配的IP地址了,等IP地址快到期后,客户端会在向DHCP服务器发送请求报文
- 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延长租期。
- 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。
DHCP通信过程采取UDP广播通信,广播通信只能在同一个局域网。而DHCP中继代理,可以转发各个网络的DHCP请求到DHCP服务器。网络内采取广播形式,而DHCP中继代理到DHCP服务器通信采取单播。
17. 网络层:控制平面
数据包在数据链路层传递时,需要确定一个从发送方到接收方之间路由器网络的最短路径——路由选择算法
路由选择算法的三种分类角度
- 集中式路由选择算法+分散式路由选择算法:划分表示是算法是否需要全局完整的网络知识,要求知道网络的全局状态信息(集中式)(LS算法),而分散式不需要知道全局信息,只需要知道相邻结点的信息即可,然后逐层迭代,得到最短路径(DV算法)。
- 静态路由选择算法+动态路由选择算法:静态需要人工进行链路调整。动态会随着网络流量和拓扑结构变化自行选择路径
- 负载敏感算法+负载迟钝算法:某个链路开销变化是否能反映出拥塞水平。
首先一个LS算法: 经典Dijkstra算法,就不展开说了,基础算法了。
DV算法: 经典Bellmanford算法,同理,这里不展开描述
以上内容是一个小区域内的路由选择,但随着路由器数据变多,这些算法显然不够用。因此分区域管理,相同管理控制下的路由器称为自治系统(AS)
AS内部路由选择协议:
- OSPF开放最短路优先,一种LS协议,路由器向AS内其他所有路由器广播路由选择信息
AS间路由选择协议:
- 所有AS运行相同的AS间路由选择协议,称为边界网关协议BGP,yao'bu