TCP的三次握手和四次挥手

2022-08-19 11:18:42

TCP(Transmission Control Protocol,传输控制协议)

        TCP是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。

        客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。TCP建立连接时要传输三个数据包,俗称三次握手。

几个重要字段的全称,方便记忆:

seq:(sequence number)序号
ack:(acknowledgement number)确认号
标志位:
        SYN :(SYNchronization)同步
        ACK :(ACKnowlegment)确认
        FIN   :(FINish)终止

三次握手:

第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

为什么要第三次通信?

1、在第一次通信过程中,A向B发送信息之后,B收到信息后可以确认自己的收信能力和A的发信能力没有问题。

2、在第二次通信中,B向A发送信息之后,A可以确认自己的发信能力和B的收信能力没有问题,但是B不知道自己的发信能力到底如何,所以就需要第三次通信。

3、在第三次通信中,A向B发送信息之后,B就可以确认自己的发信能力没有问题。

小结:

三次握手的关键就是要确认对方收到了自己的数据包,这个目标就是通过“确认号(Ack)”字段实现的。计算机会记录下自己发送的数据包序号Seq,待收到对方的数据包后,检测“确认号(Ack)”字段,看Ack = Seq + 1是否成立,如果成立则说明对方正确收到了自己的数据包

四次挥手:

第一次挥手:客户端发送一个FIN,用来关闭客户端到服务器的数据传送,客户端进入FIN_WAIT_1状态。

第二次挥手:服务器收到FIN后,发送一个ACK给客户端, 服务器进入CLOSE_WAIT状态。

第三次挥手:服务器发送一个FIN,用来关闭服务器到客户端的数据传送,服务器进入LAST_ACK状态。

第四次挥手:客户端收到FIN后,客户端进入TIME_WAIT状态,发送ACK给服务器,服务器进入CLOSED状态,完成四次挥手。

四次挥手的情景大致是这样的:

1、客户端主机C说:“我没有数据了,断开连接吧。 ”

2、服务器S说:“好,但是我还有数据(不断给C发送数据,此时C已经不能给S发送数据了,但是必须要就收S发来的数据)。”

3、(当S给C发完数据后)S说:“我发完了,断开连接吧。”

4、C说:“好,断开连接吧。”


为什么连接的时候是三次握手,关闭的时候却是四次握手?

①因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

②但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。

③只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

TCP三次握手一定能保证传输可靠吗?不能

  • 三次握手比两次更可靠,但也不是完全可靠,而追加更多次握手也不能使连接更可靠了。因此选择了三次握手。
  • 世界上不存在完全可靠的通信协议。从通信时间成本空间成本以及可靠度来讲,选择了“三次握手”作为点对点通信的一般规则。
  • 作者:m0_71537663
  • 原文链接:https://blog.csdn.net/m0_71537663/article/details/125051391
    更新时间:2022-08-19 11:18:42