4

TCP三次握手和四次挥手

 2 years ago
source link: https://blog.csdn.net/weixin_45674389/article/details/118859416
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

如果不了解TCP报文的格式可以点击这里

三次握手在这里插入图片描述

第一次握手:由客户端主动发起连接建立请求,发送数据包,将SYN置为 1 ,通常叫做发送SYN包,并且随机产生一个值:seq = J,然后将数据包发送给服务端,客户端进入SYN_SENT状态,等待服务端的确认

第二次握手: 服务端收到SYN报文,对该报文进行回复,将报文的标志位SYN和ACK都置为 1 ,确认应答序号ack = J + 1,同样随机产生一个值seq = K,将数据报发送给客户端,服务端进入SYN_RCVD的状态

第三次握手: 客户端接收到数据包之后检查ACK是否为 1 、ack是否为J + 1,如果正确,那么将ACK位置 1 ,ACK = K + 1,然后发送给服务端,此时客户端的状态变为ESTABLISHED,数据报到服务端,经过同样的检测,如果正确,服务端也变为ESTABLISHED,此时可以正常交换数据通信

简单的说:三次握手由客户端发起,客户端发送一个SYN包,服务端发送一个SYN+ACK包,客户端再发送一个ACK包,三次握手建立成功

在这里插入图片描述
第一次挥手: 客户端发送一个FIN包来断开连接,并停止数据发送,客户端进入FIN_WAIT_1状态。
注意:TCP规定,FIN报文段即使不携带数据,也需要消耗掉一个序列号

第二次挥手: 服务端收到一个FIN包,回复一个ACK,确认序号需要进行加一操作,因为FIN包需要消耗一个序号。此时客户端进入CLOSE_WAIT转态,此时服务端依旧可以进行数据的发送,客户端依然有数据到来是要接收的,这个状态需要持续一段时间,这个时间就是CLOSE_WAIT状态的持续时间。
客户端接收到服务端的确认请求之后客户端进入FIN_WAIT_2状态,等待服务端发送FIN包

第三次挥手: 服务端将最后的数据都发送给客户端,然后发送一个FIN包,随即进入LAST_ACK状态

第四次挥手: 客户端收到来自服务端的FIN包,需要发出确认包,当确认包发出之后状态变为TIME_WAIT
注意:这个时候TCP连接还没有释放,需要经过 2 * MSL个时间才能释放,这个时候才进入CLOSED的状态
服务端只要收到了来自客户端的ACK包,就进入CLOSED的状态

思考为什么建立连接是三次,不是 俩次?
Client发送一个SYN请求包,Server回复一个ACK确认包,这不就建立好连接了吗?是的,这样可以建立连接,但是并不安全,比如说这个情况:
一、Client发送了一个SYN请求报文,但是由于网络拥塞,导致SYN包在网络中滞留了很久,而Client并没有进行一个SYN的重传,那么这个SYN包就作废了,而在作废之后到到Server,Server会当做是Client发来的请求,然后回复一个ACK,此时Server认为连接建立好了,而Client收到ACK并不会理睬,Server还在等着接受数据就会浪费一定的资源。
二、当Server收到SYN包回复一个ACK之后认为连接建立成功,但是如果ACK数据报丢失,那么连接并没有建立,只是Client单方面的认为连接建立成功了。

所以说,建立连接需要三次才能保证连接建立成功。

思考为什么挥手需要四次呢?
因为当Client发送一个FIN包断开连接的时候,但是Server并不一定也想要断开连接,Server会先回复一个ACK,然后继续发送自己的数据,当Server的全部数据都发送完毕之后,会主动给Client发送一个FIN包表示,我的数据也发送完毕了,现在可以断开连接了,收到来自Client的ACK之后,双方进入CLOSED状态。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK