nagle算法总结

nagle算法,发送延迟
nagle算法会延迟数据包的发送,仅仅对发送队列中最后一个数据包(未完成的数据包)起作用。
其目的是解决大量的小包造成网络负担上升的问题,方法是囤积数据到满足条件为止,然后发送 大数据包。
下面,大包即指大小等于mss的包。

算法的核心判断在这个地方:
net\ipv4\tcp_output.c

/* Return 0, if packet can be sent now without violation Nagle's rules:
* 1. It is full sized.
* 2. Or it contains FIN. (already checked by caller)
* 3. Or TCP_NODELAY was set.
* 4. Or TCP_CORK is not set, and all sent packets are ACKed.
*    With Minshall's modification: all sent small packets are ACKed.
*/
static inline int tcp_nagle_check(const struct tcp_sock *tp,
                      const struct sk_buff *skb,
                      unsigned mss_now, int nonagle)
{
     return (skb->len < mss_now &&
          ((nonagle & TCP_NAGLE_CORK) ||
          (!nonagle && tp->packets_out && tcp_minshall_check(tp))));
}

这个函数是说明,当包的长度小于mss值时,既考虑延迟发送。 Cork塞子的作用和nagle算法类似,目的是塞住数据,阻止数据发送,直到拔除塞子。 这里不探讨其用法。
tp->packets_out是判断是否有未确认(ack)的数据包,如果是则返回true。 显然,这里如果没有被确认的数据包的话,  (!nonagle && tp->packets_out &&tcp_minshall_check(tp))这个条件
整个儿会返回false,如果没有塞子的情况下,将导致整个儿判断返回false,nagle被禁用,这就是nagle算法处理 最后一个包的方法, 因为最后一个包一般情况下不会正好大小为mss,此时如果前面的包都被发送出去且得到确认 则不考虑其是否为大包而禁用nagle算法。
tcp_minshall_check是对nagle算法的改进,因为这种方式的延迟发送(1或者数据大小为mss,2或者前面所有包都 收到ack)在遇到延迟确认 ack_delay时,会造效率上的问题.
延迟确认根据RFC1122标准,当
1 连续收到两个大包时
2 超时(一般是200ms时)
3 有数据回发可以携带上ack标志时
发送ack包。
这就导致比如当要发送的数据是一个大包一个小包时,最后一个小包迟迟得不到发送。而这个影响在http长连接且 非pipeline模式中影响巨大。

为此,tcp_minshall_check这个函数专门用来改进nagle算法。

static inline int tcp_minshall_check(const struct tcp_sock *tp)
{
     return after(tp->snd_sml,tp->snd_una) &&
          !after(tp->snd_sml, tp->snd_nxt);
}
image006.jpg

这个函数的作用是,只要上一个小包被确认,则关闭nagle算法,这样保证了控制小包的数量(同时只有一个未确认的小包)。 同时又放宽了条件,尽量的减少ack延迟对nagle算法造成的损害。


下面是nagle算法最外层函数:

/* Return non-zero if the Nagle test allows this packet to be
* sent now.
*/
static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
                    unsigned int cur_mss, int nonagle)
{
     /* Nagle rule does not apply to frames, which sit in the middle of the
     * write_queue (they have no chances to get new data).
     *
     * This is implemented in the callers, where they modify the 'nonagle'
     * argument based upon the location of SKB in the send queue.
     */
     if (nonagle & TCP_NAGLE_PUSH)
          return 1;

     /* Don't use the nagle rule for urgent data (or for the final FIN).
     * Nagle can be ignored during F-RTO too (see RFC4138).
     */
     if (tp->urg_mode || (tp->frto_counter == 2) ||
         (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN))
          return 1;

     if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
          return 1;

     return 0;
}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26899445/viewspace-759806/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26899445/viewspace-759806/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值