TCP

三次握手与四次挥手

tcp3次握手

tcp3次握手

SYN=1 & 设置序列号初始值
ACK: 序列号+1
通过 序号(发送序号)ACK号(返回ack号) 可以确认接收方是否收到网络包

第1次发送: client --> server (client序列号初始值

第2次发送: server --> client (ACK号 + server序列号初始值

第3次发送: client --> server (ACK号)


TCP的4次挥手

4次挥手

TCP的三次握手与四次挥手(详解+动图


3次握手,为什么客户端最后还要发送一次确认

简言之:

主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
通俗讲就是: 客户端第一次的连接请求因为网络延时没有发送到服务器,然后又发送了第二次连接请求,当第二次的请求过程整个过程都结束后,第一次的连接请求到达了服务器。如果是2次握手,则会导致错误

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。


为什么客户端最后还要等待2MSL

简言之:

  1. 如果网络延时导致client发出的最后ACK没有到达server,则服务器会重发,2MSL可以保证client可以接收到server重发的报文。

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

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


为什么建立连接是三次握手,关闭连接确是四次挥手呢?

简言之:

建立连接时: 服务器是将ACK+SYN一起发送客户端;
关闭连接时: 服务器将ACK和SYN分开发送到客户端,一次多了一次。
之所以分开发,是因为客户端请求关闭时,服务器的数据可能没有发送完,服务器可以先应答在关闭

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次


TCP的滑动窗口机制与流控介绍

[通俗易懂]深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

滑动窗口: 发送一个包之后,不等待ACK号返回,而是直接发送后续的一系列包。这样一来,等待ACK号的这段时间就被有效利用了。

问题:如果不等待ACK号返回就连续发包,如何处理发送频率 大于 处理能力

滑动窗口基本思路: 接收方需要告诉发送方自己最多能接收多少数据(窗口大小),然后发送方根据这个值对数据发送进行控制。