2021-04-19打卡记录

171 阅读14分钟

网络协议

HTTP 与 HTTPS 有哪些区别?

自己的理解: Http是超文本传输协议,Https是安全超文本传输协议;从字面上来看,Https 是对请求报文进行加密后处理的,密文发送请求,而Http是明文发送,之所以Https能够做到密文发送,是因为在传输层建立TCP三次握手之前,会跟服务器建立SSL/TSL安全协议的握手请求。首先向服务器发起加密请求,服务器会返回一个公钥以及一个证书给客户端,客户端生成一个随机值,然后通过公钥进行加密,发送给服务端,服务端收到之后会根据自己的私钥进行解密,完成之后拿到这个随机值,这个随机值就是用来这次加密解密的盐。完成之后就ack给客户端,至此,客户端发送报文数据都得通过公钥进行加密处理。从而达到安全的效果。

Http默认端口是80,而Https默认端口是443,需要申请数字认证 之前有人问过:“https和http相比,就是传输的内容多了对称加密,可以这么理解吗?”

建立连接时候:https 比 http多了 TLS 的握手过程; 传输内容的时候:https 会把数据进行加密,通常是对称加密数据;

参考文档: cloud.tencent.com/developer/a…

TCP 怎么保证可靠传输?

自己的理解: TCP是面向连接的,数据流传输,主要通过它的三次握手和四次挥手,以及传输过程中的ack应答机制,重传机制保证可靠性传输。归结如下几个点:

  • 序列号和确认应答信号
  • 超时重发控制
  • 连接管理
  • 滑动窗口控制
  • 流量控制
  • 拥塞控制

序列号和确认应答信号

发送方在发送数据的时候,会带上自己的序列号,当发送到接受方的时候,会给发送方返回一个ack应答,当发送方接收到ACK应答,即可代表数据发送成功,反之,这条数据就有可能丢失。此时发送方会再次重试发送消息。

而丢失ack应答的情况有两种,第一种是消息没有到达接收方,第二种是ack在返回的途中由于网络原因丢失了。 如果是第一种情况,重新发送数据即可,但是如果是第二种情况,接收方就会出现接收到重复的消息了,反复收到相同的数据可能会是一个”灾难“,既浪费网络资源,还要耗资源对它处理。 所以,我们需要一种机制来识别是否已经接收到了这个数据包、又能够判断数据包是否需要接收。 目标主机反复收到相同数据是不可取的,为了保持数据的一致性,目标主机必须扔掉重复的数据包,那么怎么判断该数据包是已经重复收取过呢?为此我们引入了序列号。 通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输。

超时重发

上面说到,发送方如果超时,会重新发送这条消息,那这个超时是怎么判断的呢? 其实对每个包发送完成之后,都会记录这个包的往返时间和偏差值,将往返时间和偏差值加起来,超时时间就是比这个值稍微大一点的值。 所以这个超时时间不是定死的,是动态波动的,如果超时,就会重发,但是重发有一个次数限制,如果超过这个限制,就代表目标机跟主机失去连接,就会中断。

连接管理

这里解释的就是TCP三次握手和四次挥手机制,具体请看后面

滑动窗口控制

TCP 以1个段为单位,如果每发送一个段进行一次确认应答,才能进行下一次通信,那这样的传输方式有一个缺点,就是包的往返时间(RTT)越长通信性能就越低. 这种方式有点类似于数据库不能并发请求,只能一个挨一个的处理,自然这样的效率肯定是比并发低的

image.png

为解决这个问题,TCP 引入了窗口这个概念。确认应答不是以每个分段来确认,而是以更大的单位进行确认,转发时间将会被大幅地缩短。也就是说,发送端主机,在发送了一个段以后不必要一直等待确认应答,而是继续发送。

image.png

对于滑动窗口有以下几点特点:

  • 上图中的窗口内的数据即便没有收到确认应答也可以被发送出去。不过,在整个窗口的确认应答没有到达之前,如果其中部分数据出现丢包,那么发送端仍然要负责重传。为此,发送端主机需要设置缓存保留这些待被重传的数据,直到收到他们的确认应答。

  • 在滑动窗口以外的部分包括未发送的数据以及已经确认对端已收到的数据。当数据发出后若如期收到确认应答就可以不用再进行重发,此时数据就可以从缓存区清除。

  • 收到确认应答的情况下,将窗口滑动到确认应答中的序列号的位置。这样可以顺序地将多个段同时发送提高通信性能。这种机制也别称为滑动窗口控制。

流量控制

是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止丢失数据包的。 所谓流量控制,就是让发送端不要发送的过快,让接收端能来得及接收

假设没有流量控制,发送端根据自己的实际情况发送数据,如果发送的速度太快,导致接收端的接收缓冲区很快填满了,此时发送端如果继续发送数据,接收端处理不过来,这时接收端就会把本来应该接收的数据丢弃,这会触发发送端的重发机制,从而导致网络流量的无端浪费。

所以TCP需要提供一种机制:让发送端根据接收端实际的接收能力控制发送的数据量。这就是所谓的流量控制。

拥塞控制

拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。

什么是拥塞

我们都知道计算机网络中的资源是有限的。某段时间内网络中对资源的需求超过了网络中的可用部分,而导致网络性能下降的情况就是拥塞。

通俗点说就是发送的数据包太多网络中的设备处理不过来,而导致网络性能下降的情况。

TCP 为什么要进行拥塞控制

网络中的路由器会有一个数据包处理队列,当路由器接收到的数据包太多而一下子处理不过来时,就会导致数据包处理队列过长。此时,路由器就会无条件的丢弃新接收到的数据封包。

这就会导致上层的 TCP 协议以为数据包在网络中丢失,进而重传这些数据包,而路由器又会丢弃这些重传的数据包,如此以往,就会导致网络性能急剧下降,引起网络瘫痪。因此,TCP 需要控制数据包发送的数量来避免网络性能的下降。

拥塞控制原理

有了TCP的滑动窗口控制,收发主机之间即使不再以一个“段”为单位,而是以一个“窗口”为单位发送确认应答信号,所以发送主机够连续发送大量数据包。然而,如果在通信刚开始的时候就发送大量的数据包,也有可能会导致网络的瘫痪。

在拥塞控制中,发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。

发送窗口取拥塞窗口和接收端窗口的最小值,避免发送接收端窗口还大的数据。

拥塞控制使用了两个重要的算法: 慢启动算法, 拥塞避免算法。

慢启动算法

慢启动算法的思路是,不要一开始就发送大量的数据,先试探一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。慢算法中,每个传输轮次后将 cwnd 加倍。

举个例子:一开始发送方设置cwnd=1(为方便理解,这里用报文段的个数作为窗口大小的单位),然后每经过一个传输轮次,cwnd都发加倍,比如1, 2, 4, 8...指数增长

所以,这里的慢启动,不是指拥塞窗口增长慢,而是相对于一开始就上来传输大窗口的数据要显得慢

image.png

拥塞避免算法

拥塞避免算法也是逐渐的增大 cwnd 的大小,只是采用的是线性增长 而不是像慢启动算法那样的指数增长。

具体来说就是每个传输轮次后将 cwnd 的大小加一(加法增大),如果发现出现网络拥塞的话就按照上面的方法重新设置ssthresh的大小(乘法减小,原来的二分之一)并从cwnd=1开始重新执行慢开始算法。

image.png

慢启动算法和拥塞避免算法结合: 问题:在拥塞控制中, 慢启动算法 和 拥塞避免算法 是怎么配合使用的呢?

像上面所说,慢启动算法下的cwnd大小是指数增长,所以不能任 cwnd 任意增长,所以我们引入一个慢启动门限(ssthresh)的阈值来控制 cwnd 的增长。

ssthresh的作用是:

当cwnd < ssthresh时,使用慢开始算法。 当cwnd > ssthresh时,改用拥塞避免算法。 当cwnd = ssthresh时,慢开始与拥塞避免算法随机

TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?

应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。 TCP和UDP是位于传输层的传输协议。 TCP:面向连接的,需要进行三次握手传输数据,有应答机制,保证消息的传输可靠性,通过四次挥手进行中断请求。面向字节流的。全双工通信。

UDP:非面向连接的,数据不可靠传输,不会进行重试,一般用于实时性比较高的场景,比如视频通话等。 有单播,多播,广播的功能 可以一对一,一对多,多对多。 UDP是面向报文的,发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文 不可靠性 首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。

并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。

image.png

简述 TCP 三次握手以及四次挥手的流程。为什么需要三次握手以及四次挥手?

自己的理解: 三次握手 首先,请求是由客户端发起请求,它会带一个seq标志位和sy同步请求发送给服务端,自己的状态为SYN-SENT状态,此时,称为第一次握手;当服务端收到请求的时候,会返回一个ACK以及seq标志位,ack=客户端的ack+1 SYN = 1返回给客户端,自己进入SYN_RECV状态,此时完成第二次握手;当客户端收到之后,再次返回ACK=1,seq=x+1,ack=y+1给服务端,并且两边状态都进入ESTABLISHED,此时完成第三次握手。

四次挥手 当服务端想要中断连接的时候, 就会发起FIN信号给服务端,服务端收到之后,返回一个ACK应答,稍后再返回一个FIN,然后客户端在返回一个ACK,此时完成断开连接。 详细点:

第一次挥手,客户端放出释放信号FIN=1信号,自己的序列号 seq=u进入最终等待状态FIN-WAIT-1状态

第二次挥手,服务端收到信号后,会返回ACK=1 seq=y ack=u+1 信号,进入关闭等待状态CLOSE-WAIT客户端收到消息进入FIN-WAIT-2状态。

第三次挥手,服务端发出FIN=1的信号,确认标志ACK=1,确认序号ack=u+1,自己的序列号seq=w,服务器进入最后确认LAST-ACK状态

第四次挥手:客户端收到回复后,发送确认标志ACK=1,确认序号ack=w+1,自己的序列号seq=u+1,客户端进入时间等待TIME-WAIT状态,经过2个最长报文段寿命后,客户端CLOSE。服务器收到确认后,立刻进入CLOSE状态。

为什么需要三次握手?

避免服务端资源的浪费 1.首先TCP连接是基于seq序列号进行通信的,三次握手是用来确立双方发送的序列号的起始值,而避免连接复用时无法分辨出seq是延迟或者是旧链接的seq,因此需要三次握手来约定确定双方的初始seq序列号,也就是保证序号完成同步确认。 例如,一个连接请求在发送的过程中超时了,由于网络阻塞的原因,然后重新发送了一个连接请求,此时 这个链接请求跟服务端交互完成之后并且关闭了链接,但是上一次链接这时候才到服务端,如果是是两次握手,此时服务端就会建立连接了,但是客户端那边其实已经舍弃掉这个响应,所以就造成了资源的浪费。

为什么四次挥手

四次挥手主要是ACK响应以及FIN请求是分开发送的。当服务端收到FIN响应的时候,只是表明客户端没有消息要发送了。但是还可以接收数据,服务端这边也可以接受数据并且返回数据给客户端,所以此时只会发送ACK告诉客户端我这边收到你要关闭连接的这个请求了。等数据发送完成之后,就可以发送FIN通知客户端关闭连接。

客户端最后还要等待2MSL

第一:保证客户端最后一次发送的ACK应答到达服务器,站在服务器的角度考虑,已经发送FIN断开请求了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似已经失效的连接请求报文段出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。