免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4090 | 回复: 3
打印 上一主题 下一主题

tcp实现中tcp_incr_quickack()函数的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-06 11:46 |只看该作者 |倒序浏览
tcp_input.c里面有如下定义:
static void tcp_incr_quickack(struct tcp_opt *tp)
{
        unsigned quickacks = tp->rcv_wnd/(2*tp->ack.rcv_mss);

        if (quickacks==0)
                quickacks=2;
        if (quickacks > tp->ack.quick)
                tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
}

ack.quick的意义是不是启动快速重传时所要接收到的dup ack的个数?
如果是的话为什么ack.quick的值要用tp->rcv_wnd和tp->ack.rcv_mss去估算?
我觉得应该是用tp->snd_wnd和tp->mss_cache去估算,因为这个ack的个数应视接收端能容纳的数据

段来定,如果接受端窗口容纳不了这么多段的数据,那根本不可能有这如此数目的重复ack发过来,

因此也就不能触发快速重传算法。(内核版本2.4.22)

十分不解,请高手指点。谢谢。

论坛徽章:
0
2 [报告]
发表于 2010-05-06 13:59 |只看该作者
本帖最后由 lmarsin 于 2010-05-07 15:21 编辑

struct {...} icsk_ack

延时确认控制数据块,以下是对各字段的简要描述

__u8 pending

标识当前需发送确认的紧急程度和状态。在数据从内核空间复制到用户空间时会检测该状态,如果需要则立即发送确认;而在计算rcv_mss时,会根据情况调整此状态。由于pending是按位存储的,因此多个状态可以同时存在。


pending
  描述
  ICSK_ACK_SCHED
ACK需要发送,是立即发送还是延时发送,还需要看其他标志,也是能否发送确认的前提。在接收到有负荷的TCP段后,会设置该标志。  
  ICSK_ACK_TIMER延时发送ACK定时器已经启动。
  ICSK_ACK_PUSHED只要有ACK需要发送,并且pingpong0时,ACK可以立即发送。
  ICSK_ACK_PUSHED2只要有ACK需要发送,都可以立即发送,不管是否在快速发送模式中。

__u8 quick

标识在快速发送确认模式中,可以快速发送ACK段的数量。与pingpong一同作为判断是否在快速发送确认模式下的条件,如果要延时发送确认,则必须要在延时发送确认模式下。

__u8 pingpong

标识启用或禁用快速确认模式。通过TCP_QUICKACK选项可以设置其值


  pingpong    描述
  0
  不延时ACK段的发送,而是进行快速发送。
  1    将会延时发送ACK  

在快速确认模式下,会立即发送ACK。整个TCP处理过程中,如果需要还会进入到正常模式运行,也就是说,这个标志的设置不是永久性的,而只是在当时启用/禁用快速确认模式,在这之后,根据如延时确认超时、数据传输因素等,有可能会再次进入或离开快速确认模式。

__u8 blocked

软中断和用户进程是不能同时占有锁定套接口的,因此如果套接口已被用户进程锁定,而此时延时ACK定时器被触发,在逻辑上说此时应该发送ACK,但由于套接口被用户进程锁定了不能访问,因此只能置blocked标志为1,表示“套接口被用户进程锁定了,现不能发送ACK,如果有机会立即发送ACK”,这些机会包括接收到数据之后和将数据复制到用户空间之后。

__u32 ato

用来计算延时确认的估值,在接收到TCP段时会根据本次与上次接收的时间间隔来调整该值,而在设置延时确认定时器时也会根据条件调整该值

unsignedlong timeout

当前的延时确认时间,超时后会发送ACK

__u32 lrcvtime

标识最近一次接收到数据包的时间

__u16 last_seg_size

最后一个接收到的段的长度,用来计算rcv_mss

__u16 rcv_mss

由最近接收到段计算出的MSS,主要用来确定是否执行延时确认。

论坛徽章:
0
3 [报告]
发表于 2010-05-06 14:02 |只看该作者
本帖最后由 lmarsin 于 2010-05-07 10:22 编辑

TCP接收到数据后,需发送相应的确认,但如果只是为了确认就发送一个段,这样会增加不必要的网路流量,而解决这个问题的最好方法就是延迟确认,因为ACK不占用TCP段资源,因此可以将ACK与数据一起发送给对端。因此TCP使用两种模式来处理确认接收到的数据,即快速确认和延迟确认。在整个TCP发送和接收过程中,由于网络拥塞、接收到小包等原因会在快速确认和延迟确认模式之间切换。

TCP进入延迟确认模式,通常接收到两个TCP段产生一个确认或者延迟在0.5秒之内产生一个确认。

尽管代码中也有检测是否在快速确认模式的函数,但事实上确定使用快速确认还是延迟确认有些复杂,存在多个条件。在以下任何一种情况都会导致快速确认:

1)FIN_WAIT_1FIN_WAIT_2状态下接收到FIN

2)SYN_SENT状态下,PAWS校验失败或接收到已确认的段,发送DACK

3)在接收的慢速路径处理中,PAWS校验失败或收到已确认的段,发送DACK

4)接收到多个全尺寸的段且接收窗口的右端已更新;

5)快速确认模式下;

6)乱序TCP段队列中还有待处理段;

7)连续接收到2个小包,即小于536字节的段;

评分

参与人数 1可用积分 +18 收起 理由
Godbach + 18 多谢分享

查看全部评分

论坛徽章:
0
4 [报告]
发表于 2010-05-06 17:50 |只看该作者
谢谢lmarsin ,我偏得有点远了。。呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP