标签:mode 大数据 数据完整性 网络层协议 拒绝访问 多少 pos 随机 协议
问:UDP 与 TCP 的区别是什么?
答:首先 UDP 协议是面向无连接的,也就是说不需要在正式传递数据之前先连接起双方。然后 UDP 协议只是数据报文的搬运工,不保证有序且不丢失的传递到对端,并且UDP 协议也没有任何控制流量的算法,总的来说 UDP 相较于 TCP 更加的轻便。
TCP 基本是和 UDP 反着来,建立连接断开连接都需要先需要进行握手。在传输数据的过程中,通过各种算法保证数据的可靠性,当然带来的问题就是相比 UDP 来说不那么的高效。
问:为什么 TCP 建立连接需要三次握手,明明两次就可以建立起连接?
答:因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。
可以想象如下场景。客户端发送了一个连接请求 A,但是因为网络原因造成了超时,这时 TCP 会启动超时重传的机制再次发送一个连接请求 B。此时请求顺利到达服务端,服务端应答完就建立了请求,然后接收数据后释放了连接。
假设这时候连接请求 A 在两端关闭后终于抵达了服务端,那么此时服务端会认为客户端又需要建立 TCP 连接,从而应答了该请求并进入 ESTABLISHED 状态。但是客户端其实是 CLOSED 的状态,那么就会导致服务端一直等待,造成资源的浪费。
TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
第一次握手:客户端停止发送数据,向服务端发送一个释放连接的报文,FIN 置 1,然后进入 FIN_WAIT-1(终止等待1) 状态。
第二次握手:服务端收到连接释放报文,发回确认报文, ACK 置 1,然后进入 CLOSE-WAIT(等待关闭) 状态,客户端收到确认报文后,会进入 FIN_WAIT-2(终止等待2) 状态。
这时 TCP 连接处于半关闭状态,客户端已经停止发送数据,但服务端可能还会继续发送数据。
第三次握手:当服务端发送完数据后,会向客户端发送 连接释放报文,FIN 置 1,然后进入 LAST-ACK( 最后确认) 状态。
第四次握手:客户端收到连接释放报文后,会发回确认报文, ACK 置 1,然后进入 TIME-WAIT(时间等待) 状态,等到 2MSL(2次最长报文段寿命) 后进入 CLOSE 状态,关闭连接 。服务端收到确认,就进入 CLOSE 状态,连接正式关闭。
问:为什么客户端要进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态?
答:为了保证服务端能收到客户端的确认应答。若客户端发完确认应答后直接进入 CLOSED 状态,如果确认应答因为网络问题一直没有到达,那么会造成服务端不能正常关闭。
正常传输过程
只要 A 向 B 发送一段报文,都要停止发送并启动一个定时器,等待对端回应,在定时器时间内接收到对端应答就取消定时器并发送下一段报文。
报文丢失或出错
在报文传输的过程中可能会出现丢包。这时候超过定时器设定的时间就会再次发送丢失的数据直到对端响应,所以需要每次都备份发送的数据。
即使报文正常的传输到对端,也可能出现在传输过程中报文出错的问题。这时候对端会抛弃该报文并等待 A 端重传。
PS:一般定时器设定的时间都会大于一个 RTT 的平均时间。
ACK 超时或丢失
对端传输的应答也可能出现丢失或超时的情况。那么超过定时器时间 A 端照样会重传报文。这时候 B 端收到相同序号的报文会丢弃该报文并重传应答,直到 A 端发送下一个序号的报文。
在超时的情况下也可能出现应答很迟到达,这时 A 端会判断该序号是否已经接收过,如果接收过只需要丢弃应答即可。
从上面的描述中大家肯定可以发现这肯定不是一个高效的方式。假设在良好的网络环境中,每次发送数据都需要等待片刻肯定是不能接受的。那么既然我们不能接受这个不那么高效的协议,就来继续学习相对高效的协议吧。
在连续 ARQ 中,发送端拥有一个发送窗口,可以在没有收到应答的情况下持续发送窗口内的数据,这样相比停止等待 ARQ 协议来说减少了等待时间,提高了效率。
连续 ARQ 中,接收端会持续不断收到报文。如果和停止等待 ARQ 中接收一个报文就发送一个应答一样,就太浪费资源了。通过累计确认,可以在收到多个报文以后统一回复一个应答报文。报文中的 ACK 标志位可以用来告诉发送端这个序号之前的数据已经全部接收到了,下次请发送这个序号后的数据。
但是累计确认也有一个弊端。在连续接收报文时,可能会遇到接收到序号 5 的报文后,并未接收到序号 6 的报文,然而序号 7 以后的报文已经接收。遇到这种情况时,ACK 只能回复 6,这样就会造成发送端重复发送数据的情况。
在 TCP 中,两端其实都维护着窗口:分别为发送端窗口和接收端窗口,以字节为单位。
发送端窗口包含已发送但未收到应答的数据和可以发送但是未发送的数据。
发送端窗口是由接收窗口剩余大小决定的。接收方会把当前接收窗口的剩余大小写入应答报文,发送端收到应答后根据该值和当前网络拥塞情况设置发送窗口的大小,所以发送窗口的大小是不断变化的。
当发送端接收到应答报文后,会随之将窗口进行滑动
滑动窗口是一个很重要的概念,它帮助 TCP 实现了流量控制的功能。接收方通过报文告知发送方还可以发送多少数据,从而保证接收方能够来得及接收数据,防止出现接收方带宽已满,但是发送方还一直发送数据的情况。
拥塞处理包括了四个算法,分别为:慢开始,拥塞避免,快速重传,快速恢复。
慢开始算法,顾名思义,就是在传输开始时将发送窗口慢慢指数级扩大,从而避免一开始就传输大量数据导致网络拥塞。想必大家都下载过资源,每当我们开始下载的时候都会发现下载速度是慢慢提升的,而不是一蹴而就直接拉满带宽。
慢开始算法步骤具体如下
拥塞避免算法相比简单点,每过一个 RTT 窗口大小只加一,这样能够避免指数级增长导致网络拥塞,慢慢将大小调整到最佳值。
在传输过程中可能定时器超时的情况,这时候 TCP 会认为网络拥塞了,会马上进行以下步骤:
快速重传一般和快恢复一起出现。一旦接收端收到的报文出现失序的情况,接收端只会回复最后一个顺序正确的报文序号。如果发送端收到三个重复的 ACK,无需等待定时器超时而是直接启动快速重传算法。具体算法分为两种:
TCP Taho 实现如下
TCP Reno 实现如下
TCP New Reno 算法改进了之前 TCP Reno 算法的缺陷。在之前,快恢复中只要收到一个新的 ACK 包,就会退出快恢复。
在 TCP New Reno 中,TCP 发送方先记下三个重复 ACK 的分段的最大序号。
假如我有一个分段数据是 1 ~ 10 这十个序号的报文,其中丢失了序号为 3 和 7 的报文,那么该分段的最大序号就是 10。发送端只会收到 ACK 序号为 3 的应答。这时候重发序号为 3 的报文,接收方顺利接收的话就会发送 ACK 序号为 7 的应答。这时候 TCP 知道对端是有多个包未收到,会继续发送序号为 7 的报文,接收方顺利接收并会发送 ACK 序号为 11 的应答,这时发送端认为这个分段接收端已经顺利接收,接下来会退出快恢复阶段。
2xx 成功
3xx 重定向
4xx 客户端错误
5xx 服务端错误
HTTPS 默认使用端口 443
问:TLS 与 SSL 的区别?
答:SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。
TLS:(Transport LayerSecurity,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握手协议。
SSL是Netscape开发的专门用户保护Web通讯的,目前版本为3.0。最新版本的TLS 1.0是IETF(工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,两者差别极小。
HTTPS 还是通过 HTTP 来传输信息,但是信息通过 TLS 协议进行了加密。
TLS 协议位于传输层之上,应用层之下。首次进行 TLS 协议传输需要两个 RTT ,接下来可以通过 Session Resumption 减少到一个 RTT。
在 TLS 中使用了两种加密技术,分别为:对称加密和非对称加密。
对称加密:
对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
这种加密方式固然很好,但是问题就在于如何让双方知道秘钥。因为传输数据都是走的网络,如果将秘钥通过网络的方式传递的话,一旦秘钥被截获就没有加密的意义的。
非对称加密:
有公钥私钥之分,公钥所有人都可以知道,可以将数据用公钥加密,但是将数据解密必须使用私钥解密,私钥只有分发公钥的一方才知道。
这种加密方式就可以完美解决对称加密存在的问题。假设现在两端需要使用对称加密,那么在这之前,可以先使用非对称加密交换秘钥。
简单流程如下:首先服务端将公钥公布出去,那么客户端也就知道公钥了。接下来客户端创建一个秘钥,然后通过公钥加密并发送给服务端,服务端接收到密文以后通过私钥解密出正确的秘钥,这时候两端就都知道秘钥是什么了。
TLS 握手
问:Post 和 Get 的区别?
答:首先先引入副作用和幂等的概念。
副作用指对服务器上的资源做改变,搜索是无副作用的,注册是副作用的。
幂等指发送 M 和 N 次请求(两者不相同且都大于 1),服务器上资源的状态一致,比如注册 10 个和 11 个帐号是不幂等的,对文章进行更改 10 次和 11 次是幂等的。因为前者是多了一个账号(资源),后者只是更新同一个资源。
在规范的应用场景上说,Get 多用于无副作用,幂等的场景,例如搜索关键字。Post 多用于副作用,不幂等的场景,例如注册。
在技术上说:
- Get 请求能缓存,Post 不能
- Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里(当然你想写到
body
里也是可以的),且会被浏览器保存历史纪录。Post 不会,但是在抓包的情况下都是一样的。- URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
- Post 支持更多的编码类型且不对数据类型限制
方法
缺陷
改进
问:HTTP 1.xx 存在的问题?
答:
- 线头阻塞
- 多个 TCP 连接,HTTP 1.xx 版本请求并发依赖于多个TCP连接,建立TCP连接成本很高,还会存在慢启动的问题。
- 头部冗余,首部未压缩,而且每一个请求都会带上 cookie 等完全相同的首部。
- 文本格式,HTTP 1.xx 版本采用文本格式进行传输。
- 只能客户端主动请求。
虽然 HTTP/2 解决了很多之前旧版本的问题,但是它还是存在一个巨大的问题,虽然这个问题并不是它本身造成的,而是底层支撑的 TCP 协议的问题。
因为 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
QUIC
Google 搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,当然 HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC.
虽然 UDP 效率很高,但是并不是那么的可靠。QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,比如多路复用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重传等等功能。这里我们就挑选几个重要的功能学习下这个协议的内容。
多路复用
虽然 HTTP/2 支持了多路复用,但是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,并且传输的单个数据流可以保证有序交付且不会影响其他的数据流,这样的技术就解决了之前 TCP 存在的问题。
并且 QUIC 在移动端的表现也会比 TCP 好。因为 TCP 是基于 IP 和端口去识别连接的,这种方式在多变的移动端网络环境下是很脆弱的。但是 QUIC 是通过 ID 的方式去识别一个连接,不管你网络环境如何变化,只要 ID 不变,就能迅速重连上。
0-RTT
通过使用类似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只需要将之前的缓存传递给服务端验证通过就可以进行传输了。
纠错机制
假如说这次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。
当出现其中的非校验包丢包的情况时,可以通过另外三个包计算出丢失的数据包的内容。
当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
Expires
Expires的值对应一个GMT(格林尼治时间),比如Mon, 22 Jul 2002 11:12:01 GMT
来告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求,会直接从缓存中读取资源内容。
Cache-Control
优先度高于Expires
Last-Modified If-Modified-Since
服务器将资源传递给客户端时,会将资源最后更改的时间以Last-Modified: GMT
的形式加在实体首部上一起返回给客户端。
当要使用缓存时,客户端会带上If-Modified-Since: Last-Modified-value
这个请求首部去询问服务器,缓存是否新鲜,如果服务器返回 304,则直接取缓存使用。
缺陷:Last-Modified 存在一个问题,如果服务器的一个资源被修改了,但其实际内容根本没发生改变,会因为 Last-Modified 的时间匹配不上而返回整个实体给客户端(即使客户端缓存里有一模一样的资源)。
ETag If-None-Match
为了解决 Last-Modefied 存在的问题,HTTP 1.1 还推出了 ETag 首部字段,服务器会通过结合文件内容和算法(一般是hash) 来生成一个唯一值作为 ETag 的值发送给客户端。
当要使用缓存时,客户端会带上If-None-Match: ETag-value
这个请求首部去询问服务器,缓存是否新鲜,如果服务器返回 304,则直接取缓存使用。
注意:ETag 的优先级高于 Last-Modified
WebSocket 的目的是解决网络传输中的双向通信的问题,即实现服务端推送。
请求
为了兼容性,目前 WebSocket 使用 HTTP 来完成握手,请求首部需要携带Upgrade
字段来表示服务器需要使用 WebSocket(ws、wss) 协议来进行通信。
ws 协议默认使用80
端口,wss 协议默认使用443
端口。
GET /chat HTTP/1.1 //必需。
Host: server.example.com // 必需,WebSocket服务器主机名
Upgrade: WebSocket // 必需,并且值为" WebSocket"。
Connection: Upgrade // 必需,并且值为" Upgrade"。
/* 必需,其值采用 base64 编码的随机16字节长的字符序列。 */
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
/* 浏览器必填,防止跨站攻击,浏览器一般会使用这个来标识原始域 */
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat //选填, 可用选项有子协议选择器。
Sec-WebSocket-Version: 13 //必需, 版本。
响应
服务端收到请求会切换协议进行通信,但仍会发回 HTTP 响应报文,其中会携带Sec-WebSocket-Accept
首部,表示同意连接,其值生成如下:
全局唯一(GUID,[RFC4122])标识:258EAFA5-E914-47DA-95CA-C5AB0DC85B11
WebSocket 使用数据帧(文本、二进制)进行通信,将数据分片后,包装成帧发送。
WebSocket 为了保持客户端、服务端的实时双向通信,需要确保客户端、服务端之间的TCP通道保持连接没有断开。然而,对于长时间没有数据往来的连接,如果依旧长时间保持着,可能会浪费包括的连接资源。
但不排除有些场景,客户端、服务端虽然长时间没有数据往来,但仍需要保持连接。这个时候,可以采用心跳来实现。
标签:mode 大数据 数据完整性 网络层协议 拒绝访问 多少 pos 随机 协议
原文地址:https://www.cnblogs.com/guolao/p/11458471.html