免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

TCP/IP实现刨根究底大讨论【活动结束】 [复制链接]

论坛徽章:
0
181 [报告]
发表于 2011-04-04 18:06 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
182 [报告]
发表于 2011-04-04 20:04 |只看该作者
问个没想明白的问题。
软件方法QOS,能分类限流量。必定是缓存了若干包的。
那么作为转发来说。原来一个软中断接受然后处理。然后发送。现在有缓存,那么原来一个执行流被分成2部分?

评分

参与人数 1可用积分 +2 收起 理由
Godbach + 2 欢迎提问

查看全部评分

论坛徽章:
0
183 [报告]
发表于 2011-04-05 07:36 |只看该作者
tcp ip 能够实现的原因应该就是把信息进行封装   分层处理     各层互相依靠  这样能够有效的保证数据得到保护和传送

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
184 [报告]
发表于 2011-04-05 10:34 |只看该作者
回复 182# 绝望の生鱼片


   
软件方法QOS,能分类限流量。必定是缓存了若干包的。
那么作为转发来说。原来一个软中断接受然后处理。然后发送。现在有缓存,那么原来一个执行流被分成2部分?


LZ 了解过 QoS 吗。你为什么说要缓存若干包啊。

论坛徽章:
0
185 [报告]
发表于 2011-04-05 12:33 |只看该作者
回复 184# Godbach


    没了解过 但感觉缓存是必然的
否则来一个包就发一个,从接收的软中断开始一直运行到网卡发送函数,和没QOS不是一样了?

论坛徽章:
0
186 [报告]
发表于 2011-04-06 09:53 |只看该作者
不错的话题。我很有兴趣。

论坛徽章:
0
187 [报告]
发表于 2011-04-06 10:06 |只看该作者
本帖最后由 xiongweixie 于 2011-04-06 10:12 编辑

回复 157# ynchnluiti


    谢谢你。我看明白那个公式怎么来的了。根据下面这个函数。化简得 delayed_ack = 15/16*delayed_ack + cnt;
    由于 ratio = delayed_ack/ 16;  所以 ratio = 15/16 * ratio + cnt / 16;
/*
* ratio = (15*ratio + sample) / 16
*/
static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt)
{
        const struct inet_connection_sock *icsk = inet_csk(sk);

        if (icsk->icsk_ca_state == TCP_CA_Open) {
                struct bictcp *ca = inet_csk_ca(sk);
                cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;                        /// ACK_RATIO_SHIFT = 4
                ca->delayed_ack += cnt;
        }
}
///////////******************************************************************//////////////////////////////////////
还有个问题,
/*
*        behave like Reno until low_window is reached,
*        then increase congestion window slowly
*/
static u32 bictcp_recalc_ssthresh(struct sock *sk)
{
        const struct tcp_sock *tp = tcp_sk(sk);
        struct bictcp *ca = inet_csk_ca(sk);

        ca->epoch_start = 0;        /* end of epoch */

        /* Wmax and fast convergence */
        if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)               
                ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
                        / (2 * BICTCP_BETA_SCALE);                                                                ///更改last_max_cwnd 的值 = snd_cwnd*(1+ 0.8 )/2
        else
                ca->last_max_cwnd = tp->snd_cwnd;                                                        ///否则 把最大拥塞窗口设为 当前snd_cwnd

        ca->loss_cwnd = tp->snd_cwnd;


        if (tp->snd_cwnd <= low_window)                                                                        ///snd_cwnd 小于 low_window,返回 2 或者snd_cwnd/2 中的大值, 常规方法
                return max(tp->snd_cwnd >> 1U, 2U);
        else
                return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
}
这个函数是在发生拥塞时调用的吧。是么?

static u32 bictcp_undo_cwnd(struct sock *sk)                                               
{
        const struct tcp_sock *tp = tcp_sk(sk);
        const struct bictcp *ca = inet_csk_ca(sk);
        return max(tp->snd_cwnd, ca->last_max_cwnd);
}        //这个也是拥塞时 在bictcp_recalc_ssthresh调用后调用的吧。

那我就有疑问了,bictcp_recalc_ssthresh 将last_max_cwnd置为snd_cwnd 或者 0.9*snd_cwnd。 那么这里的返回max中是不是就永远是返回snd_cwnd了。还是我把调用顺序搞错了。
请你指点一下。谢谢

评分

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

查看全部评分

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
188 [报告]
发表于 2011-04-06 11:36 |只看该作者
回复 187# xiongweixie

   
...那么这里的返回max中是不是就永远是返回snd_cwnd了。还是我把调用顺序搞错了。

    你说的调用顺序没错。bictcp_recalc_ssthresh() 在进入拥塞状态时调用,bictcp_undo_cwnd() 在退出拥塞状态时调用

    进入拥塞状态时,ca->last_max_cwnd = cwnd1 < ca->last_max_cwnd  //bictcp_recalc_ssthresh(): ( tp->snd_cwnd < ca->last_max_cwnd && fast_convergence )
                                                  ? cwnd1 * 0.9
                                                  : cwnd1
                                                  ;
   
退出拥塞状态时,cwnd = max (cwnd2, ca->last_max_cwnd);         //bictcp_undo_cwnd(): max(tp->snd_cwnd, ca->last_max_cwnd);

    进入和退出拥塞状态时的 cwnd 是两个值。具体怎么控制 cwnd 正是拥塞算法要做的事。

评分

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

查看全部评分

论坛徽章:
0
189 [报告]
发表于 2011-04-06 13:03 |只看该作者
回复  绝望の生鱼片


   

LZ 了解过 QoS 吗。你为什么说要缓存若干包啊。
Godbach 发表于 2011-04-05 10:34


内核里的 QoS 实现是需要一个 queue 的,queue 不满则整形,如果满了则丢包
“绝望の生鱼片” 可能说的是这个 queue 的东西

评分

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

查看全部评分

论坛徽章:
0
190 [报告]
发表于 2011-04-06 14:54 |只看该作者
本帖最后由 xiongweixie 于 2011-04-06 14:56 编辑

回复 188# ynchnluiti

    你说的我明白了。谢谢你!

    我再请教2个问题。

    1、判断进入拥塞状态的方法,比如是连续收到三个相同的ack。
    离开拥塞状态具体是什么状态。我猜是指拥塞窗口大于ssthresh后,不知道对不对?
    正常的tcp拥塞控制是发生拥塞时,ssthresh设为当前拥塞窗口的一半,然后进行慢启动。当拥塞窗口超过ssthresh时,进行线性递增。离开拥塞状态是指线性递增的状态么?

    2、在bictcp中,主要有5个函数。如下 bictcp_update(struct bictcp *ca, u32 cwnd), bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight),  bictcp_recalc_ssthresh(struct sock *sk),  bictcp_undo_cwnd(struct sock *sk), bictcp_acked(struct sock *sk, u32 cnt, s32 rtt) 。

     我的理解是 每收到一个ack, 会调用一个 bictcp_acked, 用来更新 delayed_ack,因为调整拥塞窗口会用到delayed_ack;还会调用一次 bictcp_cong_avoid, bictcp_update 是由bictcp_cong_avoid 调用的。当检测到拥塞时,调用 bictcp_recalc_ssthresh, 离开拥塞状态时 调用bictcp_undo_cwnd。

     不知道我的理解对不对。请你指导一下。
     谢谢。

评分

参与人数 1可用积分 +2 收起 理由
Godbach + 2 欢迎提问

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP