TCP连接的建立和释放

TCP的建立与释放

 

1 TCP报文段的首部格式

源端口、目的端口:客户端端口号和服务器端口号

序列号:序号使用mod2^32运算,从0开始。TCP是面向字节流的,在一个TCP连接中传送带字节流中的每一个字节都按顺序编号。整个要传送到字节流的起始序号必须在连接建立是设置。首部中的序号字段值则指的是本报文段所发送到数据的第一个字节的序号。例如,一个报文段的序号为301,携带数据为100字节,那么下一个报文段的数据号应当从401开始。

确认号:是期望收到对方下一个报文段的第一个数据字节的序号

数据偏移:即报文段的数据起始处到报文段的起始处的字节数,这个字段实际上是指出TCP报文段的首部长度。

紧急URG:URG=1时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送,而不要按照原来的排队顺序来传送

确认ACK:仅当ACK=1时确认号字段才有效。TCP规定,在连接建立后所有传送到报文段都必须将ACK置为1

推送PSH: 当发送方TCP将PSH置1,并立即创建一个报文段发送出去,接收方接收到PSH=1的报文段就尽快的(即”推送“向前)交付接收应用进程,而不再等到整个缓存都填满后在向上交付

复位RST:当RST=1时,表明TCP连接中出现严重错误,必须释放连接,然后在重新建立运输连接。RST置1还用来拒绝一个非法的报文段或者拒绝打开一个连接,RST也成为重建位或重置位

同步SYN:在建立连接时用来同步序号。SYN为1表明这是一个连接请求或者连接接收报文

终止FIN:用来释放一个连接,当FIN=1时,表示此报文段的发送方的数据已经发送完毕,并要求释放运输连接。

检验和:检验和字段的检验的范围包括首部和数据这两部分,在计算检验和是要在TCP报文段的前面加上12字节的伪首部。

紧急指针:紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数,因此,紧急指针指出了紧急数据的末尾在报文段中的位置。值得注意到是,即使窗口为0时也可发送紧急数据。

 

TCP连接的建立(三次握手):

 

第一次握手:Client向Server发送连接请求,此时SYN=1,同时选择一个初始序号seq=J。TCP规定,SYN报文段不能携带数据,但是要消耗一个序号,此时Client进入SYN-SENT状态。

第二次握手:Server收到连接请求,需要向Client发送确认,此时SYN=1,ACK=1,确认号ack=J+1,同时也为自己选择一个初始序号seq=K。请注意这个报文段也不能携带数据,但同样要消耗一个序号,这次服务器进入SYN-REVD状态。

第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,seq=J+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。(TCP规定,ACK报文段可以携带数据,如果不携带数据则不消耗序号,在这种情况下,下一个报文段序号仍为J+1)

 

问题:为什么Client还要发送一次确认?

这主要是为了防止已经失效的连接请求报文段又传送到了Server,因而产生错误。

假如Client发送了两次连接请求,第一个请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达Server,本来这是一个早己失效的报文段。但是Server收到此失效的连接请求报文后就误以为是Client有发送出一次新的连接请求,于是就向Client发出确认报文段,同意建立连接,假定不采用三次握手,那么这个连接就建立了。但实际上,Client没有发出建立连接的请求,因此不会理睬Server的确认,也不会向Server发送数据,但Server却以为新的运输已经建立,并一直等待Client发来数据,Server的许多资源就这样白白浪费了

 

TCP连接的释放(四次挥手):

  A:客户端                                             B:服务器

 

第一次挥手:A主动关闭连接,发送连接释放报文段。FIN=1,其序号seq=u,它等于前面传送过得数据的最后一个字节的序号加1A进入FIN_WAIT1状态;

第二次挥手:B收到连接释放报文段后发出确认,确认号ack=u+1,自己的序号seq=v,等于之前已经传送过得数据的最后一个字节的序号加1B进入CLOSE_WAIT状态。此时连接处于半关闭状态。A收到B的确认后进入FIN_WAIT2状态,等待B发出的连接释放报文;

第三次挥手:B已经没有要向A发送到数据,B便发送释放连接报文。FIN=1,现假定B的序号为w(在半关闭的状态期间,B可能又发送了一些数据),B还要重复上次已发送过的确认号ack=u+1,此时B进入LAST_ACK状态,等待A的确认;

第四次挥手:A在收到B的连接释放报文段后,必须对此发出确认。ACK=1ack=w+1seq=u+1A进入TIME_WAIT状态。注意:此时TCP连接还没有释放掉。等待时间为2MSL,MSL为最长报文段寿命。

 

问题:为什么ATIME_WAIT状态必须等待2MSL时间?

第一:为了保证A发送到最后一个ACK报文段能够到达发B,因为这个报文有可能丢失,是处在LAST_ACK状态的B收不到对已经发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的报文段,接着A重传一次确认,重新启动2MSL计时器。最后,AB都正常进入到CLOSED状态。如果ATIME_WAIT时不等待一段时间,而是在发送完ACK数据后立即释放,那么就无法收到B重传的的FIN+ACK报文段,因而也不会再发送一次确认,这样B就不能按照正常不走进入CLOSED状态。

第二:防止”已经失效的连接请求报文段“出现在本连接中,A在发送完最后一个ACK确认后,再经过2MSL时间就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样就可以是下一个新的连接中不会出现这种旧的连接请求报文段

进一步理解连接释放:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。 
简单说来是 先关读,后关写,一共需要四个阶段。以客户机发起关闭连接为例:
1.服务器读通道关闭
2.客户机写通道关闭
3.客户机读通道关闭
4.服务器写通道关闭
关闭行为是在发起方数据发送完毕之后,给对方发出一个FINfinish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK
详细过程:
    第一阶段   客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i
    1.服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道;
    2.客户机收到ACK(i+1)后,关闭客户机写通道;
   (此时,客户机仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据)
    第二阶段 服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j
    3.客户机收到FIN(j)后,返回确认段ACK,序列号为j+1,关闭客户机读通道;
    4.服务器收到ACK(j+1)后,关闭服务器写通道。
这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值