1. 请画出三次握手和四次挥手的示意图
2. 为什么连接的时候是三次握手?
- 1.让服务端确认客户端有接受信息的能力
- 2.当一次连接请求延迟到达服务器(此时服务器已断开第二次链接),会开启一个新的tcp连接,服务器返回确认报文后就建立,此时客户端不发送任何信息,
3. 什么是半连接队列?
- 客户端发送完syn,并且服务器接收到报文时,会把这种状态下的请求连接存放入半连接队列
4. ISN(Initial Sequence Number)是固定的吗?
- 根据时间动态生成,tcp三次握手要点之一就是seqNum的交换,让接收方知道接下来要发送的数据以什么样的序列号组装。
5. 三次握手过程中可以携带数据吗?
- 第一二次握手不行,假设第一次可以携带,会导致攻击者发送大量数据的连接请求而不需要估计自己的接收,导致服务器资源占用。第三次握手时对于客户端来说它的连接已经建立了,客户端已经知晓服务端有接收和发送的能力,所以可以携带数据。
6. 如果第三次握手丢失了,客户端服务端会如何处理?
- 服务器会重新发送确认报文(按时间指数间隔),当达到一定次数后,将该连接请求从半连接队列中移除。
7. SYN攻击(洪泛攻击)是什么?
- 服务器资源是在二次握手是分配的(即把该连接请求推入半连接队列),当客户端伪造大量不同ip发送连接请求时,会导致服务器的半连接队列被占满,而无法存放需要的请求,使其丢失。是一种DoS?DDoS攻击。
8. 挥手为什么需要四次?
- 因为客户端发送fin报文后,客户端的可能还残留未发送完的报文,故无法在第二次确认报文发送时立即关闭,需要发起另一个报文来通知客户端(第三次挥手)。
9. 四次挥手释放连接时,等待2MSL的意义?
- TCP是以IP数据报的形式在网络中传输的,而IP数据报存在最大生存时间TTL,使TCP的报文段也存在最大存留时间,即MSL。而客户端发送的最后一次关闭ACK确认报文存在丢失的可能,这时服务器会重新发送FIN-ACK报文(即第三次挥手),如果没有2MSL的等待时间,客户端在第四次报文发送后直接关闭连接,服务端重发的FIN-ACK报文将不会得到响应,会导致服务器无法关闭。2MSL:报文传输一来一回。
10.TCP的重传机制
-
1.超时重传(时间驱动)
在请求发起时设置一个定时器,当超过这个时间未收到确认报文,则重发请求,超时重传事件(RTO)略大于包传输一个往返的时间(RTT),根据网络情况动态计算。每当遇到一次超时重传,会将下一次超时时间设置为之前的两倍,避免频繁重复发送。 -
2.快速重传(数据驱动)
当一个请求丢失时,服务端不会返回下一个请求正确的ack,比如我请求2000~3000的请求报文丢失,服务器未返回本该返回的3001的ack,导致客户端在第二个请求发起时收到的ack仍然是3001,当客户端收到三次同样的ack,就会触发快速重传机制。(在超时时间过期时重传,可以解决超时时间的问题)SACK:为了解决触发重传后不对所有请求进行重传,需要缓存已经收到的数据(需要双方都支持)。
即服务端返回报文中返回一个sack字段用于记录已经收到的数据,通过对比ack可以得到丢失的数据段,就对该数据段进行重传即可。Duplicate SACK:服务器收到请求而发送给客户端的确认报文丢失的情况。
客户端未收到服务器的确认报文,进行重传时发现客户端返回的SACK是重复的,即服务器已经收到的数据,可以知道到底是发出去的请求丢失还是接收方的确认报文丢失
11.TCP的滑动窗口
因为TCP是每发送一个数据,都要进行一次确认应答。当上一个数据包收到应答了, 再发送下一个。这样的回合制交流效率比较低,窗口即无需等待就可以继续发送的请求的最大值。(假设窗口中一个确认报文丢失,那么下一次请求可以通过ack进行确认,若1000的确认报文丢失,下一个请求收到ack是2000,说明服务器收到了1000的数据,无需进行重传,这个模式也叫累计确认或累计应答)。
(窗口大小:TCP请求头中的window字段,由接收方发送给请求方,告诉自己最大能处理请求的能力。)
当接收方收到窗口内请求的确认报文,窗口就会有空余,此时窗口向右滑动对应数量来处理更多请求。(窗口的移动由指向序列号的指针来实现)
发送窗口:
接收窗口:
12.TCP的TCP的流量控制
若发送方无脑的发送数据给接收方,但接收方处理不过来,就会导致重传机制的触发,为了解决这一现象,TCP提供了流量控制的机制,即:让发送方根据接收方的实际接受能力来控制发送数量。(TCP 通过让接收方指明希望从发送方接收的数据大小(窗口大小)来进行流量控制)
窗口关闭: 如果窗口大小为 0 时,就会阻止发送方给接收方传递数据,直到窗口变为非 0 为止,这就是窗口关闭。
当接收方处理完数据后发送给带有可用窗口的ack确认报文给发送方,发送方才会继续发送数据,若该确认报文丢失,会导致发送方一直等待该报文而始终不发送数据,造成思死锁。为了解决这个问题,TCP为每个连接都设置了持续定时器,只要连接一方受到窗口为0的通知,就启动该定时器,定时器超时时会发送一个窗口探测报文来探测窗口,三次探测若还是0,就中断连接。
糊涂窗口综合症: 接收方来不及取出窗口中的数据,一旦有一点空取走了窗口中几个字节的数据,并返回给发送方,发送方会立即再次发送数据,而TCP和IP请求头就有好40字节,为了传输几个字节没有必要,这就是糊涂窗口综合征。 解决该问题有两种方式:1.让接收方不发送小的窗口给发送方,2.让发送方不发送小的数据量(通过设置窗口和数据最小值控制实现)
13.TCP的拥塞控制
流量控制是为了避免发送方数据填满接收方,拥塞控制是为了避免发送方的数据填满整个网络(因为计算机可能处在共享的网络环境中,可能会因为其他主机之间的通信使得网络拥堵。)
通过拥塞窗口实现,拥塞窗口 = min(发送窗口,接收窗口),网络越拥堵,拥塞窗口就越小也就是只要发生了超时重传,就可以认为网络出现了拥堵。
拥塞控制的四个算法:
1.慢启动
即TCP连接建立后,一点一点提高发送数据包的数量,当发送方每收到一个 ACK,拥塞窗口的大小就会加 1。
2.拥塞避免
慢启动若不限制,会导致发送数据包的数量指数增长,
所以设置一个慢启动门限(一般是65535字节),
当超过这个额门限,就进入拥塞避免:每当收到一个 ACK 时,cwnd 增加 1/cwnd,
自此开始转为线性增长
3.拥塞发生
随着前两种一直增长,还是会导致网络拥堵,
此时进入拥塞发生(也就是会发生数据包重传):通过动态控制拥塞窗口和慢启动门限来减少发送的数据包数量。
(超时重传和快速重传的拥塞发送算法是不同的)
4.快速恢复
快速重传和快速恢复一般一起使用,快速恢复算法是认为,
你还能收到 3 个重复 ACK 说明网络也不那么糟糕,
所以没有必要像超时重传那么强烈得减少发送数据包的数量,
所以会设置能发送的数据包数量为一个相对多的阶段,而不是一下子减少很多,后续让然线性增长。
(超时重传会一下子减少到慢启动门限以下,后续指数增长)。