TCP的三次握手与四次挥手

三次握手与四次挥手

TCP的三次握手与四次挥手

TCP三次握手的流程:

第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=x,并将数据包发送给服务端,客户端进入SYN_SENT状态,等待服务器端确认

第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。

第三次握手:客户端收到确认之后,检查ack是否为x+1,ACK是否为1,如果正确将ACK置为1,ack=y+1,并将该数据包发送给服务端,服务端检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功。客户端和服务端均进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

TCP的三次握手与四次挥手

四次挥手的过程:

第一次挥手:客户端发送一个FIN=1的标识,用来关闭客户端到服务端的数据传输,同时发送了一个随机***seq=x客户端进入FIN-WAIT-1状态

第二次挥手:服务端收到FIN后,向客户端发送ACK=1,一个随机***seq=y,ack=u+1,此时服务端进入进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态(此时相当于TCP连接处于半关闭的状态,客户端不能向服务端发送数据,但是服务端可以向客户端发送数据)

第三次挥手:服务端关闭与客户端的连接,发送FIN=1,ACK=1,seq=w,ack=u+1报文段给客户端,并进入LAST-ACK状态

第四次挥手:客户端发送确认报文段给服务端后,服务端进入CLOSED状态,客户端进入TIME-WAIT状态,等待2MSL后进入CLOSED状态,TCP连接释放,四次挥手结束

TCP的扩展问题

1、TCP为什么是三次握手,改成两次握手可以吗?为什么?

 tcp三次握手目的是为了防止已经过期的连接再次连接上。

  考虑一种情况,在网络拥堵的情况下,如果CLI 向 SER发送连接请求1, 但是连接请求SYN1没有及时到达。这时候CLI以为SYN1丢失,会再次发送连接请求SYN2。当SYN2到达的时候,SER回复ACK,,基于两次握手,CLI和SER连接成功,当CLI和SER数据传输完成之后,两者断开连接。而在连接已经断开之后,SYN1到达SER,SER回复ACK,两者再次连接成功。

2、TCP释放连接可以可以改成三次挥手?为什么?

不可以,三次挥手代表,当SER收到CLI的FIN1时候将ACK和FIN2同时发送给CLI,CLI回复ACK2,完成三次挥手。 如果这样则相当于在四次挥手基础上去掉了SER收到FIN1回复ACK后的CLOSE_WAIT状态,那么如果SER发送缓冲区或者网络节点上还有发送给CLI未发送完成的数据,而且FIN2先于数据到达CLI,会造成数据的丢失。

3、TCP的可靠性如何保证?

 1)将数据阶段为合理的长度

     应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度将保持不变。 

2)超时重发

     当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

3)对于收到的请求,给出确认响应

     当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒 。 (之所以推迟,可能是要对包做完整校验)

4、)校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据

      TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。 

5) 对失序数据进行重新排序,然后才交给应用层

      既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。 

6)对于重复数据,能够丢弃重复数据

     既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。

7)TCP可以进行流量控制,防止较快主机致使较慢主机的缓冲区溢出

     TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。TCP使用的流量控制协议是可变大小的滑动窗口协议。 

4、为什么在四次挥手过程中,客户端进入TIME_WAIT状态时要等待2MSL?

1)为了保证客户端发送的最后一个ACK报文段能够到达服务端。这个ACK报文段有可能会丢失,因而处于LAST_ACK状态的服务端收不到已经发送的FIN+ACK报文段的确认。服务端会超时重传这个FIN+ACK报文段,而客户端就有可能在2MSL时间之内收到这个重传的FIN+ACK报文段。如果客户端在TIME_WAIT状态的时候不等候一段时间,而是在发送完ACK确认报文段之后直接释放连接,那么此时就无法收到客户端超时重传的FIN+ACK报文段,因此也不会再发送一次确认报文段,那么服务端就无法进入CLOSED状态。

2)客户端在发送完ACK报文段之后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都会从网络中消失,这样就可以使得下一次新的连接中不会出现这种旧的连接请求的报文段。