TCP三次握手和四次挥手的原理和问题分析

TCP报文段的首部格式
在这里插入图片描述

注意:一个是确认值ACK(Acknowledgement),值为1就是确认连接,一个是确认编号ack(Acknowledgement Number),即接收到的上一次远端主机传来的seq然后+1,再发送给远端主机。提示远端主机已经成功接收上一次所有数据。


TCP连接的建立——三次握手

在这里插入图片描述

最开始客户端和服务器都是处于CLOAED状态的,其中客户端是主动打开连接,服务端被动打开连接。
第一次握手
客户端A的TCP向服务端B发送连接请求报文段,SYN=1请求连接,随机初始化一个seq,设seq=x(表示传送数据时第一个数据字节是x)。此时TCP客户端进程进入SYN-SENT状态。
第二次握手
TCP服务端收到连接报文后如果同意连接则回复确认,其中SYN=1,ACK=1,确认号ack=x+1(客户端的seq值+1),服务端也随机一个seq=y;此时TCP服务端进程进入SYN-RCVD状态。
第三次握手
客户端A收到确认报文后向服务端B给出确认,ACK=1,确认号ack=y+1(),客户端通知上层应用进程建立已连接。此时TCP的客户端进程进入ESTAB-LISHED状态。当服务端B收到后就也进入ESTAB-LISHED状态,双方可以开始数据传送。

三次握手的作用

1、确认双方的接受能力、发送能力是否正常。

2、指定自己的初始化序列号,为后面的可靠传送做准备。(三次握手的一个重要功能是客户端和服务端交换ISN(Initial Sequence Number), 以便让对方知道接下来接收数据的时候如何按序列号组装数据。)

1、(ISN)是固定的吗

三次握手的一个重要功能是客户端和服务端交换ISN(Initial Sequence Number), 以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果ISN是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。

2、半连接队列

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

SYN-ACK 重传次数: 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超 过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s, 2s, 4s, 8s

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

第三次握手的时候,是可以携带数据的。也就是说,第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。

为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据,因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。也就是说,第一次握手可以放数据的话,其中一个简单的原因就是会让服务器更加容易受到攻击了。

而对于第三次的话,此时客户端已经处于 established 状态,也就是说,对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的

TCP连接的释放——四次挥手
在这里插入图片描述
第一次挥手
数据传输结束后双方都可以发出释放连接,假设客户端先释放连接。客户端向服务端发送连接释放报文并且停止发送数据,释放数据报文首部,FIN=1,序列号seq=u。此时客户端进入FIN-WAIT-1状态。等待B的确认。
第二次挥手
服务端收到连接释放报文后发出确认,确认号ack=u+1,报文段自己的序号seq=v,此时服务端进程进入CLOSE-WATE状态。这个时候客户端不再向服务端发送数据但是服务端如果还要继续向客户端发送数据,客户端照常接收,也就是终止等待的时间。客户端收到确认后进入FIN-WAIT-2状态。
第三次挥手
若服务端没有数据向客户端传送时其应用进程就会通知TCP释放连接,向客户端发送连接释放报文,发送FIN=1,ack=u+1,序列号seq=w,此时服务器进入LAST-ACK状态。。等待客户端的最后确认。
第四次挥手
客户端收到服务端连接释放报文后进入TIME-WAIT状态。,然后给服务端回一个最后的确认报文,这是TCP连接并没有被释放,而是等2MSL(报文段最长存活时间,超过这个时间报文将被丢弃)后才会被释放。服务端一旦收到确认,立马进入CLOSED状态,2MSL后客户端也进入CLOSED状态,本次TCP连接彻底结束。

数据传输时
   (1)发送的seq和ack是根据上一个接收包的seq、ack和len(数据长度)得到,具体为:seq=ack,ack=seq+len
   (2)如果某一主机连续发了4个包,后三个包的seq和ack和第一个包的一样
   (3)seq会单调增大
   (4)如果握手完第一个数据包是客户端发送,第一个数据包的seq和ack和第三次握手的一样
   (5)会话劫持的原理就是利用这个
   
状态描述

LISTEN - 侦听来自远方TCP端口的连接请求;

SYN-SENT -在发送连接请求后等待匹配的连接请求;

SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;

ESTABLISHED- 代表一个打开的连接,数据可以传送给用户;

FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;

FIN-WAIT-2 - 从远程TCP等待连接中断请求;

CLOSE-WAIT - 等待从本地用户发来的连接中断请求;

CLOSING -等待远程TCP对连接中断的确认;

LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;

TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认;

CLOSED - 没有任何连接状态;

常见问题
1.从图中就可以轻易的看出,当客户端A已经处于ESTAB-LISHED状态时,服端B还可能处于SYN-RCVD状态。其他情况同理。

2.为什么是三次握手
(1)防止已经失效的连接建立请求突然又传送到服务端了,导致错误。

假设A第一个给B发送建立连接请求,因为传送过程中在某个网络节点停留了很久,由于A迟迟没有收到B的确认报文,误以为请求丢失,于是重新向B发送请求。当A和B完成数据传送准备关闭连接时先前停留的请求报文到达了B,此时B会再次建立连接导致资源浪费。有第三次握手的情况下即使第一次迟到的报文不幸被B接受到了,A也不会发送确认报文,连接不会打开。

(2)假设第二次握手之后没有第三次握手,则服务端会在发送确认报文(第二次握手)后,开始发送数据,如果确认报文在客户端接收之前丢失,客户端没有收到,便不知道服务端建立了什么样的序列号,则客户端不会处理服务端发送过来的数据一直等待确认报文,而服务端发送的数据超时后会继续重传相同的数据造成死锁。

3.为什么等待2MSL
为了保证客户端发送的最后一个ACK报文段能到达服务端,如果没收到的话服务端会在超时后将重发第三次握手的FIN包,并且初始化计时器2MSL。还有就是防止之前失效的连接分组再次出现,而2MSL的时间足够让他消失。

4.为什么握手三次,挥手四次
建立连接时,ACK和SYN可以放在一个报文里来发送,其中ACK报文是用来应答的,SYN报文是用来同步的。而关闭连接时,被动关闭方可能还需要发送一些数据后,所以会先回复一个ACK确认报文,等服务端所有报文都发送完了再发送FIN报文表示同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

5.当建立连接后客户端出现故障怎么办
TCP设有一个保活计时器,客户端如果出现故障,服务器不会一直等下去造成资源浪费。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,然后关闭连接。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值