簡體   English   中英

TCP服務器不接受具有少量偵聽積壓的客戶端發出的正確連接數

[英]TCP server not accepting right number of connections issued by client with small listen backlog

我編寫了一個簡單的客戶端程序,在很短的時間內使用100個線程發出了10000個連接。 一個簡單的服務器程序,使用epoll將listen backlog設置為20,僅用於接受任何新連接並記錄總連接數。 我使用了ulimit -n來確保它大於20000,因此應該有足夠的fd資源。

但是在服務器程序accept 8800、9400(非固定)連接后,它只是停止接受任何新連接。 客戶端使用阻塞connect建立連接,所有這10000個connect調用均成功返回。 然后,所有內容凍結,不再有數據包(沒有重新傳輸),也沒有更多的接受連接。

但是,一旦我關閉了客戶端程序,服務器程序在關閉了一些連接之后便開始接受其余的連接(並最終接受了所有10000個連接並關閉了所有這些連接)。

當我將backlog更改為100或更大時,所有10000個連接都被接受,沒有任何問題。 (所以這不是fd資源問題)

我知道,當接受隊列已滿時,Linux可能會忽略3Way握手的傳入ACK ,保留客戶端的連接已建立,但服務器的連接仍未建立,然后讓重傳機制起作用。 最終服務器重傳SYN/ACK包,如果服務器的接受隊列可用,則客戶端以ACK響應以重新建立此連接。 如果隊列中沒有可用空間,則服務器將再次忽略該ACK

但是,當我使用wireshark監視這些重傳時,我發現僅發生了少量的SYN/ACK重傳(例如100〜200,遠少於丟失的連接數(介於500〜1500之間)),它們只是被重傳了一次或兩次,都小於/proc/sys/net/ipv4/tcp_synack_retries指定的值。 我檢查了其中一些重傳的SYN/ACK數據包,所有這些數據包都從客戶端接收到ACK 但是從客戶端重傳的SYN數據包的數量很大。

那么潛在的細節是什么?

這是我的代碼: 客戶端 服務器

當積壓已滿並且啟用了SYN cookie時,內核將激活臨時SYN泛洪模式。 下圖顯示了cookie的工作方式( ):

在此處輸入圖片說明

激活SYN Flood后,將從客戶端發送的所有ACK丟棄。 服務器僅向客戶端發送了SYN / ACK和cookie,因此cookie緩存表將比套接字表小得多,以保持活動連接。 在這種情況下,在客戶端,套接字被認為已建立,但在服務器端並沒有真正打開任何東西(半開連接)。

當客戶端應用程序關閉套接字時,帶有ACK標志設置的FIN數據包將被發送到服務器,其中包含cookie,服務器將看到連接具有ACK,此時,如果積壓未滿,服務器將嘗試從cookie重建連接。 如果cookie有效(在有效的往返時間內),則套接字將被添加到積壓隊列中,並且可以作為普通套接字進行處理。

這意味着,在激活SYN cookie模式並且積壓隊列未滿時,如果客戶端通過半開套接字向服務器發送一些數據,accept()函數將返回新的傳入連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM