tcp三次握手和四次挥手

TCP头部: 其中 ACK   SYN  序号  这三个部分在以下会用到,它们的介绍也在下面。


暂时需要的信息有:

ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此,  SYN置1就表示这是一个连接请求或连接接受报文。

FIN (finis)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

三次握手的过程:

第一次握手:建立连接时,客户端发送SYN报文段到服务器SYN=1 ACK=0,并进入SYN_SENT状态,等待服务器确认;该SYN报文段不包含应用层数据。客户端会随机选择初始序号seq=x,将其放到SYN报文段的序号字段中。该报文段被封装在一个IP数据报中并发送给服务器。SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手服务器收到包含SYN报文段的IP数据报,服务器从数据报中提取SYN报文段,并未该TCP连接分配TCP缓存和变量,并向客户端发送允许连接的报文段:SYNACK报文段。该报文段不包含应用层数据。服务器选择自己的初始序号y放入该报文段首部的序号字段中。SYN=1,ACK=1,seq=y,确认号字段ack=x+1。此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYNACK报文段后,客户也要为该连接分配缓存和变量。客户向服务器发送确认ACK=1,置ack=y+1,因连接已建立,故SYN=0。seq=x+1。此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。该确认报文段可以携带客户到服务器的数据。

然后连接建立,为什么要进行三次握手呢(两次确认)。

当一台主机接收到一个TCP报文段,其端口号或源IP地址与该主机上进行中的套接字都不匹配时:假如一台主机接收到具有目的端口号80的一个SYN报文段,但该主机在端口80不接受连接,则该主机向源发送一个特殊重置报文段,该报文段将RST标志位置1.当源主机收到重置报文段时,它告诉源“我没有那个报文段的套接字。请不要在发送该报文段了”。

下面是释放连接的过程:


当客户A 没有东西要发送时就要释放 A 这边的连接,A会发送一个报文(没有数据),其中 FIN 设置为1,  服务器B收到后会给应用程序一个信,这时A那边的连接已经关闭,即A不再发送信息(但仍可接收信息)。  A收到B的确认后进入等待状态,等待B请求释放连接, B数据发送完成后就向A请求连接释放,也是用FIN=1 表示, 并且用 ack = u+1(如图), A收到后回复一个确认信息,并进入 TIME_WAIT 状态, 等待 2MSL 时间。

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态

(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1Server进入CLOSED状态,完成四次挥手

当客户端没有数据再需要发送给服务端时,就需要释放客户端的连接,这整个过程为:

  1. 客户端发送一个报文给服务端(没有数据),其中FIN设置为1,Sequence Number置为u,客户端进入FIN_WAIT_1状态
  2. 服务端收到来自客户端的请求,发送一个ACK给客户端,Acknowledge置为u+1,同时发送Sequence Number为v,服务端年进入CLOSE_WAIT状态
  3. 服务端发送一个FIN给客户端,ACK置为1,Sequence置为w,Acknowledge置为u+1,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态
  4. 客户端收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给服务端,Acknowledge置为w+1,Sequence Number置为u+1,最后客户端和服务端都进入CLOSED状态

这里的一个问题是,为什么TCP连接的建立只需要三次握手而TCP连接的释放需要四次握手呢:

因为服务端在LISTEN状态下,收到建立请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而连接关闭时,当收到对方的FIN报文时,仅仅表示对方没有需要发送的数据了,但是还能接收数据,己方未必数据已经全部发送给对方了,所以己方可以立即关闭,也可以将应该发送的数据全部发送完毕后再发送FIN报文给客户端来表示同意现在关闭连接。

从这个角度而言,服务端的ACK和FIN一般都会分开发送。

 

为什么要等待呢?

为了这种情况: B向A发送 FIN = 1 的释放连接请求,但这个报文丢失了, A没有接到不会发送确认信息, B 超时会重传,这时A在 TIME_WAIT 还能够接收到这个请求,这时再回复一个确认就行了。(A收到 FIN = 1 的请求后 WAIT_TIME会重新记时)


 

 在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

另外服务器B存在一个保活状态,即如果A突然故障死机了,那B那边的连接资源什么时候能释放呢?  就是保活时间到了后,B会发送探测信息, 以决定是否释放连接。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值