9.8.1 Why
TCP在收到数据后必须发送ACK给对端,但如果每收到一个包就给一个ACK的话会使得网络中被注入过多报文。TCP的做法是在收到数据时不立即发送ACK,而是设置一个定时器,如果在定时器超时之前有数据发送给对端,则ACK会被携带在数据中捎带过去;超时则由定时器发送ACK。这样就减少了报文的发送,提高了协议的效率。
9.8.2 When
设置延迟ACK的时机主要有以下几个:
(1)发送SYN后收到SYN|ACK时:
5373 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
5374 const struct tcphdr *th, unsigned int len)
5375 {
...
5385 if (th->ack) {
,,,
5486 if (sk->sk_write_pending ||
5487 icsk->icsk_accept_queue.rskq_defer_accept ||
5488 icsk->icsk_ack.pingpong) {
5489 /* Save one ACK. Data will be ready after
5490 * several ticks, if write_pending is set.
5491 *
5492 * It may be deleted, but with this feature tcpdumps
5493 * look so _wonderfully_ clever, that I was not able
5494 * to stand against the temptation 8) --ANK
5495 */
5496 inet_csk_schedule_ack(sk);
5497 icsk->icsk_ack.lrcvtime = tcp_time_stamp;
5498 tcp_enter_quickack_mode(sk);
5499 inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
5500 TCP_DELACK_MAX, TCP_RTO_MAX); //设置延迟ACK定时器,超时时间200ms
(2)发送ACK时无法申请skb:
net/ipv4/tcp_output.c
3027 void tcp_send_ack(struct sock *sk)
3028 {
3029 struct sk_buff *buff;
3030
3031 /* If we have been reset, we may not send again. */
3032 if (sk->sk_state == TCP_CLOSE)
3033 return;
3034
3035 /* We are not putting this on the write queue, so
3036 * tcp_transmit_skb() will set the ownership to this
3037 * sock.
3038 */
3039 buff = alloc_skb(MAX_TCP_HEADER, sk_gfp_atomic(sk, GFP_ATOMIC));
3040 if (buff == NULL) {
3041