Tcp
沒有丟包的 TCP 重複確認
編輯:實際上存在 2 個問題,執行 RTOS 的設備上的 TCP 實現有問題,以及當超過 1 個核心處於活動狀態時導致 Linux 網路堆棧無序接收 TCP 片段的問題。
我有一個在 IP 192.168.2.250 上執行一些嵌入式 RTOS 的發送器和一個在 IP 192.168.2.1 上執行 Linux 4.9.x 的接收器
接收器配置為無線接入點,發送器通過 WiFi 直接連接到接收器。
我在 TCP 數據傳輸期間在接收端做了一個 tcpdump,我注意到接收器發送了很多重複的 ACK,而沒有發生實際的封包遺失(或者至少我是這麼認為的,因為我沒有看到重傳和ACK 最終會跟隨發送的序列號)。
有人知道可能導致接收器行為的原因嗎?
編輯:您沒有看到來自發件人的快速重傳,因為我將它們關閉以證明流沒有失去數據(這樣做會使吞吐量大大提高)。一種解釋是 tcp 堆棧看到的數據包亂序。我可以讓 Linux 更能容忍亂序數據包嗎?就像不立即發送重複確認一樣。
的輸出
sysctl net | grep tcp
net.ipv4.tcp_abort_on_overflow=0 net.ipv4.tcp_adv_win_scale=1 net.ipv4.tcp_allowed_congestion_control=cubic reno net.ipv4.tcp_app_win=31 net.ipv4.tcp_autocorking=1 net.ipv4.tcp_available_congestion_control=cubic reno net.ipv4.tcp_base_mss=1024 net.ipv4.tcp_challenge_ack_limit=1000 net.ipv4.tcp_congestion_control=cubic net.ipv4.tcp_delack_seg=1 net.ipv4.tcp_dsack=1 net.ipv4.tcp_early_retrans=3 net.ipv4.tcp_ecn=2 net.ipv4.tcp_ecn_fallback=1 net.ipv4.tcp_fack=1 net.ipv4.tcp_fastopen=1 net.ipv4.tcp_fin_timeout=60 net.ipv4.tcp_frto=2 net.ipv4.tcp_fwmark_accept=0 net.ipv4.tcp_invalid_ratelimit=500 net.ipv4.tcp_keepalive_intvl=75 net.ipv4.tcp_keepalive_probes=9 net.ipv4.tcp_keepalive_time=7200 net.ipv4.tcp_limit_output_bytes=262144 net.ipv4.tcp_low_latency=0 net.ipv4.tcp_max_orphans=16384 net.ipv4.tcp_max_reordering=300 net.ipv4.tcp_max_syn_backlog=128 net.ipv4.tcp_max_tw_buckets=16384 net.ipv4.tcp_mem=332494433366498 net.ipv4.tcp_min_rtt_wlen=300 net.ipv4.tcp_min_tso_segs=2 net.ipv4.tcp_moderate_rcvbuf=1 net.ipv4.tcp_mtu_probing=0 net.ipv4.tcp_no_metrics_save=0 net.ipv4.tcp_notsent_lowat=4294967295 net.ipv4.tcp_orphan_retries=0 net.ipv4.tcp_pacing_ca_ratio=120 net.ipv4.tcp_pacing_ss_ratio=200 net.ipv4.tcp_probe_interval=600 net.ipv4.tcp_probe_threshold=8 net.ipv4.tcp_recovery=1 net.ipv4.tcp_reordering=3 net.ipv4.tcp_retrans_collapse=1 net.ipv4.tcp_retries1=3 net.ipv4.tcp_retries2=15 net.ipv4.tcp_rfc1337=0 net.ipv4.tcp_rmem=4096873806291456 net.ipv4.tcp_sack=1 net.ipv4.tcp_slow_start_after_idle=1 net.ipv4.tcp_stdurg=0 net.ipv4.tcp_syn_retries=6 net.ipv4.tcp_synack_retries=5 net.ipv4.tcp_syncookies=1 net.ipv4.tcp_thin_dupack=0 net.ipv4.tcp_thin_linear_timeouts=0 net.ipv4.tcp_timestamps=0 net.ipv4.tcp_tso_win_divisor=3 net.ipv4.tcp_tw_recycle=0 net.ipv4.tcp_tw_reuse=0 net.ipv4.tcp_use_userconfig=0 net.ipv4.tcp_window_scaling=1 net.ipv4.tcp_wmem=4096163844194304 net.ipv4.tcp_workaround_signed_windows=0
出於某種原因,
.250
正在為它已經收到的 SEQ 發送舊的 ACK 值。見數據包#551:.1
狀態SEQ=290541
。在數據包 #552 中,.250
說ACK=267181
. 因此,由於.250
確認號 (267181) 低於.1
序列號 (290541),因此.1
假設.250
失去了 #551,因為 #552 和 #558 之間的所有數據包都使用過時SEQ=267181
的數據包,並為它接收到的每個數據包發送另一個 ACK,其中包含過期的 ACK 編號。如果 RTOS 沒有報告失去,我們只能假設它的調度程序優先推送數據而不是處理確認。