TCP-三次握手、四次挥手详解

TCP虽然是面向字节流,但是TCP传送的数据单元确实报文段,一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在首部中各字段的作用,因此,只要弄清了首部各字段的作用后,就能很好的理解TCP的工作原理。
这里写图片描述
序号:(seq):占4个字节,一个报文段的序号字段值是201,而携带的数据共有100字节,这就表明,本报文段的数据的第一个字节的序号是201,最后一个字节的序号是300;那么下一个报文段的序号字段值是301;序号也称报文段序号。
确认号:(ack):占4个字节,是期待收到对方下一个报文段的第一个数据字节的序号,例如,B正确的收到了A发过来的一个报文段,其序号字段值是301,而数据长度是200字节,(301~500),这表明B正确的收到了A发送的200个字节的数据,那么B期待收到A发过来的下个数据序号是501,于是B给A发送一个确认号ack=501,总之,若ack为N,那么到N-1为止的所有数据都已正确收到,
确认ACK:仅当ACK=1时,我们的确认序列号ack才有效,当ACK=0时,确认序号ack无效,TCP规定:建立连接后所有发送的报文端都必须把ACK必须置为1。
同步SYN(SYNchronization):在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此, SYN置1就表示这是一个连接请求或连接接受报文。
终止FIN (FINis,意思是完,终), 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。


这里写图片描述
主机A运行的是TCP客户程序,而B运行的是TCP服务端程序,最初TCP进程都处于关闭状态,A主动打开连接,B被动打开连接;
三次握手:
第一次握手:
B的TCP服务器进程先创建传输控制块TCB,准备接收客户进程的连接请求,然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求.如有,就做出响应.
A的TCP客户进程也是先创建传输控制块TCB,然后向B发出连接请求报文段,这时候首部中的同步位SYN=1,同时选择一个初始序号 seq=x。TCP规定,SYN报文段(SYN=1的报文段) 不能携带数据,但要消耗一个序号.这时,TCP客户进程进入SYN-SENT(同步已发送)状态.
第二次握手:
B收到连接请求报文段后,如同意建立连接,则向A发送确认.在确认报文段中,应把SYN和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。这个报文段也不能携带数据,同样要消耗一个序号.这时TCP服务器进程进入SYN-RCVD(同步收到)状态.
第三次握手:
TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,这种情况下,下一个数据报文段的序号仍是seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
当B收到A的确认后,也进入ESTABLISHED状态。


这里写图片描述

四次挥手:

1.数据传输结束后,通信双方都可释放连接。现在A,B都处于ESTABLISHED状态。A先发送连接释放报文段,并停止在发送数据,主动关闭TCP连接。A把连接释放报文段首部离得FIN置1,其序号seq=u,u等于前面已发送的数据的最后一个字节的序号加1.这是A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。请注意,TCP规定,FIN报文段即使不携带数据,也消耗一个序号。

2.B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于B前面已发送的数据的最后一个字节的序号加1.然后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时通知高层应用程序,因而从A到B的连接就释放了,这时的TCP连接处于半关闭(half-close)状态,即A已经没有数据要发送了,但B若发送数据,A仍然接收。也就是B到A这个方向的连接并未关闭,这个状态可能持续一段时间。

3.A收到B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。若B已经没有数据要发给A,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1.假定B的序号是w(在半关闭状态B可能又发送了一些数据)。B还必须从夫上次已发送过的确认号ack=u+1。这时B进入LAST-ACK状态,等待A确认。

4.A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号为seq=u+1(根据TCP标准,前面发送的FIN报文段要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态。现在TCP连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。时间MSL:Maximum Segment Lifetime 最长报文段寿命,MSL值可以根据具体情况设置。当A撤销传输控制块后,就结束了本次TCP连接。

为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
1)为了保证A发送的最后一个ACK报文段能够达到B。 这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发的FIN+ACK报文段的确认。B会超时重传FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器。最后, A和B都正常进入到CLOSED状态。如果A在TIME-WAIT状态不等待一段时间,而是再发送完ACK报文后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文。这样, B就无法按照正常步骤进入CLOSED状态。

2)防止“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK确认报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
B只要收到A发出的确认,就进入CLOSED状态,同样,B在撤销了相应的传输控制块后,就结束了本次TCP的连接,B结束TCP连接的时间比A早一些。


MSL的含义:
MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值