传输层协议TCP—滑动窗口(7)

1 PUSH

       在上一小节(6)讲述了 TCP 为了提升网络传输效率以及避免一些不必要的网络拥塞,而不惜付出些许时延的代价,以将多个小包攒成1个大包进行发送。本小节讲述的“PUSH”,其目标则恰恰相反,它是为了减少“时延”。PUSH 本身是 TCP 报文头中的一个 Flag,如图5-90所示:

        

       上图5-90中的“P”标记位,代表的就是 PUSH(有时候简写为 PSH),占用1个 bit。当 PSH = 1 时,它从一定意义上来讲,就可以减少“时延”。其原理首先要从 TCP 接收端与它的上层之间的数据提交模型说起,如图5-91所示:

        

       上图5-91中,TCP 接收方收到数据以后,首先是将数据存储在自己的接收缓存中,然后再提交给上层(应用层)相关缓存中。那么问题来了,TCP 接收方何时将这些数据提交给应用层呢?这分为两种提交模型(满泻提交模型、直流提交模型),如图5-92、5-93所示:

        

       上图5-92所表达的是满泻提交模型(接受缓存满了以后,才提交给应用层),T0、T1 时刻,TCP接收方虽然接收了一些数据,但是其缓存并没有满,所以它暂时还不把所接收到的数据提交给应用层。待到 T3 时刻,TCP 接收方又接收了一些数据,此时其缓存已满,它才将缓存中所有的数据一次性提交给应用层。

       图5-93则没有图5-92那么复杂,表达的是直流提交模型(直接提交过去),TCP 接收方在任意时刻(Ti),只要接收到数据,就直接从接收缓存提交给应用层。之所以会有这两种模型,是因为 TCP 认为直流提交模型的效率并不高,所以期望自己先缓存一下,待缓存满了以后再一次新提交,这样提交的效率会高些,但这样做会引起时延变大的问题,其实也没啥显著效果。

       想象一下图5-92中,如果从 T2 时刻到 T3 时刻,中间如果经历了很长时间(比如几秒、甚至几小时),那么 TCP 几乎就是不可用了。对于这种满泻提交模型下的时延问题,通过引入“PUSH”方案来解决这个问题。

       

       上图5-86表达的是满泻提交模式与 PUSH 相遇的故事。T0 时刻的报文,其 PSH = 0(图5-92、5-93中的 PSH 都是0),所以此时数据(data0,3个字节)并不会被 TCP提交给应用层。T1 时刻的报文,PSH = 1,此时TCP 会将已接收未提交的数据全部提交给应用层缓存:data1(4个字节) + data0(3个字节)。也就是说,对于接收方而言,TCP 只要看到 PSH = 1,无论其接收缓存是否已满,它都会将缓存中所接收的所有数据(包括本次接收和历史接收),全部一次性提交给应用层。

       由此看来,PSH 标签(等于1),对于 TCP 接收方来说,其含义就是:立刻马上全部提交(PUSH)接收缓存中的数据。也正是源于此,PSH 标签可以有效地减少或者避免 TCP 接收方缓存提价(意思是等待缓存变为0的时间)的时延。PSH 标签作用如此明显,那么它是怎么来的呢?当然,是由发送方打上的——发送方决定 PSH 等于0或者等于1。这里的发送方指的是两个角色:TCP 发送方、用户(可以理解为应用程序,或者说是使用人)

用户

        先说用户这个角色。用户设置 PSH = 0 或者 PSH = 1,是一个主动行为。也就是说,用户根据不同的场景、不同的应用特点,决定 PSH 的值是多少。这个我们就不展开说了,毕竟这里没有绝对的规则——当然,一般来说,如果要追求低时延,报文中最好还是打上 PSH 标签。

        PSH = 1,不仅可以是 TCP 接收方立刻提交数据,也可以使 TCP 发送方立刻发送数据。前面讲解nagle算法时提到发送方可能会为了攒大包而延迟发送,从而发送方会产生时延。PSH 标签正是为了解决此问题,如下图5-95所示:

        

       上图5-87中,T0 时刻,用户(应用层)调用 TCP 的 SEND 接口,发送了 data0(3个字节),此时 PSH = 0,TCP 发送方并不会立刻发送 data0(假设 TCP 采用了 Nagle 算法)。T1 时刻,用户又调用 SEND 接口,发送了 data1(4个字节)。此时,data1 + data0,一共也才7个字节,仍然是属于小包,但是由于用户设置了 PSH 标签(PSH = 1),TCP 会立刻将其发送缓存中的数据发送出去(当然发送本身,仍然要受发送窗口、MSS 等约束)。所以,PSH 标签,对于 TCP 发送方而言,其目的就是:立刻马上全部发送发送缓存中的数据。也正是源于此,PSH 标签也可以有效地减少或者避免 TCP 发送方缓存发送的时延。

       因此,总的来说,PSH标签既可以减少或避免接收方的时延,也可以减少或避免发送方的时延。

TCP发送方

       PSH 标签,不仅用户可以主动打上,TCP 发送方(TCP 协议栈)也会自动打上。一个典型的场景就是“发送缓存空了(each write empties the sender buffer)”,如下图5-96所示:

        上图5-96中,TCP 发送方将一批 data 发送出去以后,会发现自己发送缓冲区空了——未发送已允许,没有数据;未发送未允许,没有数据——也就说没有数据可以发送了。于是 TCP 在发送这批数据时,会自动打上 PSH 标签(PSH = 1)。打上标签是为了 TCP 接收方。前文我们说过,TCP 接收方可能会采用“满泻提交模式”,当接收到PSH为1的数据后,直接提交给应用层缓存进行处理,而不用再一直等下一波数据到来。如果发送缓存为空,TCP 发送方会自动在发送报文里打上 PSH 标签(PSH = 1)”:我已经很闲了(发送缓存为空),你莫要等待了(收到数据赶紧提交给应用层吧)。

       还有一个场景,TCP 发送方也会自动打上 PSH 标签,那就是:用户调用 CLOSE 接口,以关闭一个 TCP 连接。这个时候 TCP 会发送1个 FIN 报文,并且为这个报文打上 PSH 标签(PSH = 1)。这很好理解,既然都决定要关闭连接了,那就更有必要通知接收方收到报文后,马上提交给应用层,因为自己再也不会发送数据了

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值