TCP三次握手四次挥手过程

在正式介绍TCP三次握手四次挥手之前我们先来看看TCP的报头:

通过上图我们可以看到TCP报头里边包含有如下部分:

16位源端口号:发送方的端口号,占2个字节

16位目的端口号:接收方的端口号,占2个字节

32位序号:发送方发送批量字节数据时第一个字节数据的序号(第一次发送数据时第一个字节的序号由本地随机产生),TCP会给要发送的每个字节数据都编上一个序号,通常用syn表示。(可保证数据按序到达)

32位确认序号:对发送方发来的批量字节数据的确认,告诉发送方下一次应该从哪个字节开始发送数据(默认表示该字节之前的数据已全部被正常接收到),通常用ack表示。(明确告诉发送方哪些字节数据已收到,哪些字节数据需要重传)

4位首部长度:表示TCP报头有多少个4字节(32个bit),由于4个比特位最大可以表示到15,由此可以得出TCP头部最长占15*4=60个字节,其中除开选项部分,TCP首部长度共占20个字节。也叫数据偏移,表示TCP报文数据距离TCP报文起始位置有多远,即TCP报头的长度。

6位保留位:6位置0的字段,用于以后定义新的用途。

6位标志位:

URG(urgent):紧急指针,置1时有效,表示此次数据需要被紧急处理(优先处理)

ACK(acknowledgment):置1时表示确认序号有效,置0时确认序号无效。

PSH(push):置1表示告诉接收方应用程序立即将数据从TCP接收缓冲区读走,而不是在缓冲区中排队

RST(reset):复位标志,表示对方要求重新建立连接。

SYN(synchronization):请求建立连接。当SYN=1且ACK=0时表示这是一个连接请求报文,而SYN=1且ACK=1表示对方接收到你的请求并同意建立连接(连接响应报文)。

FIN(finish):释放连接。FIN=1时表示此报文的发送方的数据已经发送完毕,要求释放运输连接。

16位窗口大小:表示发送此报文的发送方的接收缓冲区剩余空间的大小。当接收方看到此空间剩余大小时可以控制自己发送数据的多少,保证对方可以接收,可保证双方的流量控制。

16位校验和:发送端填充,如果接收方校验不通过,则认为数据有问题(既校验TCP首部,也校验数据部分)。

16位紧急指针:当URG标志位为1时有效,表示被优先处理的数据的偏移量(指向被优先处理的数据)。

选项:可变长度,最多包含40个字节(TCP报头最大长度60字节-固定长度20字节)。

 了解完TCP报头的基本信息后,我们知道TCP是面向连接的,即在双方通信之间是先要建立好连接的,所以现在我们来看看TCP三次握手建立连接和四次挥手断开连接的具体过程: 

 

  • 三次握手

第一次握手:客户端将请求建立连接的报文数据(SYN为1,ACK为0)发送给服务器,同时随机生成一个序号(syn=x),并进入SYN_SENT状态(同步已发送状态)。TCP规定,SYN报文段(SYN=1)不允许携带数据,但是会消耗一个序号。

第二次握手:服务器收到此报文后发现这是一个请求建立连接的报文,所以服务器将SYN置为1,ACK置为1的报文发送给客户端,以此表示对客户端发来请求建立连接的报文的确认,同时请求建立连接,此时确认序号ack=x+1,序号随机产生(syn=y),并进入SYN_RECV状态(同步收到状态)。 同样,此报文段也不能携带数据,但是会消耗一个序号。

第三次握手:客户端收到来自服务器的报文后,发送确认收到报文给服务器,此时发送的报文中ACK为1,序号syn=x+1,确认序号ack=y+1。TCP连接建立,客户端对此次连接分配空间保存对应信息,并进入ESTABLISHEB状态(已建立状态)。当服务器收到客户端的确认报文后,也对此次连接分配空间保存对应信息,并进入ESTABLISHED状态(已建立状态)。此时连接已经建立成功,完成三次握手。

问:为什么建立连接一定是三次握手,而不是两次或四次呢?

先说说两次握手建立连接的情况:

客户端发送请求建立连接的报文给服务器(第一次握手),服务器收到请求建立连接的报文后发送响应连接报文给客户端(第二次握手),两次握手完毕。但是我们并不保证服务器所发送的响应报文客户端一定能收到,如果在传输过程中该报文丢失,而服务器对此却全然不知,所以服务器会对此次连接开辟空间资源。而客户端在一直没有收到确认报文的情况下会再次向服务器发送请求建立连接的报文。此时服务器再次对此次请求报文作出响应,如果此时响应报文再次被丢失,那么又会发送前面的事:服务器再次为此次连接开辟空间,而客户端一直发送请求报文。一直循环,服务器会因为耗费大量资源而挂掉。所以,两次握手不可行。

再来说说四次握手建立连接的情况:

客户端发送请求建立连接的报文给服务器(第一次握手),服务器收到请求建立连接的报文后发送响应连接报文给客户端(第二次握手),当客户端收到了响应报文后会发送确认报文给服务器(第三次握手),表明自己已经收到了服务器同意建立连接的报文。此时由于客户端服务器双方都已经知道双方要建立连接的事了,所以没有必要再进行第四次握手了。

最后来说说为什么三次握手可以建立连接

客户端发送请求建立连接的报文给服务器(第一次握手),服务器收到请求建立连接的报文后发送响应连接报文给客户端(第二次握手),当客户端收到了响应报文后会发送确认报文给服务器(第三次握手)。此时如果第三次握手的ACK包没有丢失,那么双方都会进入ESTABLISHEB状态(已连接状态)。但是如果第三次握手的ACK包丢失了,那么只有客户端进入了ESTABLISHED状态,而服务器由于没有收到确认包,所以不会为此次连接开辟空间,自然也不会进入ESTABLISHED状态。此时在客户端误认为连接已经建立好了的情况下,客户端会发送数据给服务器,而由于服务器并没有保存此次连接的任何信息,所以服务器会发送一个RST为1的报文给客户端,要求重新建立连接。所以,如果第三次握手的ACK包没有丢失,那么双方均进入ESTABLISHEB状态;否则,由于服务器并没有为这种无用连接开辟空间,所以对服务器并没有什么影响,只要求重新建立连接就可以了,当然,对客户端的影响也很小。

  • 四次挥手

第一次挥手:客户端发送完数据后将发送一个释放连接的报文给服务器(FIN=1),此报文中序号syn=m(已发送数据的最后一个字节数据的序号加1),并进入到FIN_WAIT_1状态(终止等待1状态)。TCP规定,FIN报文段(FIN=1)即使不携带数据,也要消耗一个序号。

第二次挥手:服务器收到客户端释放连接的报文后,由于不能确定自己是否已将数据发送完,或还有待处理的数据,所以服务器先给客户端发送一个确认报文(ACK=1),此报文中携带自己的序号syn=n,确认序号ack=m+1,并进入到CLOSE_WAIT状态(关闭等待状态)。此时服务器TCP会通知高层应用进程已无数据可读,然后客户端向服务器的连接就释放了,但是如果服务器给客户端发送数据,客户端还是会接收。当客户端收到服务器的确认报文后进入FIN_WAIT_2状态(终止等待2状态),等待服务器发送释放连接的报文。

第三次挥手:当服务器处理完自己的工作后(如发送数据给客户端),会发送释放连接的报文给客户端(FIN=1),此时由于处于半关闭状态,所以服务器很有可能给客户端发送了数据,先假设服务器发送了数据给客户端,序号为syn=p,并进入到LAST_ACK状态(最后确认状态)。同样,此报文段也不能携带数据,但是会消耗一个序号。

第四次挥手:当客户端收到服务器的FIN包时发送确认报文给服务器(ACK=1),序号syn=m+1,确认序号ack=p+1,并进入TIME_WAIT状态(时间等待状态)。值得注意的是,此时连接并未断开,客户端会等待2*MSL(MSL:Max Segment Life,报文最大生存时间)时间后才进入CLOSED状态。当服务器收到客户端的确认报文后进入CLOSED状态。

问:为什么客户端最后要等待2*MSL的时间?

尽可能保证最后一个ACK包被服务器收到。如果在2*MSL时间内服务器收到了客户端发的ACK包,那么服务器直接进入CLOSED状态,而客户端在2*MSL时间后也进入CLOSED状态;如果在2*MSL时间内服务器未收到客服端发的ACK包,那么在一定时间后会触发超时重传机制,即服务器会再次发送FIN包给客户端,而此时客户端会再次发送确认包ACK包给服务器,并重启2*MSL计时器。

问:为什么断开连接一定是四次挥手,而不是三次或五次呢?

由于断开连接必须等到双方该做的工作都已经做完了才能执行,即断开连接需要双方同意。所以当客户端完成了数据的发送工作之后,通知服务器自己的工作做完了,而由于服务器的工作可能还没做完,所以只能暂时先给客户端发送确认报文。只有当服务器的工作也完成之后,它才会给客户端发送释放连接的报文,客户端对此报文进行确认。最后在双方都已经知晓且同意断开连接的情况下才能断开此次连接。

问:为什么建立连接是三次握手,而断开连接是四次挥手呢?

由于建立连接时并不涉及到数据的发送接收等,所以当客户端提出想要建立连接时,服务器可以直接响应此连接,即同时发送SYN包和ACK包,最后客户端确认收到,双方进入ESTABLISHED状态。

而在断开连接中,由于客户端服务器需要交互处理数据,而双方的工作进度也不一样。所以当客户端发送完自己的数据时并不代表服务器也已经完成了自己的工作,所以当收到客户端发来的释放连接的报文时,服务器只能先回复ACK报文。只有当服务器完成了自己的工作时才会给客户端发送FIN包,然后客户端进行确认,最后均进入CLOSED状态。由于服务器不能同时发送FIN包和ACK包给客户端,所以断开连接比建立连接多了一次。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值