三次握手和四次挥手总结

 

三次握手:

第一次:客户端向服务器发送连接报文,该报文里面的重点内容:SYN=1和seq=x
SYN:同步标识位,第一次握手SYN(S)=1,此时ACK=0。当SYN=1,ACK=0时表示:这是一个连接请求报文段,表示这是一个建立连接的请求。(而当SYN=1,ACK=1时,表示同意连接,即第二次握手)只有在TCP建立连接时置1,握手完成后置0。(建立连接后)
seq:序列号,32位,TCP把连接中发送的报文的所有数据,按字节都编上一个序号,而seq为第一个字节序号,这是一个随机数。
所有第一次握手的报文信息:SYN=1,seq=x(随机数)
第二次:
服务器向客户端发送一个连接接受报文,信息有SYN=1,ACK=1, seq=y, ack=x+1
第二次握手,多了ACK和ack.
1.seq不管对方用不用,都会有,都会发送。TCP协议定的
2.ACK和ack是不一样的
ACK:确认标志位,对已接收的数据包进行确认并表示确认号(ack)是否有效,值为1,表示ack有效。
ack:确认号,32位,只有在ACK=1时,ack才有效,ack=x+1,表示希望对方下次传过来的数据第一个字节序号值是x+1,即为期望接收到对方下一个报文中第一个字节的编号

第三次握手:
1.SYN=0,只所以不是1,是因为等于1后,服务器会认为你要发起一个新的连接请求,所以只有在发起连接请求和请求接受的情况下SYN才是1,即第一次握手和第二次握手。
客户端发送报文:ACK=1:确认标志位;      seq =x+1:报文头序号;    ack=y+1:确认号
三次握手完建立连接。


三次握手的意义:确认客户端和服务器都可以正常接收和发送报文。
初始时:客户端处于Closed状态,服务器处于Listen状态;

第一次握手:客户端发送SYN报文给服务器,初始序列号为x(seq=x), 此时客户端进入SYN_SENT状态;这时,客户端可以知道自己发送能力正常,服务器可以知道自己接收能力正常,客户端发送能力正常。

第二次握手:服务器通过自己的SYN报文给与客户端确认和响应,服务器进入SYN_RECV状态;这时客户端可以知道服务器收发能力正常,自己收发能力正常;服务器知道自己收发能力正常,但不知道客户端接收能力正常,因此需要第三次握手。服务器发送报文的四个参数具体含义如下:

    SYN=1,表示为连接请求报文,也不能携带数据;
    seq=y,服务端的序列号为y;
    ACK=1,表示确认客户端序列号有效,此时确认号(ack)有值;
    ack=seq+1:ack的值为客户端传来的序列号(seq)加1,即ack=x+1;

第三次握手:客户端收到服务器的SYN+ACK的包,此时客户端处于ESTABLISHED(已确认)状态,表示客户端和服务器都表示同意连接,因此客户端发送一个ACK报文,ack仍为序列号+1,即y+1,初始序列号为x,因此客户端发送的第二次报文,序列号要+1,即x+1;这时服务器可以确认客户端收发能力正常;第三次握手可以携带数据。
注:
1.双方的确认号ack和序号seq的值,都是在彼此ack和seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。
2.SYN =1时,不携带数据

三次握手过程分析:

第一次握手:客户端发送请求到服务器(客户端什么都不能确认),服务器确认客户端发送,自己接受正常SYN=1,seq=x;

第二次握手:服务器发给客户端

                   客户端确认:自己发送/接受正常,对方发送/接受正常;

                   服务器确认:自己接受正常,对方发送正常;

                    ACK=1,ack=x+1,SYN=1,seq=y

第三次握手:客户端发给服务器

                      服务器确认:自己发送/接受正常,对方发送/接受正常;

                      客户端确认:自己发送/接受正常,对方发送/接受正常;

                      ACK=1,ack=y+1,seq=x+1

 


注:
1.第一次握手:TCP规定,SYN报文段(即SYN=1的报文段)不能携带数据且要消耗掉一个序号,并将该数据包发送给服务端,客服端进入SYN_SENT状态,等待服务端确认
2.第二次握手:该报文段(SYN=1)不能携带数据且同样要消耗掉一个序号,这时服务端进入SYN_RCVD状态

6个标志位:

    URG:紧急指针是否有效,为1,表示某一位需要被优先处理;
    ACK:确认号是否有效,仅当ACK=1时,确认号字段才有效,ACK=0,确认号无效
    PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
    RST:对方要求重新建立连接;
    SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建立连接时才会被置1,握手完成后SYN标志位被置0。
    FIN:通知对方,本段要关闭了,释放一个连接,FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接。

四次挥手:
看懂三次握手后,四次挥手也就没有问题了。
所谓四次挥手,既终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,流程如下图:

 

过程:
第一次挥手:
客户端发送报文:FIN = 1, seq =u
第二次挥手:
服务端收到报文,返回给客户端一个确认报文:ACK = 1,seq = v,ack =u +1
第三次挥手:
服务端确认自己数据传输完毕,再返回给客户端一个确认报文:FIN = 1,ACK =1, seq = w,ack = u +1
第四次挥手:
客户端收到服务器的报文,返回给服务器:ACK =1,seq =u +1,ack = w +1
注:
1.第四次挥手,FIN =0不等于1,和第三次握手情况相同,客户端FIN结束标志位为1的时候,服务器会认为你要发起一个新的断开请求,所以只有客户端在发起顿开请求和服务器确认可以断开的情况下FIN才是1,即第一次挥和第三次挥手
2.TCP连接是全双工的,因此,每个方向都必须要单独进行关闭。这一原则是当一方(比如客户端)完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN(比如服务器端)只是意味着这一方向上(客户端--->服务器)没有数据流动了,即不会再收到数据了。但是在这个TCP连接上仍然能够发送数据(服务器--->客户端),直到这一方向(服务器--->客户端)也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
3.第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态;(TCP规定,FIN报文段即使不携带数据,也要消耗一个序号)
第二次挥手:服务器收到客户端发送的结果后,发出ACK=1,确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE_WAIT状态;(TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间)
第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,确认标志ACK=1,确认序号ack=u+1,由于在半关闭状态,服务器很可能在发送一些数据,假定此时的序号seq=w,服务器进入LAST_ACK状态,等待客户端的确认;
第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态;可以看到,服务器结束TCP连接的时间要比客户端早一些。
4.全双工:客户端在给服务器端发送消息的同时,服务器端也可以给客户端发送消息;
半双工:客户端可以给服务端发消息,服务器端也可以给客户端发消息,但客户端和服务端不能同时发

常见问题:
1.为什么挥手比握手多一次?
因为握手的时候并没有数据传输,所以服务端的 SYN 和 ACK 报文可以一起发送,但是挥手的时候有数据在传输,所以 ACK 和 FIN报文不能同时发送,需要分两步,所以会比握手多一步。

2.为什么三次挥手不行?
因为服务端在接收到FIN, 往往不会立即返回FIN ,必须等到服务端所有的报文都发送完毕了,才能发FIN。因此先发一个ACK表示已经收到客户端的FIN,延迟一段时间才发FIN。这就造成了四次挥手。如果是三次挥手
即将服务端的两次挥手合为一次,等于说服务端将ACK和FIN的发送合并为一次挥手,那服务器在等数据传输完成的过程中,长时间的延迟可能会导致客户端误以为FIN没有到达客户端,从而让客户端不断的重发FIN。所有只能第二次握手先发送ACK确认接收到了客户端的数据,等服务器发送完了数据,再发送FIN包进行第三次挥手。
3.如果只有两次握手会发生什么?
从三次握手的过程,第三次握手可以让服务端知道自己发送数据没有问题,只有2次握手,即只要服务端发出确认,新的连接就建立,1.可能会出现服务器一直发送数据,但客户端收不到的情况,服务器数据传完,等不到FIN,造成资源浪费;2.客户端因收不到数据,反复向服务端发送请求连接的报文,服务器反复发送数据的情况4.如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接
5.为什么客户端在TIME-WAIT阶段要等2MSL?

主要目的是确认服务器端是否收到客户端发出的最终ACK确认报文。
当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。MSL指的是:一段TCP报文在传输过程中的最大生命周期。2MSL即是一个发送和一个回复所需的最大时间。

服务端如果在1MSL内没有收到客户端发出的最终ACK确认报文(说明最终确认报文丢失了),就会再次向客户端发出FIN报文。

如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时。

所以,客户端要经历时长为2MSL的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值