网络模型
- 应用层【HTTP👉报文/消息】
- 传输层【TCP或UDP👉段👉MSS】
- 网络层【IP、寻址和路由👉MTU】
①IP(Internet Protocol,网际协议)主要作用是定义数据包的格式、对数据包进行路由和寻址,以便它们可以跨网络传播并到达正确的目的地。
②NAT:(Network Address Translation,网络地址转换) 主要用于在不同网络之间转换 IP 地址。它允许将私有 IP 地址(如在局域网中使用的 IP 地址)映射为公有 IP 地址(在互联网中使用的 IP 地址)或者反向映射,从而实现局域网内的多个设备通过单一公有 IP 地址访问互联网。作用:NAT 不光可以缓解 IPv4 地址资源短缺的问题,还可以隐藏内部网络的实际拓扑结构,使得外部网络无法直接访问内部网络中的设备,从而提高了内部网络的安全性。 - 网络接口层【物理层】
OSI七层
应用层/表示层/会话层
传输层
网络层
数据链路层/物理层
TCP
报文头部
序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。
控制位 :
👉ACK
:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。
👉RST
:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。
什么情况下用到RST :TCP处理程序会在自己认为的异常时刻发送RST包。
- case1:A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。
- case2:AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。
👉SYN
:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
👉FIN
:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
三次握手
- 过程
- 客户端发送一个 SYN 报文段,其中包含【同步序列号(SYN = 1)】【客户端的初始序列号,即ISN (seq=x)】。发完后客户端处于
SYC-Send
状态 - 服务端收到 SYN 报文段后,会回复一个 SYN + ACK 报文段,包含【同步序列号(SYN = 1)】【服务端的初始序列号 (seq = y)】【对客户端 ISN 的确认号 (ack = x + 1)】【确认号(ACK=1)】。发完后服务器为
SYN_Received
状态。 - 客户端收到 SYN + ACK 报文段后,会发送一个 ACK 报文段,包括【数据包序列号(seq = x + 1)】【同步序列号(ack = y + 1)】【确认号(ACK = 1)】。客户端转为
established
状态。
- 客户端发送一个 SYN 报文段,其中包含【同步序列号(SYN = 1)】【客户端的初始序列号,即ISN (seq=x)】。发完后客户端处于
- 为什么三次
三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。 - 为什么不是两次?
无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号; - 为什么不是四次?
三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。 - 可以携带数据吗?
第三次握手的时候,是可以携带数据的。第一次、第二次握手不可以携带数据。
原因:第一次携带数据会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
四次挥手
- 过程
- 客户端发送一个 FIN 报文段,表示客户端希望断开连接。
- 服务端收到 FIN 报文段后,会回复一个 ACK 报文段,表示服务端已经收到客户端的 FIN 报文段。
- 服务端发送一个 FIN 报文段,表示服务端希望断开连接。
- 客户端收到 FIN 报文段后,会回复一个 ACK 报文段,表示客户端已经收到服务端的 FIN 报文段。
- 为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥手?
因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务器到客户端的数据传送。
TCP保证可靠性的机制?
- 三次握手和四次挥手
- 基于数据块传输:应用数据被分割成数据块,再传输给网络层,数据块被称为报文段或段。
- 对失序数据包重新排序以及去重:TCP 为了保证不发生丢包,就给每个包一个序列号,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据就可以实现数据包去重。
- 校验和:TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- 流量控制:使用滑动窗口 机制来进行流量控制,确保发送方发送的数据不会超出接收方处理的能力范围。接收方通过发送窗口大小信息告知发送方自己的接收能力,发送方据此调整发送速率。
- 拥塞控制:通过控制发送方的发送速率,减少网络拥塞,是发送方 根据网络状况维护的值
👉慢启动:在慢启动阶段,发送方会指数级地增加发送速率。
👉拥塞避免:在拥塞避免阶段,发送方会线性地增加发送速率。
👉快恢复:在快恢复阶段,发送方会快速地恢复到拥塞发生前的发送速率。 - 超时重传:发送方定时重传丢失的数据包保证数据可靠传输
👉超时重传:如果发送方在规定时间内没有收到接收方的确认号,则会重传该数据包。
👉累计确认:接收方会对收到的所有数据包进行确认,发送方只需要重传接收方没有确认的数据包。
👉选择性重传:发送方可以只重传接收方没有收到的数据包。
什么是TCP粘包/拆包?发生的原因?
👉由于 TCP 传输协议是面向字节流的传输协议,没有消息保护边界,所以发送方发送的多个数据包,接收方应用层不知如何区分,可能会被当成一个包来处理,这就是粘包 ;或者,发送方将一个打包分成多个小包发送,而接收方将它们当成多个包进行处理,这就是拆包 。
👉解决方法:将首尾字符用特殊字符分隔 | 使用变长协议,在报文头中指定当前报文中数据的长度。(如HTTP协议)
什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_Received
状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。
使用TCP的协议
👉HTTP 协议(HTTP/3.0 之前):是一种用于传输超文本和多媒体内容的协议,主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。当我们使用浏览器浏览网页的时候,我们网页就是通过 HTTP 请求进行加载的。
👉HTTPS 协议:更安全的超文本传输协议(HTTPS,Hypertext Transfer Protocol Secure),身披 SSL 外衣的 HTTP 协议。
👉FTP 协议:文件传输协议 FTP(File Transfer Protocol)是一种用于在计算机之间传输文件的协议,可以屏蔽操作系统和文件存储方式。
👉SMTP 协议:简单邮件传输协议(SMTP,Simple Mail Transfer Protocol)的缩写,是一种用于发送电子邮件的协议。注意 ⚠️:SMTP 协议只负责邮件的发送,而不是接收。要从邮件服务器接收邮件,需要使用 POP3 或 IMAP 协议。
👉POP3/IMAP 协议:两者都是负责邮件接收的协议。IMAP 协议是比 POP3 更新的协议,它在功能和性能上都更加强大。IMAP 支持邮件搜索、标记、分类、归档等高级功能,而且可以在多个设备之间同步邮件状态。几乎所有现代电子邮件客户端和服务器都支持 IMAP。
👉Telnet 协议:用于通过一个终端登陆到其他服务器。Telnet 协议的最大缺点之一是所有数据(包括用户名和密码)均以明文形式发送,这有潜在的安全风险。这就是为什么如今很少使用 Telnet,而是使用一种称为 SSH 的非常安全的网络传输协议的主要原因。
👉SSH 协议 : SSH( Secure Shell)是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH 建立在可靠的传输协议 TCP 之上。
timewait作用
- 在 TCP 连接关闭时,可能会有延迟的数据包在网络中传输,这些数据包可能是在连接关闭之前发送的。TIME_WAIT 状态确保了在连接关闭后,双方都有足够的时间处理延迟的数据包,从而保证数据的完整性和正确性。
- TIME_WAIT 状态会持续一段时间(通常是 2 * MSL,MSL 是最大报文生存时间),在这段时间内,旧的连接信息仍然保留在操作系统中。这样可以防止旧的数据包影响到新的连接,避免了连接混淆和数据损坏的可能性。
- 在 TIME_WAIT 状态下,如果另一端延迟接收到最后的 ACK 或者重传了数据包,这时发送端仍然可以处理这些数据包,从而保证了数据的可靠传输。
解决重传乱序和重复
UDP
和TCP的区别
- UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接。
- 远地主机在收到 UDP 报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达。TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。
- TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情了。
- 由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多。
- TCP 是面向字节流的,UDP 是面向报文的。
- TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大。
- TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多。
UDP和TCP如何选择
UDP 一般用于即时通信,比如:语音、 视频、直播等等。这些场景对传输数据的准确性要求不是特别高,比如你看视频即使少个一两帧,实际给人的感觉区别也不大。
TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。
使用UDP的协议
👉HTTP/3.0 : HTTP/3.0 弃用 TCP,改用基于 UDP 的 **QUIC **协议 。
QUIC 协议通过基于 UDP、多路复用、0-RTT 握手等特性,提供了更快的连接建立和数据传输速度,同时保证了数据的安全性和可靠性。
👉DHCP 协议:动态主机配置协议,动态配置 IP 地址。
👉DNS:域名系统(DNS,Domain Name System)将人类可读的域名转换为机器可读的 IP 地址。实际上,DNS 同时支持 UDP 和 TCP 协议。
从输入 URL 到页面展示到底发生了什么?
- 检查缓存:浏览器接收到⽤户请求,先检查浏览器缓存是否有缓存该资源,如果有直接返回。
- DNS解析:发送到DNS(域名服务器)获得域名对应的WEB服务器的IP地址。
- TCP连接:客户端浏览器与WEB服务器建立TCP连接。
- 发送HTTP请求:客户端浏览器向目标WEB服务器发送相应的HTTP或HTTPS请求。
- 服务器处理请求并返回HTTP报文:WEB服务器响应请求,返回指定的URL数据或错误信息;如果设定重定向,则重定向到新的URL地址。
- 浏览器渲染界面:客户端浏览器下载数据,解析HTML源文件,在页面中进行显示。
- TCP断开连接:断开TCP连接。
HTTP
常见状态码
👉1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
👉2xx 类状态码表示服务器成功处理了客户端的请求 ,常见的有:
「200 OK」是最常见的成功状态码,表示一切正常。
「204 No Content」也是常见的成功状态码,但响应头没有 body 数据。
👉3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向 ,常见的有:
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
「302 Found」即临时重定向,请求的资源还在,但暂时需要用另一个 URL 来访问。
「304 Not Modified」缓存重定向,告诉客户端可以继续使用缓存资源,用于缓存控制。
👉4xx 类状态码表示客户端发送的报文有误,服务器无法处理 。常见的有:
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
「404 Not Found」表示请求的资源在服务器上不存在,所以无法提供给客户端。
👉5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误 ,常见的有:
「500 Internal Server Error」与 400 类似,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
「501 Not Implemented」表示客户端请求的功能还不支持,类似"即将开业,敬请期待"的意思。
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似"网络服务正忙,请稍后重试"的意思。
请求报文
请求行:请求方法:get post等 + 请求路径 url + 版本号
请求头:常见字段如下
Host:客户端发送请求时,用来指定服务器的域名。
Content-Length :表明服务器返回数据的数据长度。
Connection :常用于客户端要求服务器使用「HTTP 长连接」机制,以便其他请求复用。
Content-Encoding :说明数据的压缩方法,表示服务器返回的数据使用了什么压缩格式。
请求体:传递请求参数
响应报文
响应行:版本信息 + 状态码及描述
响应头:服务器的基本信息等
响应体:返回的数据
GET 和 POST 有什么区别?
👉语义(主要区别):GET 通常用于获取或查询资源;而 POST 通常用于创建或修改资源。
👉幂等:GET 请求是幂等的,即多次重复执行不会改变资源的状态;而 POST 请求是不幂等的,即每次执行可能会产生不同的结果或影响资源的状态。
👉格式:GET 请求的参数通常放在 URL 中,形成查询字符串;POST 请求的参数通常放在请求体(body)中。
👉缓存:由于 GET 请求是幂等的,它可以被浏览器或其他中间节点缓存起来,以提高性能; POST 请求则不适合被缓存,因为它可能有副作用,每次执行可能需要实时的响应。
缓存技术
针对重复的HTTP请求,可以缓存在本地。主要在http响应头中设定。当浏览器第一次请求服务器资源的时候,服务器返回资源时在Response
头部加上Cache-Contro
l,设置了过期时间。当浏览器再次请求这个资源会先去判断是否过期,如果没有就使用该缓存
- 强制缓存:只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,无需向服务器发送请求。
- 协商缓存:向服务器发送请求,服务器会根据请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并通知浏览器从缓存中读取资源。
HTTP不同版本优化对比
👉HTTP/1.1
- 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
- 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
👉HTTP/2
- 基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。
- 头部压缩:如果同时发送多个请求,且头部是一样的,那协议会自动进行压缩。
- 二进制格式:不再像 HTTP/1.1 采用纯文本格式,头信息和数据体都是二进制且统称为帧。
- 并发传输:引入了 Stream 概念,多个 Stream 复用在一条 TCP 连接。
- 服务器推送:客户端和服务器双方都可以建立 Stream,减少消息传递次数。
👉HTTP/3
- 把 HTTP 下层的 TCP 协议改成了 UDP QUIC协议,解决了1.1和2中的队头阻塞问题。
1.1的队头阻塞是在HTTP层,2是在TCP层【因为在单个TCP连接上用了多路复用,受到TCP拥塞控制的影响,少量丢包可能就会导致所有流被阻塞】
无状态的协议如何保存用户状态
通过session和cookie机制协同保存用户的状态。Session的作用就是通过服务端记录用户的状态,当用户进行操作时,服务端给该用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个 Session)。最后通过在 Cookie 中附加一个 Session ID 来方式来跟踪这个Session。如果cookie被禁用的话,可以利用 URL 重写把 Session ID 直接附加在 URL 路径的后面。
【Session具体流程】用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。
HTTPS
与HTTP的区别
HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
HTTPS解决了HTTP的哪些问题
- 混合加密 的方式实现信息的机密性,解决了窃听的风险。
在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。
在通信建立前采用非对称加密的方式交换「会话秘钥」,后续不再使用非对称加密。 - 摘要算法的方式来实现完整性,它能够为数据生成独一无二的标识,用于校验数据的完整性,解决了篡改的风险。
- 将服务器公钥放入到数字证书中,解决了冒充的风险。
HTTPS的握手过程(TLS握手)
- 客户端向服务器发起连接请求,请求建立安全连接。
- 服务器收到客户端的连接请求后,返回一个包含自己的 SSL 证书 的消息,其中 SSL 证书包含了服务器的公钥和其他信息。
- 客户端收到服务器发送的 SSL 证书后,首先会验证证书的合法性。这包括检查证书是否由可信的证书颁发机构(CA)签发,是否没有过期,是否与服务器的域名匹配等。
- 如果证书验证成功,客户端会生成一个随机的对称密钥(称为会话密钥),用于加密通信数据。
- 客户端使用服务器的公钥(从 SSL 证书中获取)对会话密钥进行加密,并将加密后的密钥发送给服务器。
- 服务器收到客户端发送的加密密钥后,使用自己的私钥 (与 SSL 证书对应的私钥)进行解密,得到会话密钥 。
现在,客户端和服务器都拥有了相同的会话密钥,它们可以使用这个密钥来加密和解密通信数据了
WebSocket
WebSocket 是一种基于 TCP 连接的全双工通信协议,即客户端和服务器可以同时发送和接收数据。其本质上是应用层的协议,用于弥补 HTTP 协议在持久通信能力上的不足。客户端和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。优点:报文体积小(因为没有请求头)、支持长连接
TCP 协议本身是全双工的,但我们最常用的 HTTP1.1,虽然是基于 TCP 的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的 websocket 协议。对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用 websocket 协议。
和 HTTP 有什么区别?
- WebSocket 是一种双向实时通信协议,而 HTTP 是一种单向通信协议。
- WebSocket 使用 ws:// 或 wss:// 作为协议前缀,HTTP 使用 http:// 或 https:// 作为协议前缀。
- WebSocket 可以支持扩展,实现部分自定义的子协议,如支持压缩、加密等。
短连接和长轮询
短连接是一种轮询后端的方法:效率低,浪费资源,HTTP协议只能由客户端向服务端发起,所以必须不停连接后端。最常见的应用场景是扫码登录,登录页面二维码出现之后,前端网页根本不知道用户扫没扫,于是不断去向后端服务器询问,看有没有人扫过这个码。而且是以大概 1 到 2 秒的间隔去不断发出请求,这样可以保证用户在扫码后能在 1 到 2s 内得到及时的反馈,不至于等太久,这属于一种【短轮询】。
也可以用【长轮询】HTTP 请求将超时设置的很大,比如 30s,在这 30s 内只要服务器收到了扫码请求,就立马返回给客户端网页。如果超时,那就立马发起下一次请求。RocketMQ的消费者去取数据时也用到了这种方式。现在想要实现服务器主动向客户端推送消息的效果,但是在 HTTP1.1 里。只要客户端不问,服务端就不答。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送 (comet) 的效果,但在一些情况下,这样会使得服务器负担加重,因此有了websoket,能够让服务端主动向客户端推送消息。
ping命令和ICMP
ping
命令用来测试网络中主机之间的连通性和网络延迟。
基于网络层的 ICMP(Internet Control Message Protocol,互联网控制报文协议),其主要原理就是通过在网络上发送和接收 ICMP 报文实现的。
【流程】PING 命令会向目标主机发送 ICMP Echo Request。如果两个主机的连通性正常,目标主机会返回一个对应的 ICMP Echo Reply。 ICMP Echo Request(类型为 8 ) 和 ICMP Echo Reply(类型为 0) 属于查询报文类型 。
DNS
(Domain Name System)域名管理系统,是当用户使用浏览器访问网址之后,使用的第一个重要协议。DNS 要解决的是域名和 IP 地址的映射问题,属于应用层协议,使用UDP传输。先以递归的方式查询本地 DNS 服务器,再以迭代的方式查询其余服务器。
【解析过程】先查询缓存以及硬盘里的hosts文件。请求本地dns服务器,本地dns服务器一般都是网络接入服务器商提供,比如中国电信。本地DNS服务器以迭代的方式请求根域名服务器、顶级域名服务器...最终查询到ip地址。
【to be continue...】