# 网络
# 关于OSI七层模型和TCP四层模型
OSI分层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
TCP/IP模型:应用层、传输层、网络层、网络接口层
参考:IP
# TCP和UDP属于哪一层
属于传输层的协议
# TCP/UDP各有哪些优缺点
TCP Transmission Control Protocol 传输控制协议
- 面向连接的,可靠的传输协议
- tcp在通信之前必须通过三次握手机制与对方建立连接
- tcp连接耗时,占用的系统资源多
- 保证数据传输的正确性,不易丢包
- tcp传输速率较慢,实时性差
- tcp是流模式
- 每一条TCP连接只能是点到点的
UDP User Datagram Protocol 用户数据包协议
面向无连接的,无状态的传输协议
udp通信不必与对方建立连接,不管对方的状态就直接把数据发送给对方
连接相对不耗时
udp是不可靠的,易丢包
udp传输速率较快
udp是数据包模式
UDP支持一对一,一对多,多对一和多对多的交互通信
TCP是面向链接的,而UDP是面向无连接的。
TCP仅支持单播传输,UDP 提供了单播,多播,广播的功能。
TCP的三次握手保证了连接的可靠性; UDP是无连接的、不可靠的一种数据传输协议,首先不可靠性体现在无连接上,通信都不需要建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收。
UDP的头部开销比TCP的更小,数据传输速率更高,实时性更好
# 从浏览器地址栏输入url到显示页面的步骤
- 浏览器地址栏输入URL
- 浏览器查看页面缓存 (浏览器缓存,操作系统缓存,路由器缓存 )
- 浏览器解析URL获取协议,主机,端口,path
- 浏览器查询DNS获取主机ip地址 (DNS基于UDP)
- 建立TCP连接,三次握手
- 发送HTTP请求
- 服务端处理,返回响应
- 浏览器进行解码
- 浏览器解析页面DOM结构
- 请求额外的资源
- 构建DOM树
- 构建CSSOM树
- 生成渲染树
- 解析js
- 渲染,显示页面
# HTTP 请求的方法有哪些
- get
- post
- put
- delete
- head
- purge
- options: 询问支持的请求方法,用来跨域请求;
- trace: 回显服务器收到的请求,主要⽤于测试或诊断。
- connect: 要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
- connect: 要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
# GET 和 POST 有什么区别
本质上从HTTP的标准来看没有什么区别,一般事实上的区别:
- get 获取数据,post 修改数据,restful 语义开发
- get 使用url query
- post 放在body内
- post比get相对安全,因为数据在地址栏上不可见,但是也可以抓包
- 浏览器对url的长度有限制
另一种答法:
- 应用场景: GET 请求是一个幂等的请求,一般 Get 请求用于对服务器资源不会产生影响的场景,比如说请求一个网页的资源。而 Post 不是一个幂等的请求,一般用于对服务器资源会产生影响的情景,比如注册用户这一类的操作
- 是否缓存: 因为两者应用场景不同,浏览器一般会对 Get 请求缓存,但很少对 Post 请求缓存
- 发送的报文格式: Get 请求的报文中实体部分为空,Post 请求的报文中实体部分一般为向服务器发送的数据
- 安全性: Get 请求可以将请求的参数放入 url 中向服务器发送,这样的做法相对于 Post 请求来说是不太安全的,因为请求的 url 会被保留在历史记录中
- 请求长度: 浏览器由于对 url 长度的限制,所以会影响 get 请求发送数据时的长度。这个限制是浏览器规定的,并不是 RFC 规定的
- 参数类型: post 的参数传递支持更多的数据类型
# http1.1 和 http2.0的区别
http2.0
- 兼容http1.1
- 多路复用,并发传输
- 协议 二进制分帧 分为HEADER 帧+ DATA帧
- 首部压缩
- 服务端推送(Server Push)
- 安全 和 https 一起使用
# HTTP 缓存
- 强缓存
- 协商缓存
强缓存:200 http1.0: expires http1.1: cache-control: max-age
协商缓存:304 last-modifies/if-modifies-since Etag/if-none-match
# HTTP 工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应
模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据
- HTTP:一个基于请求与响应,无状态的,
应用层
的协议 - TCP:Http使用TCP作为它的支撑运输协议。HTTP客户机发起一个与服务器的TCP连接,一旦连接建立,浏览器(客户机)和服务器进程就可以通过套接字接口访问TCP
# HTTP 常用返回码
1xx Informational(信息状态码) 接受请求正在处理
2XX 成功
200 OK,表示从客户端发来的请求在服务器端被正确处理
204 No content,表示请求成功,但响应报文不含实体的主体部分
205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
206 Partial Content,进行范围请求
3XX 重定向
301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
302 found,临时性重定向,表示资源临时被分配了新的 URL
303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
4XX 客户端错误
400 bad request,请求报文存在语法错误
401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
403 forbidden,表示对请求资源的访问被服务器拒绝
404 not found,表示在服务器上没有找到请求的资源
405 Method Not Allowed
499 client has closed connection 客户端端已经关闭了连接
5XX 服务器错误
500 internal sever error,表示服务器端在执行请求时发生了错误
501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
502 服务器内部错误
503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
504 504 Gateway Timeout 网关超时
# https 协议的工作原理
HTTPS 采取的是混合加密的方式,简单来说就是通过非对称加密的方式来传输对称密钥,采用对称加密的方式来传输之后的数据。
- Client 发起一个 HTTPS 的请求 Client Hello (TLS 连接)到服务器,同时会告诉自己支持的加密算法
- Server从客户端发来的加密算法中,选出一组加密算法和HASH算法(注,HASH也属于加密),并将自己的身份信息以证书的形式发回给客户端。而证书中包含了网站的地址,加密用的公钥,以及证书的颁发机构等(这里,服务器就将自己用来加密用的公钥一同发还给客户端)
- Client 验证公钥证书:比如是否在有效期内,证书的用途是不是匹配 Client 请求的站点,是不是在 CRL 吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的 Root 证书或者 Client 内置的 Root 证书)。如果验证通过则继续,不通过则显示警告信息。
- Client 使用
伪随机数生成器
生成加密所使用的会话密钥
,然后用证书的公钥
加密这个会话密钥,发给 Server - Server 使用自己的私钥解密这个消息,得到
会话密钥
。至此,Client 和 Server 双方都持有了相同的会话密钥(对称密钥) - Server 使用对称密钥加密明文内容 A,发送到 Client
- Client 使用对称密钥解密响应的密文,得到明文内容 A
- Client 再次发起 HTTPS 的请求,使用对称密钥加密请求的
明文内容B
,然后 Server 使用对称密钥解密密文,得到明文内容B
。
可以参考图:
# TCP 三次握手
- 客户端发送一个
SYN
段,并指明客户端的初始序列号,即ISN(c)
- 服务端发送自己的
SYN
段作为应答,同样指明自己的ISN(s)
。为了确认客户端的SYN
,将ISN(c)+1
作为ACK
数值。这样,每发送一个SYN
,序列号就会加 1
。 如果有丢失的情况,则会重传。 - 为了确认服务器端的
SYN
,客户端将ISN(s)+1
作为返回的ACK
数值
# TCP 四次挥手
- 客户端发起
FIN 包(FIN = 1)
,客户端进入FIN_WAIT_1
状态。TCP 规定,即使FIN
包不携带数据,也要消耗一个序号。 - 服务器端收到 FIN 包,发出确认包
ACK(ack = x + 1)
,并带上自己的序号seq=y
,服务器端进入了CLOSE_WAIT
状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的ACK
后,进入了FIN_WAIT_2
状态 - 服务器端数据发送完毕后,向客户端发送
FIN
包(seq=z ack=x+1
),半连接状态下服务器可能又发送了一些数据,假设发送 seq 为 w。服务器此时进入了LAST_ACK
状态 - 客户端收到服务器的
FIN
包后,发出确认包(ACK=1,ack=z+1
),此时客户端就进入了TIME_WAIT
状态。注意此时 TCP 连接还没有释放,必须经过2*MSL
后,才进入CLOSED
状态。而服务器端收到客户端的确认包 ACK 后就进入了CLOSED
状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。
# 为什么是三次握手,四次挥手?
其实在 TCP 握手的时候,接收端发送 SYN+ACK
的包是将一个ACK
和一个 SYN
合并到一个包中,所以减少了一次包的发送,三次完成握手
对于四次挥手,因为 TCP 是全双工通信,在主动关闭方发送 FIN 包后,接收端可能还要发送数据,不能立即关闭服务器端到客户端的数据通道,所以也就不能将服务器端的FIN 包与对客户端的 ACK 包合并发送
,只能先确认 ACK,然后服务器待无需发送数据时再发送 FIN 包,所以四次挥手时必须是四次数据包的交互
# 为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSE 状态?
MSL 指的是报文在网络中最大生存时间。在客户端发送对服务器端的 FIN 的确认包 ACK 后,这个 ACK 包是有可能不可达的,服务器端如果收不到 ACK 的话需要重新发送 FIN 包。
所以客户端发送 ACK 后需要留出 2MSL 时间(ACK 到达服务器 + 服务器发送 FIN 重传包,一来一回)等待确认服务器端确实收到了 ACK 包。
也就是说客户端如果等待 2MSL 时间也没有收到服务器端的重传包 FIN,说明可以确认服务器已经收到客户端发送的 ACK。
还有第 2 个理由,避免新旧连接混淆。
在客户端发送完最后一个 ACK 报文段后,在经过 2MSL 时间,就可以使本连接持续的时间内所产生的所有报文都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文。
你要知道,有些自作主张的路由器会缓存 IP 数据包,如果连接重用了,那么这些延迟收到的包就有可能会跟新连接混在一起
# 常见的HTTP请求头和响应头
请求头
- Accept: 浏览器能够处理的内容类型
- Accept-Charset:浏览器能够显示的字符集
- Accept-Encoding:浏览器能够处理的压缩编码
- Accept-Language:浏览器当前设置的语言
- Connection:浏览器与服务器之间连接的类型
- Cookie:当前页面设置的任何Cookie
- Host:发出请求的页面所在的域
- Referer:发出请求的页面的URL
- User-Agent:浏览器的用户代理字符串
响应头
- Date:表示消息发送的时间,时间的描述格式由rfc822定义
- server:服务器名称
- Connection:浏览器与服务器之间连接的类型
- Cache-Control:控制HTTP缓存
- content-type: 表示后面的文档属于什么MIME类型
# HTTP 3.0 *
http2.0的问题
HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题
。
HTTP/3基于UDP协议实现了类似于TCP的多路复用数据流、传输可靠性等功能,这套功能被称为QUIC协议
- 流量控制、传输可靠性功能:QUIC在UDP的基础上增加了一层来保证数据传输可靠性,它提供了数据包重传、拥塞控制、以及其他一些TCP中的特性。
- 集成TLS加密功能:目前QUIC使用TLS1.3,减少了握手所花费的RTT数。
- 多路复用:同一物理连接上可以有多个独立的逻辑数据流,实现了数据流的单独传输,解决了TCP的队头阻塞问题。
- 快速握手:由于基于UDP,可以实现使用0 ~ 1个RTT来建立连接。
# UDP协议为什么不可靠?(tcp为什么是可靠的)
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
- 不保证消息交付:不确认,不重传,无超时
- 不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
- 不跟踪连接状态:不必建立连接或重启状态机
- 不进行拥塞控制:不内置客户端或网络反馈机制
# TCP的重传机制
由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间,二是基于确认信息。 TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号
# TCP的拥塞控制机制
TCP的拥塞控制机制主要是以下四种机制:
- 慢启动(慢开始)
- 拥塞避免
- 快速重传
- 快速恢复
# TCP的流量控制机制
一般来说,流量控制就是为了让发送方发送数据的速度不要太快,要让接收方来得及接收。TCP采用大小可变的滑动窗口进行流量控制,窗口大小的单位是字节。这里说的窗口大小其实就是每次传输的数据大小。
当一个连接建立时,连接的每一端分配一个缓冲区来保存输入的数据,并将缓冲区的大小发送给另一端。 当数据到达时,接收方发送确认,其中包含了自己剩余的缓冲区大小。(剩余的缓冲区空间的大小被称为窗口,指出窗口大小的通知称为窗口通告 。接收方在发送的每一确认中都含有一个窗口通告。) 如果接收方应用程序读数据的速度能够与数据到达的速度一样快,接收方将在每一确认中发送一个正的窗口通告。 如果发送方操作的速度快于接收方,接收到的数据最终将充满接收方的缓冲区,导致接收方通告一个零窗口 。发送方收到一个零窗口通告时,必须停止发送,直到接收方重新通告一个正的窗口
# WebSocket
WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。 WebSocket 的出现就解决了半双工通信的弊端。它最大的特点是:服务器可以向客户端主动推动消息,客户端也可以主动向服务器推送消息。 WebSocket原理:客户端向 WebSocket 服务器通知(notify)一个带有所有接收者ID(recipients IDs)的事件(event),服务器接收后立即通知所有活跃的(active)客户端,只有ID在接收者ID序列中的客户端才会处理这个事件。 WebSocket 特点的如下:
- 支持双向通信,实时性更强
- 可以发送文本,也可以发送二进制数据
- 建立在TCP协议之上,服务端的实现比较容易
- 数据格式比较轻量,性能开销小,通信高效
- 没有同源限制,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器