1 回答

TA貢獻1966條經(jīng)驗 獲得超4個贊
以下是關(guān)于您的問題的一些想法:
您不能listen()
在同一個 IP+端口上使用多個ServerSocket
.?如果可以,操作系統(tǒng)會將 SYN 數(shù)據(jù)包傳輸?shù)侥膫€套接字?*
TCP 確實維護了預(yù)先接受的連接的積壓,因此調(diào)用將accept()
(幾乎)立即返回積壓隊列中的第一個(最舊的)套接字。它通過自動發(fā)送 SYN-ACK 數(shù)據(jù)包來回復(fù)客戶端發(fā)送的 SYN,并等待回復(fù) ACK(3 次握手)來實現(xiàn)。但是,正如@zero298 所建議的那樣,盡可能快地接受連接通常不是問題。問題將是處理與您將接受的所有套接字的通信所產(chǎn)生的負載,這很可能會使您的服務(wù)器崩潰(這實際上是一次 DoS 攻擊)。實際上這個參數(shù)通常在這里 太多并發(fā)連接在積壓隊列中等待太久backlog
accept()
在到達您的應(yīng)用程序之前,ed 將被 TCP 丟棄。
我建議您使用ExecutorService
線程池來運行某個最大數(shù)量的線程,而不是為每個客戶端套接字創(chuàng)建一個線程,每個線程處理與一個客戶端的通信。這允許系統(tǒng)資源的優(yōu)雅降級,而不是創(chuàng)建數(shù)百萬個線程,這反過來會導(dǎo)致線程饑餓、內(nèi)存問題、文件描述符限制……再加上精心選擇的積壓值,您將能夠獲得您的服務(wù)器在不崩潰的情況下可以提供的最大吞吐量。run()
如果您擔(dān)心 SSL 上的 DoS,您的客戶端線程方法應(yīng)該做的第一件事就是調(diào)用startHandshake()
新連接的套接字。
關(guān)于 SSL 部分,TCP 本身不能做任何 SSL 預(yù)接受,因為它需要執(zhí)行加密/解碼、與密鑰庫對話等,這遠遠超出了它的規(guī)范。請注意,在這種情況下您還應(yīng)該使用SSLServerSocket
。
積壓隊列用于 TCP 堆棧已完成但尚未被應(yīng)用程序接受的連接。與 SSL 無關(guān)。JSSE 不會進行任何協(xié)商,直到您在已接受的套接字上執(zhí)行一些 I/O,或在其上調(diào)用 startHandshake(),這兩者都將在處理連接的線程中執(zhí)行。我看不出如何利用它制造 DOS 漏洞,至少不是特定于 SSL 的漏洞。如果您遇到 DOS 情況,很可能您正在 accept() 線程中執(zhí)行本應(yīng)在連接處理線程中完成的 I/O。
*:雖然Linux >=3.9 做了某種負載平衡,但僅適用于 UDP(所以不是?SSLServerSocket
)并且有選項SO_REUSEPORT
,這并不是在所有平臺上都可用。
添加回答
舉報