TCP的核心系列 — 重传队列的更新和时延的采样(二)

本文探讨了TCP协议中时延采样机制的细节,包括tcp_clean_rtx_queue函数的工作原理,不同类型的ACK如何影响RTT采样,以及在各种状态下(如Open、Disorder、Recovery和Loss)的时延采样行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在tcp_clean_rtx_queue()中,并非对每个ACK都进行时延采样。是否进行时延采样,跟这个ACK是否为

重复的ACK、这个ACK是否确认了重传包,以及是否使用时间戳选项都有关系。

 

本文主要内容:tcp_clean_rtx_queue()的一些细节,时延采样的条件。

内核版本:3.2.12

Author:zhangskd @ csdn

 

记分牌

 

TCP_SKB_CB(skb)->sacked称为skb的记分牌,用于跟踪skb的状态。

以下是skb记分牌可能的取值:

#define TCPCB_SACKED_ACKED 0x01 /* skb被SACKed */
#define TCPCB_SACKED_RETRANS 0x02 /* skb retransmitted */
#define TCPCB_LOST 0x04 /* skb判断为LOST */
#define TCPCB_TAGBITS 0x07 /* All tag bits */
#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */
#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS | TCPCB_EVER_RETRANS)

 

TCPCB_SACKED_RETRANS和TCPCB_EVER_RETRANS有什么区别呢?

当一个skb被重传了,它的记分牌就会添加TCPCB_RETRANS标志。

当重传的skb被sack确认或者ack累积确认时,就会清除TCPCB_SACKED_RETRANS标志,

但是这个时候TCPCB_EVER_RETRANS还保留,表示这个skb曾经被重传过。

TCPCB_EVER_RETRANS在更新RTT中发挥作用,如果skb曾经重传过,那么就不根据它来计算RTT

采样值,更新srtt和rto等。

 

释放段

 

从发送队列sk->sk_write_queue上移除skb,并非从物理内存中释放skb。

static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk)
{
    __skb_unlink(skb, &sk->sk_write_queue);
}

static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
{
    struct sk_buff *next, *prev;
    list->qlen--; /* 发送队列长度减1 */
    next = skb->next;
    prev = skb->prev;
    skb->next = skb->prev = NULL;
    next->prev = prev;
    prev->next = next;
}

static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
{
    sock_set_flag(sk, SOCK_QUEUE_SHRUNK); /* 设置标志,表示有skb释放了*/
    sk->sk_wmem_queue -= skb->truesize; /* 更新发送队列所占内存*/
    sk_mem_uncharge(sk, skb->truesize);
    __kfree_skb(skb); /* 释放skb占用的内存*/
}

 

Reno ACK处理

 

场景:Reno中收到ACK的时候。

这时候会模拟SACK,更新tp->sacked_out和tp->reordering。

/* Account for ACK, ACKing some data in Reno Recovery phase. */
static void tcp_remove_reno_sacks(struct sock *sk, int acked)
{
    struct tcp_sock *tp = tcp_sk(sk);

    if (acked > 0) {
        /* One ACK acked hole. The rest eat duplicate ACKs.
         * 收到正常ACK,不在Recovery状态。
         * 收到Cummulative ACK,确认完所有的sacked包。
         */
        if (acked - 1 >= tp->sacked_out)
            tp->sacked_out = 0;
        else /* 收到Partial ACK,确认了部分sack包*/
            tp->sacked_out -= acked - 1;
    }

    /* 检查是否有乱序,有的话更新tp->reordering */
    tcp_check_reno_reordering(sk, acked); 
    tcp_verify_left_out(tp);
}

 

时延采样

 

(1)什么情况下进行RTT采样?

首先,如果是重复的ACK,即没有使snd_una前进的ACK,那么是不会进入RTT更新路径的:

if (flag & FLAG_ACKED)

{

    ...

    tcp_ack_update_rtt(sk, flag, seq_rtt);

    tcp_rearm_rto(sk);

    ...

}

 

其次,有确认新数据的情况下:

1. 没有使用时间戳选项(tcp_ack_no_tstamp)

    确认的数据段中不能包含重传过的段(FLAG_RETRANS_DATA_ACKED)。

    因为我们无法知道是哪个包,原始包还是重传包触发了这个ACK,因此无法确定触发包的

    发送时间。

    如果此ACK确认了多个段,则使用第一个被确认段的发送时间来计算seq_rtt。

 

2. 使用时间戳选项(tcp_ack_saw_tstamp)

    RTTM rule:A TSecr value received in a segment is used to update the averaged

    RTT measurement only if the segment acknowledges some new data, i.e, only if

    it advances the left edge of the send window.

    此时我们知道这个ACK的触发段的确切发送时间为:tp->rx_opt.rcv_tsecr,所以我们计算得到

    的RTT总是正确的,而不用去考虑触发这个ACK的是原始包还是重传包。

 

(2)icsk_ca_ops->pkts_acked()的调用

如果被此ACK确认的数据段中,含有重传过的数据段,那么就设置FLAG_RETRANS_DATA_ACKED,

ca_ops->pkts_acked(sk, pkts_acked, rtt_us)中的rtt_us = -1。

 

当有FLAG_ACKED标志(FLAG_DATA_ACKED | FLAG_SYN_ACKED)时调用。

有FLAG_RETRANS_DATA_ACKED设置,表示此ACK确认的是重传的数据包,这个时候rtt_us为-1。

#define FLAG_NOT_DUP (FLAG_DATA | FLAG_WIN_UPDATE | FLAG_ACKED)

Q: 那么,在什么情况下无法观测到正常的RTT呢?

A: 重传数据包的ACK、Dup ACK、Partical ACK、Cumulative ACK。

 

(3)各个状态下的时延采样

1. Open、CWR

    对每个ACK都进行RTT采样。

2. Disorder

    dup ACK,不进行RTT采样。

    cumulative ACK,进行RTT采样。

3. Recovery

    dup ACK,不进行RTT采样。

    partical ACK

         不启用Timstamp,不进行RTT采样。

         启用Timestamp,进行RTT采样。

    cumulative ACK

         不启用Timstamp,不进行RTT采样。

         启用Timestamp,进行RTT采样。

4. Loss

    partical ACK

         不启用Timstamp,不进行RTT采样。

         启用Timestamp,进行RTT采样。

    cumulative ACK

         不启用Timstamp,不进行RTT采样。

         启用Timestamp,进行RTT采样。

 

(4)重置超时重传定时器

每次更新SRTT和RTO后,都重置超时重传定时器。

/* Restart timer after forward progress on connection.
 * RFC2988 recommends to restart timer to now + rto.
 */
static void tcp_rearm_rto(struct sock *sk)
{
    const struct tcp_sock *tp = tcp_sk(sk);

    if (! tp->packets_out) { /* 如果网络上没有数据,删除超时重传定时器*/
        inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);

    } else { /* 重置超时重传定时器*/
        inet_csk_reset_ximit_timer(sk, ICSK_TIME_RETRANS, inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
    }
}

 

转载于:https://www.cnblogs.com/aiwz/p/6333340.html

<think>好的,我现在需要帮助用户寻找关于基于时延敏感属性进行智能感知流量调度的相关资料或实现方法。用户的问题涉及三个关键词:时延敏感属性、智能感知、流量调度,以及实现方案算法。首先,我需要理解每个术语的含义以及它们之间的关系。 首先,“时延敏感属性”应该指的是在网络流量中对延迟非常敏感的应用或数据流的特性,比如实时视频通话、在线游戏、工业自动化控制等,这些应用需要低延迟以保证服务质量。接下来,“智能感知”可能是指系统能够动态地识别分类这些流量,根据实时网络状况进行调整。而“流量调度”则是根据感知到的信息,动态分配网络资源,确保时延敏感的应用得到优先处理。 接下来,我需要考虑如何将这三个概念结合起来,形成一个实现方案。可能需要参考相关的网络调度算法、机器学习方法,或者结合边缘计算等技术。根据用户提供的引用,特别是引用[1]中提到的DeepSwarm框架,它涉及边缘群体智能感知计算的双向优化,可能与此相关。此外,引用[4]提到的算力网络“东数西算”工程,可能涉及资源调度网络优化,这也是需要考虑的。 然后,我需要考虑现有的算法或框架,比如OMP算法(引用[2]提到的稀疏信号恢复,可能与数据处理相关)、PID控制(引用[5]提到的控制方法,可能用于调整参数)或者神经网络模型(引用[3]的统一算法框架)。这些可能被应用在流量调度中,实现智能感知动态调整。 接下来,可能的实现步骤包括: 1. 流量特征提取与分类:使用机器学习或深度学习方法识别时延敏感流量,例如通过数据包大小、传输频率、协议类型等特征进行分类。 2. 动态优先级分配:根据实时网络状态(如带宽、延迟、丢包率)动态调整流量优先级,确保关键流量优先传输。 3. 资源调度算法:设计或采用现有算法(如强化学习、PID控制、OMP算法)进行资源分配,优化网络性能。 4. 边缘计算协同:利用边缘节点进行本地处理,减少数据传输时延,如引用[1]中的边缘智能感知框架。 5. 实时监控与反馈:建立监控机制,实时评估调度效果,并调整参数,类似PID控制中的闭环反馈。 可能涉及的挑战包括动态环境下的算法鲁棒性(引用[1]提到的传感器噪声异常值)、计算效率与准确性的平衡(引用[1][4])、以及如何实时适应网络变化(引用[5]的PID参数调整)。 还需要考虑具体的技术实现,比如使用SDN(软件定义网络)来集中控制流量调度,或者结合AI模型进行预测性调度。例如,引用[3]提到的统一神经网络框架可能用于端到端的优化。 最后,需要验证这些方法的有效性,可能通过仿真实验或实际部署,评估时延降低的程度、资源利用率等指标。 总结来说,实现方案可能结合智能感知技术(如深度学习分类)、动态调度算法(强化学习或优化算法)以及边缘计算架构,同时考虑系统的鲁棒性实时性。需要进一步查阅具体的算法细节案例研究,如引用中的DeepSwarm、OMP、PID控制等方法如何被整合到流量调度中。</think>### 基于时延敏感属性的智能感知流量调度实现方案 #### 1. **核心概念解析** - **时延敏感属性**:指业务流量对网络延迟的容忍度低,需优先保障传输时效性,如工业控制、实时视频等[^4]。 - **智能感知**:通过动态监测网络状态(如带宽、抖动、丢包率)及流量特征(如协议类型、数据包大小),识别关键流量[^1]。 - **流量调度**:基于感知结果,动态分配网络资源(如带宽、路径、优先级),确保时延敏感业务的服务质量(QoS)。 --- #### 2. **实现方案关键技术** ##### **(1) 流量特征提取与分类** - **方法**:采用轻量级机器学习模型(如随机森林、LSTM)对流量进行实时分类。 - **输入特征**:数据包大小、传输频率、协议类型(如UDP/TCP)、端到端延迟需求[^1]。 - **示例算法**: ```python # 基于随机森林的流量分类 from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier() model.fit(training_features, labels) # 特征包括时延敏感标记、流量统计量 ``` ##### **(2) 动态优先级分配** - **策略**:根据实时网络负载调整流量优先级,例如: - **SDN(软件定义网络)**:通过集中控制器(如OpenFlow)动态设置流表规则。 - **权重队列调度**:为时延敏感流量分配高优先级队列,如IEEE 802.1Qbv时间敏感网络(TSN)标准。 ##### **(3) 资源调度算法** - **强化学习(RL)**:训练智能体根据网络状态选择最优路径或带宽分配,最大化QoS指标[^3]。 ```python # 示例DQN框架 state = [current_delay, bandwidth_usage, queue_length] action = agent.choose_action(state) # 选择调度策略 reward = calculate_qos_improvement() agent.update_model(state, action, reward) ``` - **内模控制(IMC)**:引用[5]提出的PID参数整定方法,可扩展至网络拥塞控制,动态调整调度参数。 ##### **(4) 边缘计算协同** - **边缘节点预处理**:在靠近数据源的边缘节点过滤冗余数据,减少核心网负载。 - **算力感知网络**:结合引用[4]的“算力网络”架构,根据节点算力动态分配计算任务,降低端到端时延。 --- #### 3. **典型算法与案例** - **OMP算法改进**:引用[2]的稀疏信号恢复思想可用于压缩感知网络流量,减少传输数据量。 $$ \min \|s\|_0 \quad \text{s.t.} \quad y = \Phi s $$ 其中$y$为观测数据,$\Phi$为测量矩阵,$s$为稀疏流量特征。 - **DeepSwarm框架适配**:引用[1]的群体智能感知框架可优化多传感器协同采样,降低传输延迟。 --- #### 4. **挑战与解决方案** | 挑战 | 解决方案 | |---------------------|--------------------------------------------------------------------------| | 动态环境适应性 | 采用强化学习在线优化策略 + PID控制实时微调参数[^5] | | 计算效率与准确性平衡| 边缘节点部署轻量级模型 + 算力网络动态分配任务 | | 异常事件鲁棒性 | 引入异常检测模块(如孤立森林算法) + 冗余路径备份 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值