TCP三次握手、四次挥手

三次握手过程

三次握手是建立TCP连接时,客户端和服务端总共发送3个包,确认双方的接受能力和发送能力是否正常,指定初始化序列号,为后面的可靠传输做准备。实质是连接服务器指定端口,建立TCP连接,同步双方的序列号和确认号,交换TCP的窗口大小信息。

三次握手过程:
在这里插入图片描述
名词解释:

SYN:同步序列编号,是TCP/IP建立连接时使用的握手信号。表示建立连接。

seq:TCP报文段中第一个字节的数据编号,由本地随机生成。

ACK:报文段首部“ACK”字段,为1时表示发来的数据已确认接收无误。当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性

ack:TCP报文段首部中“确认号字段”的具体数值,“ack=x+1”表示服务器希望客户端下次发送数据的字节序号为x+1

第一次握手:

客户端给服务端发送一个SYN报文,并指明客户端的初始化序列号ISN(seq的值,假设为x)。此时客户端的状态为CLOSED->SYN_SEND。

发送给服务器的数据为:SYN=1,seq=x。SYN=1的报文段不能携带数据,而且需要消耗一个序号。

第二次握手:

服务器接收到客户端的SYN报文后,用自己的SYN作为应答,并且指定了服务端的初始化序列号ISN(seq的值,假设为y)。并且将ACK的值设置为客户端ISN+1(即客户端的seq+1),标识已经收到客户端的SYN报文。此时服务器的状态为LISTEN->SYN_RCVD。

发送给客户端的数据为:SYN=1,ACK=1,初始序号seq=y,确认号ack=x+1。

第三次握手:

客户端收到SYN报文后,应答一个ACK报文,将服务器的ISN+1(seq+1)作为ACK的值,表示收到服务器的SYN报文。此时客户端的状态为SYN_SENT->ESTABLISHED,服务器的状态为SYN_RCVD->ESTABLISHED。

发送服务端数据为:ACK=1,初始序号seq=x+1,确认号ack=y+1。

发送第一个SYN报文的一端执行主动打开,接收这个SYN并回发SYN的一端执行被动打开。

注意:我们上面写的ack和ACK,不是同一个概念

  • 小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。
  • 大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1。

为什么要三次握手

三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天 balabala……”

第一次握手:客户端发送网络包,服务端确认接收。服务端就能得出结论:客户端发送能力和服务端接收能力正常。

第二次握手:服务端发送网络包,客户端确认接收。客户端就能得出结论:服务端的发送、接收能力和客户端的发送能力正常。但服务端并不能确定客户端的接收能力正常。

第三次握手:客户端发送网络包,服务端确认接收。服务端可以得出:客户端服务端发送、接收能力都正常。三次发送才能保证。

如果是两次握手可能出现的情况:

如果客户端发送一个连接请求,但因为报文丢失没有收到确认,于是客户端又发送了第二个连接请求,服务端确认连接,发送完数据后,释放了当前的连接。但是客户端发送的第一个连接请求,可能因为是在某些网络节点长时间滞留,延误到释放第二个连接后才到达服务端,此时服务端认为这是一个新的连接请求,回复确认并建立连接,但是客户端忽略此确认,一直未向服务端发送数据,导致服务端一直等待客户端发送数据,浪费资源。

3.3 第 2 次握手传回了 ACK,为什么还要传回 SYN?
接收端传回发送端所发送的 ACK 是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传 SYN 则是为了建立并确认从服务端到客户端的通信。”

SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。

三次握手的过程中可以携带数据吗

第一次和第二次不可以携带数据,第三次可以携带数据。

如果第一次握手客户端携带数据,如果有恶意攻击者攻击服务器,每次都携带了大量的数据,疯狂发送,而且不理会服务器的接收、发送能力,那么服务器需要花费很多时间和空间接受这些报文。浪费时间,可能还会导致服务器崩溃。第二次同理。

第三次,客户端已经处于ESTABLISHED状态,而且已知服务端的发送接收能力正常,所以可以携带数据。

四次挥手过程

四次挥手流程图
在这里插入图片描述
名词解释:

FIN:代表关闭连接。

建立连接需要三次握手,而终止连接需要四次握手,这是由于TCP的半关闭(half-close)造成的。

半关闭:TCP提供了在结束发送后还能接收来自另一端数据的能力。

刚开始客户端和服务端都处于ESTABLISHED状态。

第一次挥手:

客户端发送FIN报文,并携带生成的序列号,停止再发送数据,主动关闭TCP连接,等待后端确认。此时客户端的状态为ESTABLISHED->FIN_WAIT1。发送到服务端的数据:FIN=1,seq=u。

第二次挥手:

服务端收到FIN后,发送ACK报文,并将ACK值设置为客户端序列值+1,表明已经收到客户端的报文。此时TCP处于半关闭状态,客户端客户端到服务端的连接被释放(服务端还可以向客户端发送数据),客户端等待服务端发出的连接释放报文段。此时服务端的状态为ESTABLISHED->CLOSE_WAIT。客户端收到服务端的确认后,状态为FIN_WAIT1->FIN_WAIT2。
发送到客户端的数据:ACK=1,seq=v,ack=u+1。

第三次挥手:

如果服务器也想断开连接,同客户端一样发送FIN报文,等待客户端确认。此时服务端的状态为CLOSE_WAIT->LAST_ACK。
发送到客户端的数据:FIN=1,ACK=1,seq=w,ack=u+1。
第四次挥手:

客户端收到FIN报文后,发送ACK报文作为应答,并携带ACK报文序列号的值(服务端seq+1)。客户端的状态为FIN_WAIT2->TIME_WAIT。等待2MSL后,客户端的状态为TIME_WAIT->CLOSED。

发送到服务端的数据:ACK=1,seq=u+1,ack=w+1。

服务端收到ACK报文后,状态为LAST_ACK->CLOSED。

如果服务端收不到ACK报文,那么服务端超时重传FIN-ACK报文,客户端重新确认,重启时间等待计时器,直至最后客户端和服务端都变为CLOSED状态。

挥手为什么要四次

挥手操作需要四次,是因为TCP提供了在一段结束发送后还能接收来自另一端数据的能力。

握手时,SYN报文用来同步,客户端可以发送SYN报文给服务端,服务端收到后可以直接发送SYN+ACK报文来应答。但是挥手时需要考虑到服务端并不会立即关闭SOCKET,可能还需要向客户端发送数据,所以只是先回复一个ACK报文,告诉客户端“你的FIN报文我收到了”。等到数据全部发完,服务端再发送FIN报文。故需要四次挥手。

2MSL等待状态

MSL叫做“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

TIME_WAIT状态也成为2MSL等待状态,每个具体TCP实现必须选择一个报文段最大生存时间MSL,这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。

作用:

1.保证客户端发送的最后一个ACK报文段能够到达服务端。
2.第四次挥手的ACK报文可能丢失,服务端则可能不会改变为CLOSED状态。所以需要服务端超时重新发送FIN+ACK报文,客户端重新确认,重启时间等待计时器,重新发送ACK报文,保证客户端和服务端都能进入到CLOSED状态。
3.防止“已失效的连接请求报文段”出现在本连接中。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值