notion image

HTTP:

从输入网站URL到网站显示,期间发生了什么?

1.URL解析:
首先浏览器做的第一步工作就是要对 URL 进行解析,包括协议域名等
2.DNS解析:
浏览器需要将域名解析为 IP 地址
浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」:从根域开始查
3.TCP连接:
建立TCP连接,浏览器使用域名对应的 IP 地址与服务器建立 TCP 连接
4.发起 HTTP 请求
浏览器通过建立的 TCP 连接向服务器发送 HTTP 请求
5.服务器处理请求
服务器处理请求
6.服务器返回HTTP响应
并将处理结果封装成 HTTP 响应
6.浏览器接收到 HTTP 响应
根据状态码判断请求是否成功。如果成功,浏览器会继续处理响应内容。
7.浏览器显示HTML

HTTP:超文本传输协议

notion image
403 Forbidden 表示服务器禁止访问资源
404 not Found 服务器找不到资源
502 Bad Gateway 后端服务器错误
503 Service Unavailable 服务器当前忙碌

GET 与POST的区别

Get:从服务器获取指定的资源,是安全且幂等的,常用于请求数据
post:是根据负载对指定的资源做出处理,是不安全不幂等的,常用于传输数据

HTTP的缓存技术

对于一些具有重复性的 HTTP 请求,比如每次请求得到的数据都一样的,我们可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据,不必在通过网络获取服务器的响应了
  • 强制缓存
强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存。
  • 协商缓存
协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。
ETag(实体标签):服务器检测到新的请求中的ETag值与当前资源的ETag值相同,说明资源没有变化
Last-Modified(最后修改时间):如果服务器检测到新的请求中的Last-Modified值与当前资源的最后修改时间相同

HTTP的特性?

简单,灵活和易于扩展,应用广泛和跨平台
HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,
1. 无状态
好处:减轻服务器的负担
坏处:无记忆能力完成有关联性的操作时会非常麻烦
cookie:相当在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了
2.明文传输
好处:便于抓包 坏处:不安全
3.不安全,容易被监听,篡改,冒充

HTTP与HTTPS的区别?

  • HTTPS 在 TCP 和 HTTP 之间加入了 SSL/TLS 安全协议
  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443
notion image
HTTP因为是明文传输,存在三种风险:窃听,篡改,冒充风险
HTTPS 是如何解决上面的三个风险的?
  • 混合加密的方式实现信息的机密性,解决了窃听的风险。
  • 摘要算法的方式来实现完整性,解决了传输内容被篡改的风险。
  • 将服务器公钥放入到数字证书中,解决了冒充的风险
1.混合加密
HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:
  • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。
对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发私钥保密,解决了交换问题但速度慢
2.摘要算法+数字签名
为了保证传输的内容不被篡改,我们需要对内容计算出一个「指纹」,然后同内容一起传输
对方收到后,先是对内容也计算出一个「指纹」,然后跟发送方发送的「指纹」做一个比较
计算机里会用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「指纹」
(内容不会被篡改,但不能保证这个消息是来自与客户端)
数字签名算法:为了处理这一问题通过「私钥加密,公钥解密」的方式,对内容的哈希值加密,来确认消息的身份
3.数字证书
notion image
 
 

HTTPS 是如何建立连接的?其间交互了什么?

  • 客户端向服务器索要并验证服务器的公钥。
  • 双方协商生产「会话秘钥」。
  • 双方采用「会话秘钥」进行加密通信。
1. ClientHello
首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。
在这一步,客户端主要向服务器发送以下信息:
(1)客户端支持的 TLS 协议版本,如 TLS 1.2 版本。
(2)客户端生产的随机数(Client Random),后面用于生成「会话秘钥」条件之一。
(3)客户端支持的密码套件列表,如 RSA 加密算法。
2. SeverHello
服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:
(1)确认 TLS 协议版本,如果浏览器不支持,则关闭加密通信。
(2)服务器生产的随机数(Server Random),也是后面用于生产「会话秘钥」条件之一。
(3)确认的密码套件列表,如 RSA 加密算法。
(4)服务器的数字证书。
3.客户端回应
客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。
如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
(1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。
(2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
4. 服务器的最后回应
服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。
然后,向客户端发送最后的信息:
(1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
至此,整个 TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。

HTTPS如何优化?

HTTPS 相比 HTTP 协议多一个 TLS 协议握手过程:目的是为了通过非对称加密握手协商或者交换出对称加密密钥
优化方式:
1.硬件优化
2.软件优化
3.协议优化
选用ECDHE密钥交换算法:将消息往返从2RRT减少到1RRT,安全性也较高
选用TLS1.3,完成握手只要1RRT, 即客户端发送 ClientHello 消息后,只需等待服务器的回应就可以开始加密数据的发送。
notion image
4.证书优化
在线证书状态协议Online Certificate Status Protocol)来查询证书的有效性
5.会话复用(设定过期时间应对重放攻击)
把首次 TLS 握手协商的对称加密密钥缓存起来,待下次需要建立 HTTPS 连接时,直接「复用」
  • Session ID,服务器在握手阶段为每个会话生成一个唯一的Session ID,客户端在后续请求中发送这个Session ID给服务器。服务器通过匹配Session ID找到之前的会话状态
  • Session Ticket,服务器生成一个Session Ticket,其中包含了会话状态的一部分,并将其发送给客户端。客户端在后续请求中携带这个Session Ticket,服务器可以解密其中的信息来恢复会话状态,从而避免完整的握手过程。

HTTP1.1的优化是什么?

  • 使用长连接的方式改善重复连接造成的性能开销(Keep-Alive)
  • 支持管道网络传输,第一个请求发出不需要等待其返回就可以发送第二个请求出去,解决了请求的队头阻塞
性能瓶颈:
1.没有进行头部压缩
2.服务器按请求响应,如果响应速度较慢就会产生响应队头阻塞
3.没有请求优先级控制
4.请求只能从客户端开始,服务器只能被动响应

HTTP2的优化是什么?

HTTP/2协议是基于HTTPS的,因此HTTP/2的安全性也是有保障的
1.头部压缩
如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分
2.二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式。
3.并发传输
针对不同的 HTTP 请求用Stream ID 来区分接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并行交错地发送请求和响应。
4.服务器主动推送资源
服务端不再是被动地响应,可以主动向客户端发送消息。
性能瓶颈:
HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞 ,一旦发生丢包,就会阻塞住所有的 HTTP 请求,这属于 TCP 层队头阻塞。

HTTP3的优化是什么?

HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP,解决了TCP引起的队头阻塞问题
基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输
  • 支持乱序确认但不影响数据包的正确组装

  • 同样支持拥塞算法

  • 流量控制
1.每个Stream里面都有独立的滑动窗口来进行流量控制
2.限制所有Stream相加起来的总字节数

  • 无队头阻塞
多个Stream相互独立,当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题

  • 更快的连接建立
QUIC 内部包含了 TLS,QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商

  • 连接迁移不需要重新连接
基于 TCP 传输协议的 HTTP 协议,由于是通过四元组确定一条 TCP 连接
notion image
QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID 来标记通信的两个端点
即使ip地址变化了只要保留上下文信息,就可以无缝的复用原连接

HTTP和WebSocket的区别

HTTP是一种请求-响应模式的半双工协议
WebSocket是全双工的协议,服务器可以主动给客户端发送消息,适用于实时性要求高的应用
WebSocket的连接是持久性的,直到一方关闭连接

TCP:

TCP的基本概念:

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议
面向连接:一定是「一对一」才能连接。
可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证数据无差错无重复有序的到达
字节流:数据在传输过程中被视为连续的字节流
TCP通过四元组可以确定一个连接,其四元组包括如下:
notion image
TCP的最大连接数=客户端IP数×客户端的端口数

字节流:
用户通过TCP协议传输时,消息可能会被操作系统分组成多个TCP报文,因此我们不能认为一个用户消息对应一个TCP报文,所以TCP是面向字节流的协议
如何解决粘包:
出现粘包的问题是因为不知道用户消息的边界在哪,如果知道边界在哪,接收方就可以通过边界来划分有效的用户消息
  • 固定长度的消息
  • 特殊字符作为边界:如HTTP,使用回车符,换行符作为HTTP报文的边界
  • 自定义消息结构体(QT云盘)

可靠传输:
1.确认和重传:接收方收到报文就会确认,发送方发送一段时间没有收到确认就会触发重传
2.数据校验:TCP报文头有校验和,用于校验报文是否损坏。
3.数据合理分片和排序:tcp会按最大传输单元(MTU)合理分片,接收方会缓存未按序到达的数据,重新排序后给应用层
4.流量控制:通过滑动窗口来控制发送方的数据速率,防止包丢失
5.拥塞控制:当网络拥塞时,通过拥塞窗口,减少数据的发送,防止包丢失。

TCP和UDP的区别

1.连接
  • TCP 是面向连接的传输层协议,传输数据前先要建立连接。
  • UDP不需要连接,即刻传输数据
2.服务对象
  • TCP是一对一的两点服务
  • UDP支持一对一,一对多,多对多的通信
3.可靠性
  • TCP是可靠交付数据的,数据无差错不重复有序的到达
  • UDP是尽最大努力交付,不保证可靠交付数据,但是QUIC协议除外
4.拥塞控制丶流量控制
  • TCP有拥塞控制和流量控制机制,保证数据传输的可靠安全性
  • UDP即使网络拥堵,也不会影响其发送速率,但是会提高其丢包的概率
5.首部开销
  • TCP的首部是长度较长,会有一定的开销
  • UDP的首部是8个字节,固定不变
6.传输方式
  • TCP是流式传输,没有边界,保证顺序和可靠(会导致粘包)
  • UDP是一个包一个包发送的,有边界但是会丢包和乱序
7.分片不同
  • TCP的数据大小如果大于MSS大小,会在传输层进行分片,如果中途丢失了一个分片,也只需要传输丢失的这个分片
  • UDP的数据大小如果大于MTU大小,就要在IP层进行分片,目标主机收到后在IP层组装完之后在给传输层
TCP的应用场景:文件传输(FTP),Web浏览HTTP/HTTPS),数据库操作(MYSQL的连接和查询都是基于TCP的)
UDP的应用场景:实时通讯,流媒体传输,简单查询(DNS查询),广播和多播(UDP支持数据广播和多播)

TCP三次握手的流程?为什么是三次握手?

1.一开始客户端和服务端都是处于close状态,然后服务端主动监听某个端口,处于listen状态
2.客户端发送SYN报文,表示向服务端发起连接,之后客户端处于syn-send状态
3.服务端收到客户端的SYN报文后,向客户端返回SYN以及ACK报文,之后服务端处于syn-rcvd状态
4.客户端接收到报文后,向服务端回应最后一个ACK报文,之后处于ESTABULISHED状态
5.服务器收到ACK报文后,也进入ESTABLISHED状态,连接建立
第三次握手是可以携带数据的,前两次握手是不可以携带数据的
三个方面分析三次握手的原因:
  • 三次握手才可以阻止重复历史连接的初始化(主要原因)
若网络阻塞,旧的SYN报文会比新的SYN报文先到达服务端,在三次连接的情况下,客户端会确认自己收到的ACK号是否正确,两次连接则不行
  • 三次握手才可以同步双方的初始序列号(延伸问题:为什么序列号要求不一样)
客户端发送「初始序列号」给服务端需要服务端确认接收,服务端的「初始序列号」给客户端也需要确认接收,一来一回才能保证双方序列号同步
  • 「两次握手」:无法防止历史连接的建立,就会因为多余的连接造成双方资源的浪费,也无法可靠的同步双方序列号;
  • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
notion image

TCP握手丢失了会发生什么情况?

1.第一次握手丢失:
会触发超时重传机制,客户端重传的SYN报文的序列号是一致的,每次超时的时间是上一次的 2 倍
当超时重传次数到达最大次数还没有收到第二次握手,客户端就会断开连接
2.第二次握手丢失:
• 客户端会重传 SYN 报文,也就是第一次握手,最大重传次数由 tcp_syn_retries内核参数决定;
• 服务端会重传 SYN-ACK 报文,也就是第二次握手,最大重传次数由 tcp_synack_retries 内核参数决定。
3.第三次握手丢失:
ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文
因此服务端会重传SYN-ACK报文,若已达最大重传次数还没收到第三次握手,那服务端就会断开连接

SYN攻击是什么?如何避免SYN攻击?

Linux内核在TCP三次握手的时候会维护两个队列:
notion image
  • 半连接队列,也称 SYN 队列;(队列/链表:先入先出)
  • 全连接队列,也称 accept 队列; (somaxconn 和 backlog中的最小值) (是个队列/链表:先入先出的原则)
SYN 攻击方式最直接的表现就是把TCP 半连接队列打满,当 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接
Linux 有个参数可以指定当 TCP 全连接队列满了会使用什么策略:0(丢掉),1(回复RST)
避免 SYN 攻击方式,可以有以下三种方法:
  • 增大 TCP 半连接队列;
  • 开启 tcp_syncookies:直接绕开SYN半连接来建立连接
  • 减少 SYN+ACK 重传次数:减少 SYN-ACK 的重传次数,以加快处TCP 连接断开。

为什么每次TCP建立连接的初始化序列号要求都不一样?

四次挥手会让历史报文消失,但是不能保证每次连接都能通过四次挥手来正常关闭连接
1.为了防止历史报文被下一个相同四元组的连接接收
如果每次建立连接,客户端和服务端的初始化序列号都是一样的话,很容易出现历史报文被下一个相同四元组的连接接收的问题
2.为了防止黑客伪造相同的序列号TCP报文被对方接收
其序列号是通过ISN随机算法生成的。基于时钟计数器递增

为什么IP层会分片,TCP层还需要MSS分片呢?

  • MTU:一个网络包的最大长度,以太网中一般为 1500 字节;
  • MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度
因为IP层并没有超时重传机制,如果一个IP分片丢失,整个IP报文的分片都要重传
因此为了达到最佳效率,TCP建立连接的时候需要协商双方的MSS值,当发现数据超过MSS时,就先进行分片,这样也不可能超过MTU

TCP四次挥手的流程?为什么是四次挥手?

notion image
  • 客户端打算关闭连接,向服务器发送FIN报文,之后客户端进入FIN_WAIT_1状态
  • 服务器接收到该报文后,向客户端发送ACK应答报文,接着服务器进入close_wait状态
  • 客户端收到ACK报文后,进入FIN_WAIT_2状态
  • 服务器处理完数据后,向客户端发送FIN报文,并进入last_ack状态
  • 客户端收到服务端的FIN报文后,回应一个ACK报文,之后进入Time_wait状态
  • 服务端收到ACK报文后,进入close状态,至此服务器已完成连接的关闭
  • 客户端在经过2MSL一段时间后,自动进入close状态,至此客户端完成连接的关闭
主动关闭连接的,才有 TIME_WAIT 状态
客户端向服务器发送FIN时,仅仅表示客户端不再发送数据了,但是还能接收数据
服务器收到FIN,先回应一个ACK报文,此时服务器可能还有数据需要处理和发送,等服务器不再发送数据时,才发送FIN报文给客户端表示断开
也就说服务器的ACK和FIN需要分开发送,因此需要四次挥手,但是当服务器没有数据发送且开启了TCP延迟确认机制的时候,可以变成三次挥手

TCP挥手丢失了会发生什么情况

1.第一次挥手丢失
触发超时重传机制,客户端重传FIN报文,若已达最大重传次数再等待一段时间后还是没有收到服务器的第二次挥手,客户端就断开连接
2.第二次挥手丢失
因为ACK报文不会重传,还是客户端重传FIN报文
3.第三次挥手丢失
服务端重传FIN报文,若已达最大重传次数后再等待一段时间还没收到客户端的四次挥手,服务端就断开连接
客户端在收到二次挥手后进入fin_wait2状态,这个状态是有时间限制的,若再tcp_fin_timeout时间内没有收到三次挥手,客户端断开连接
4.第四次挥手丢失
服务端重传FIN报文,若已达最大重传次数后再等待一段时间还没收到客户端的四次挥手,服务端就断开连接
客户端在收到三次挥手进入Time_wait状态,开启2MSL的定时器,如果再次收到三次挥手就重置定时器,在等待2MSL后客户端断开连接

为什么需要TIME_WAIT的状态

TIME_WAIT是主动关闭连接方才会出现状态,一般经过2MSL时间后,变成close状态
MSL:报文最大生存时间,linux将MSL设置为30S,也就是意味着数据报文经过64个路由器时间不会超过30S,超过就消失在网络中
TTL:经过路由跳数,一般是64
TIME_WAIT=2MSL的原因是网络中存在来自发送方的数据包,发送方的数据包被接收方处理后又会向对方发送响应,一来一回需要2倍的时间
在2MSL的时长里至少允许报文丢失一次,是从收到FIN发送ACK开始即使的,若ACK没有传输到服务器,触发重传后2MSL将重新计时

需要 TIME-WAIT 状态,主要是两个原因:
  • 为了防止历史连接中的数据,被后面相同四元组的连接错误的接收,因此 TCP 设计了 TIME_WAIT 状态,状态会持续 2MSL 时长,这个时间足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是新建立连接所产生的。
  • 等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭,在2MSL中起码允许报文丢失一次

TIME_WAIT状态过多的危害:
  • 第一是占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等;(服务端)
  • 第二是占用端口资源,端口资源也是有限的(客户端)

如何优化TIME_WAIT:
  • 复用处于 TIME_WAIT 的 socket 为新的连接所用
  • 当系统中处于 TIME_WAIT 的连接一旦超过这个值时,系统就会将后面的 TIME_WAIT 连接状态重置

服务器出现大量TIME_WAIT的原因有哪些:
服务器如果出现大量TIME_WAIT状态的TCP连接,那说明服务器主动断开了很多TCP连接
1.HTTP没有使用长连接机制,查看客户端和服务端是否都使用了HTTP KEEP-ALIVE
2.HTTP长连接超时,是否是网络状态
3.HTTP 长连接的请求数量达到上限:调大处理客户端请求的最大值即可
 

Socket编程

notion image
  • 服务端和客户端初始socket,得到文件描述符
  • 服务端调用bind,将socket绑定在指定的IP地址和端口
  • 服务端调用listen,进行监听(如果没有监听直接发起连接建立,服务端会发送RST报文)
  • 服务端调用accept,等待客户端连接
  • 客户端调用connect,向服务端的地址和端口发起连接请求(三次握手)
  • 服务器accept返回用于传输的socket文件描述符
  • 客户端用write写入数据,服务端用read读取数据
  • 客户端断开连接时,会调用close,那么服务器read读取数据时,读到eof,待处理完毕数据后,调用close,表示连接关闭
「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket

notion image
客户端 connect 成功返回是在第二次握手,服务端 accept 成功返回是在三次握手成功之后。

客户端调用close之后,连接断开的流程是:
notion image

accept只负责在全连接队列取出一条连接,本身和三次握手毫无关系,因此没有accept也能建立TCP连接
两个客户端同时向对方发出请求建立连接(TCP自连接),所有没有listen只能建立自连接,无法正常建立连接

TCP的重传机制

1.超时重传:设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据
每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍
2.快速重传:以数据为驱动,当收到三个相同的ACK报文时,会重传丢失的报文段
问题:在于不知道丢失的是哪一个报文,无法确定重传的报文是哪一个
notion image
3.Sack方法选择性确认重传
这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据
4.D-SACK:主要是用于指示接收方收到了重复的数据段,从而可以帮助发送方更精确地识别和处理数据段的重传

TCP的滑动窗口概念

Tcp的传输模式需要一应一答,这样的缺点是:往返时间越长,通信的效率就越低
为解决这个问题,TCP 引入了窗口这个概念
窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值

TCP 头里有一个字段叫 Window,也就是窗口大小,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。
所以,通常窗口的大小是由接收方的窗口大小来决定的
并不是完全相等,接收窗口的大小是约等于发送窗口的大小的。

TCP的流量控制

TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制
TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报

TCP的拥塞控制

流量控制是避免发送方的数据填满接收方的缓存,并不知道网络中发生了什么
拥塞控制是避免发送方的数据填满整个网络

拥塞窗口( cwnd)是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的
  • 只要网络中没有出现拥塞,cwnd 就会增大;
  • 但网络中出现了拥塞,cwnd 就减少;
发生了超时重传,就会认为网络出现了拥塞

1.慢启动:发送方每收到一个ACK,拥塞窗口的cwnd大小就会加1,当cwnd到达慢启动门限时,使用拥塞避免算法
2.拥塞避免算法:发送方每收到一个ACK,cwnd增加1/cwnd,随着窗口继续增长,当网络拥塞的时候触发重传
3.拥塞发生算法:当触发重传时的算法
  • 超时重传
当初发超时重传时候,拥塞发生算法将慢启动门限变成1/2,cwnd重置
  • 快速重传
当发生快速重传时候,拥塞发生算法将cwnd/2,并且慢启动门限=cwnd,进入快速恢复算法
4.快速恢复(将重传的数据快速发给目标,然后进入拥塞避免算法)
  • 拥塞窗口将cwnd=ssthresh+3
  • 重传丢失的ACK,cwnd+1
  • 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh

TCP的缺陷

  • TCP 建立连接的延迟:每次都要经过三次握手,但是可以通过Fast TCP OPEN解决,可以在第二次连接的时候减少时延
notion image
  • TCP 存在队头阻塞问题
因为TCP 层必须保证收到的字节数据是完整且有序的,一旦TCP丢包,整个TCP都要等待重传,就会阻塞TCP连接中的请求
  • 网络迁移需要重新建立TCP连接(依赖四元组)
当移动设备的网络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建立 TCP 连接
  • 面向字节流导致的粘包问题
  1. 使用特殊的分隔符
  1. 固定长度的数据包

如何优化TCP

三次握手
1.修改 SYN 的重传次数
2.调整SYN半连接队列的长度
3.修改SYN+ACK报文的重传次数
4.调整accept队列长度
5.使用TCP Fast Open绕过三次握手(COOKIE)

四次挥手
客户端和服务端双方都可以主动断开连接,通常先关闭连接的一方称为主动方,后关闭连接的一方称为被动方。
1.调整FIN报文重传的次数
2.调整FIN_WAIT2状态的时间
3.调整time_wait状态的上限个数:当 TIME_WAIT 的连接数量超过该参数时,新关闭的连接就不再经历 TIME_WAIT 而直接关闭
4.复用time_wait状态的连接(客户端)

传输数据优化
扩大滑动窗口大小(内核缓冲区决定了其上限)
调节发送缓冲区的范围
调整接收缓冲区的范围

如果已经建立了连接,客户端/服务端出现了问题怎么办?

服务端不发送数据:
1.如果客户端出现了故障的情况下,如果服务端一直不将数据发送给客户端,那服务器是一直无法感知到客户端宕机这个事情的。
保活机制:每隔一个时间间隔,发送一个探测报文,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡
心跳机制:设置长连接的超时时间,客户端在完成一个HTTP请求后,60秒之内没有再发起新的请求,就会触发心跳机制释放连接

服务端发送数据:
如果客户端出现了故障的情况下,服务器向客户端发送数据,会出发超时重传,超过最大次数将连接终止

宕机后恢复连接:
如果重新恢复后的四元组与之前的不同,服务器会新建立连接,旧的连接按1处理
如果是相同四元组,处于 Established 状态的服务端收到SYN报文,会回复一个ACK报文,客户端收到这个ACK,会发现不是自己期望的,回复RST报文

客户端主机宕机,又迅速重启:
收到之前 TCP 连接的报文,都会回复 RST 报文,以断开连接

拔掉网线后:
拔掉网线后有数据传输:服务器发送数据得不到响应,触发超时重传
1.重传时网线插上,无事发生
2.网线没有插上,超时重传的次数到达设定阈值后,服务端就会断开TCP连接
拔掉网线后没有数据传输:
1.开启了TCP KEEPalive机制,TCP发送探测报文,会关闭连接
2.如果没有开启,TCP连接将会一直保持存在

如果服务端的进程崩溃了,还是能与客户端完成TCP四次挥手的过程

当TCP报文承载数据非常小该如何处理

1.Nagle算法提高传输效率(满足二者其一才可以发送)
  • 要等到窗口大小>=MSS并且数据大小>=MSS
  • 收到之前发送数据的ack回包
notion image
可以看出,Nagle 算法一定会有一个小报文,也就是在最开始的时候

2.TCP延迟确认(解决ACK效率低的问题)
  • 没有数据时ACK延迟一段时间以等待是否有响应数据可以一起发送
  • 当有响应数据要发送时,ACK 会随着响应数据一起立刻发送给对方

如何关闭一个TCP连接?

  • KILL进程
1.在客户端KILL进程,会影响这个客户端所建立的所有进程
2.服务端KILL进程,会导致TCP连接都被关闭

  • 伪造一个「四元组相同」和「序列号是对方期望的」的RST报文
1.killcx工具
2.tcpkill的工具

IP:

IP基本认知

IP 在 TCP/IP 参考模型中处于第三层,也就是网络层:主要实现主机与主机之间的通信,也就是点对点通信。
IP层:负责在「没有直连」的两个网络之间进行通信传输
MAC层:是实现「直连」的两个设备之间通信

IP地址被分类成了五种类型:A类,B类,C类, D类,E类
notion image
A,B,C类地址:主要分为两个部分(网络号和主机号)
notion image
最大主机个数=IP地址变成2进制后0的个数的平方-2
  • 主机号全为1用于广播(同一个链路中相互连接的主机之间发送数据包)
  • 主机号全为0指定某个网络
D,E类地址没有主机号,D类常用于多播,E是预留的分类
notion image
多播用于将包发送给特定组内的所有主机:如最后一排的同学上来做这道数学题
IP分类的优点:简单明了、选路(基于网络地址)简单
缺点:同一网络下没有地址层次,且不能很好的与现实网络匹配

无地址分类CIDR:不再有分类地址的概念,IP地址被划分为两部分(前面是网络号,后面是主机号
比如 10.100.122.2/24,这种地址表示形式就是 CIDR,/24 表示前 24 位是网络号,剩余的 8 位是主机号

还有一种是子网掩码:将子网掩码和 IP 地址按位计算 AND,就可得到网络号(0和1是0,1和1是1)
notion image
子网掩码还可以划分子网,子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址
 

IPv6与IPv4

1.可分配的地址变多了
2.提高了传输的性能
3.提升了安全性

IPv6 地址的标识方法:
IPv4 地址长度共 32 位,是以每 8 位作为一组,并用点分十进制的表示方式。
IPv6 地址长度是 128 位,是以每 16 位作为一组,每组用冒号 「:」 隔开。

IPV6地址的地址类型:
单播地址:用于一对一的通信
组播地址:用于一对多的通信
任播地址:用于通信最近的节点
没有广播地址

IPV6的单播地址类型:
  • 同一链路单播通信,可以使用链路本地单播地址
  • 内网可以使用唯一本地地址
  • 互联网使用全局单播地址

IPv6相当于IPV4的首部改进
  • 取消了首部校验和字段
  • 取消了分片/重新组装相关字段
  • 取消选项字段

IP协议相关技术

DNS:域名解析功能,将域名转换为IP地址
APR协议:已知IP地址求MAC地址
RARP协议:已知MAC地址求出IP地址
DHCP协议:通过DHCP动态获得IP地址
NAT:网络地址转换NAT,即是在对外通信的时候,把公有IP地址转变为私有IP地址
ICMP:互联网控制报文协议,主要确认IP包是否成功送达目标地址,报告发送过程中IP包被废弃的原因和改善网络设置等
  • 查询报文(ping的发送和接收过程):Ping相当于自己组了一个数据包,让系统按其他软件发送数据的路径发一遍
  • 差错报文(traceroute)
IGMP:是因特网组管理协议,工作在主机(组播成员)和最后一跳路由之间

127.0.0.1和localhost以及0.0.0.0区别在哪

127.0.0.1 是回环地址,localhost域名,但默认等于 127.0.0.1
Ping回环地址和ping本机地址都是走的本机网卡(就是把数据插入到一个链表中就软中断通知ksoftriqd来进行收数据,不出网络)
ping 0.0.0.0 会失败,因为在IPV4中表示的是无效目标地址
如果服务器listen 0.0.0.0 ,则表示本机上所有的IPV4地址
ping环回地址可以检查本地的TCP/IP协议栈,ping本地以太网地址可以检查本地的网络适配器是否正常
 

cookies和session的区别:

相同点:都是用来跟踪用户信息的,加快识别用户效率
不同点:
(1)cookie数据存放在客户的浏览器上,session数据放在服务器上
(2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session
(3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
(4)单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。
(5)所以:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中
 
 
Camellia
Camellia
明天会更好吗?🍚
公告
type
status
date
slug
summary
tags
category
icon
password
这里是一个个人博客
用于记录和分享生活