当前位置: 技术问答>linux和unix
TCP重传定时器的疑问
来源: 互联网 发布时间:2016-11-13
本文导语: 关于TCP的重传定时器一直有一个疑问,昨天看了一下linux下TCP的實現,其中关键有一个函数:如下 C/C++ codestatic void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); unsigned int prior_pac...
关于TCP的重传定时器一直有一个疑问,昨天看了一下linux下TCP的實現,其中关键有一个函数:如下
C/C++ codestatic void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
unsigned int prior_packets = tp->packets_out;
tcp_advance_send_head(sk, skb);
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
/* Don't override Nagle indefinately with F-RTO */
if (tp->frto_counter == 2)
tp->frto_counter = 3;
//关键在这里tp->packets_out += tcp_skb_pcount(skb);
if (!prior_packets)
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
}
可以看到只有当prior_packets为0时才会重启定时器,而prior_packets则是发送未确认的段的个数,也就是说如果
发送了很多段,如果前面的段没有确认,那么后面发送的时候不会重启这个定时器.
如果这样的话 在t0时刻启动定时器,发送0,1,2三个报文段,t1时刻收到了对0的ACK,此时我们可以向网络中增加一个报文段3,因为1.2还没有被确认所以根据上面的情况,不会重启定时器,此时定时器的RTO不变,那么怎么来判断3的超时呢,因为定时器从启动到现在已经经过了t1-t0的时间,所以再经过RTO-(t1-t0)就会超时,如果经过RTO-(t1-t0)超时了,那么3算不算超时呢?
C/C++ codestatic void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
unsigned int prior_packets = tp->packets_out;
tcp_advance_send_head(sk, skb);
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
/* Don't override Nagle indefinately with F-RTO */
if (tp->frto_counter == 2)
tp->frto_counter = 3;
//关键在这里tp->packets_out += tcp_skb_pcount(skb);
if (!prior_packets)
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
}
可以看到只有当prior_packets为0时才会重启定时器,而prior_packets则是发送未确认的段的个数,也就是说如果
发送了很多段,如果前面的段没有确认,那么后面发送的时候不会重启这个定时器.
如果这样的话 在t0时刻启动定时器,发送0,1,2三个报文段,t1时刻收到了对0的ACK,此时我们可以向网络中增加一个报文段3,因为1.2还没有被确认所以根据上面的情况,不会重启定时器,此时定时器的RTO不变,那么怎么来判断3的超时呢,因为定时器从启动到现在已经经过了t1-t0的时间,所以再经过RTO-(t1-t0)就会超时,如果经过RTO-(t1-t0)超时了,那么3算不算超时呢?
|
TCP是每发送一个packet,就会启动此packet的重传定时器.
另外,贴代码时,注意把kernel version附上.
另外,贴代码时,注意把kernel version附上.
|
你不如去看RFC文档.