@@ -591,12 +591,76 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
591
591
592
592
593
593
594
+ === tcp中用到的算法
594
595
596
+ ==== Nagel算法
595
597
596
598
599
+ Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。根据实际代码可以得出以下结论:
597
600
601
+ 1. 如果包长度达到最大数据长度MSS(Maximum Segment Size,作为MTU的一部分)
602
+ 2. 包含FIN标记的立即传输
603
+ 3. 设置了TCP_NODELAY选项允许发送
604
+ 4. 未设置TCP_CORK选项,若所有发送出去的小数据包均被确认,则允许发送
605
+ 5. 上述条件都不满足但是发生了超时(一般为200ms),则立即发送
598
606
599
607
608
+ .network/ipv4/tcp_output.c
609
+ [source, cpp]
610
+ ----
611
+ /* Return false, if packet can be sent now without violation Nagle's rules:
612
+ * 1. It is full sized.
613
+ * 2. Or it contains FIN. (already checked by caller)
614
+ * 3. Or TCP_CORK is not set, and TCP_NODELAY is set.
615
+ * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
616
+ * With Minshall's modification: all sent small packets are ACKed.
617
+ */
618
+ static inline bool tcp_nagle_check(const struct tcp_sock *tp,
619
+ const struct sk_buff *skb,
620
+ unsigned int mss_now, int nonagle)
621
+ {
622
+ return skb->len < mss_now &&
623
+ // nonagle与TCP_NAGLE_CORK按位与的结果不为零,表示 TCP_CORK 标志未设置。
624
+ ((nonagle & TCP_NAGLE_CORK) ||
625
+ (!nonagle && tp->packets_out && tcp_minshall_check(tp)));
626
+ }
627
+
628
+ /* Return true if the Nagle test allows this packet to be
629
+ * sent now.
630
+ */
631
+ static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb,
632
+ unsigned int cur_mss, int nonagle)
633
+ {
634
+ /* Nagle rule does not apply to frames, which sit in the middle of the
635
+ * write_queue (they have no chances to get new data).
636
+ *
637
+ * This is implemented in the callers, where they modify the 'nonagle'
638
+ * argument based upon the location of SKB in the send queue.
639
+ */
640
+ if (nonagle & TCP_NAGLE_PUSH)
641
+ return true;
642
+
643
+ /* Don't use the nagle rule for urgent data (or for the final FIN).
644
+ * Nagle can be ignored during F-RTO too (see RFC4138).
645
+ */
646
+ if (tcp_urg_mode(tp) || (tp->frto_counter == 2) ||
647
+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN))
648
+ return true;
649
+
650
+ if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
651
+ return true;
652
+
653
+ return false;
654
+ }
655
+ ----
656
+
657
+ *TCP_NODELAY*
658
+
659
+ TCP_NODELAY 选项用于禁用Nagle算法。Nagle算法是为了减少网络上的小数据包数量,它会延迟发送小的数据块直到有足够的数据组成一个完整的最大段尺寸(MSS)。然而,这种延迟对于需要高实时性的应用(如在线游戏或实时通信)来说是不可接受的。通过设置 TCP_NODELAY,应用程序可以确保每个写操作的结果都会立即发送给对方,尽管这样做可能会增加网络上的小数据包数量。
660
+
661
+ *TCP_QUICKACK*
662
+
663
+ TCP_QUICKACK 选项允许接收端在接收到数据后尽快发送确认(ACK)。默认情况下,TCP协议可能会延迟发送ACK,以便与其他数据一起打包发送,从而减少网络上的ACK包数量。然而,在某些情况下,快速返回ACK可能是有益的,比如在需要快速确认数据已经送达的情况下。TCP_QUICKACK 可以让接收端在接收到数据后更快地发送ACK,但这并不意味着它会影响数据的发送策略。
600
664
601
665
602
666
0 commit comments