在使用PHP 進行網絡編程時, socket_accept()是接受客戶端連接的核心函數。面對DoS(Denial of Service)攻擊,攻擊者通常會通過大量惡意連接請求,耗盡服務器資源,導致服務器無法正常響應合法用戶請求。本文將講解如何通過限制socket_accept()接受的最大連接數,有效防止服務器被惡意拖垮。
DoS 攻擊中,攻擊者製造大量連接請求佔滿服務器的並發連接數,導致服務器無法處理新的正常請求。限制最大連接數,確保服務器在資源許可範圍內只處理一定數量的客戶端連接,可以有效降低這種攻擊帶來的影響。
使用變量計數當前已建立的連接數。
在接收到新的連接時,判斷當前連接數是否超過限制。
超過限制時拒絕連接(關閉新連接),不再調用socket_accept()處理。
連接關閉時,及時減少連接計數。
下面的代碼示範瞭如何在PHP 中實現基於socket_accept()的最大連接數限制,假設最大連接數為100:
<?php
set_time_limit(0);
error_reporting(E_ALL);
$address = '0.0.0.0';
$port = 12345;
$maxConnections = 100;
$currentConnections = 0;
// 創建 TCP Socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port) or die('綁定失敗');
socket_listen($sock);
echo "服務器啟動,監聽 {$address}:{$port}\n";
$clients = [];
while (true) {
// 判斷是否超過最大連接數
if ($currentConnections < $maxConnections) {
// 非阻塞模式接受新連接
socket_set_nonblock($sock);
$client = @socket_accept($sock);
if ($client !== false) {
// 新連接成功,計數加一
$currentConnections++;
$clients[] = $client;
// 設置客戶端socket為非阻塞
socket_set_nonblock($client);
echo "新客戶端連接,當前連接數: $currentConnections\n";
}
} else {
// 超出最大連接數,拒絕新連接(可選等待短暫時間)
usleep(100000); // 100ms
}
// 輪詢處理已連接客戶端的數據
foreach ($clients as $key => $clientSocket) {
$data = @socket_read($clientSocket, 2048, PHP_NORMAL_READ);
if ($data === false) {
// 連接斷開,移除客戶端
socket_close($clientSocket);
unset($clients[$key]);
$currentConnections--;
echo "客戶端斷開,當前連接數: $currentConnections\n";
continue;
} elseif ($data !== '') {
$data = trim($data);
if ($data === 'quit') {
// 客戶端主動斷開連接
socket_close($clientSocket);
unset($clients[$key]);
$currentConnections--;
echo "客戶端主動斷開,當前連接數: $currentConnections\n";
continue;
}
// 處理客戶端發送的數據
$response = "服務器收到: {$data}\n";
socket_write($clientSocket, $response, strlen($response));
}
}
usleep(50000); // 減少CPU佔用
}
?>
使用$currentConnections記錄當前活躍連接數。
只在未超出最大連接數時調用socket_accept()接收新連接。
新連接創建後將客戶端socket 保存到$clients數組,並設置為非阻塞模式。
通過輪詢$clients ,讀取客戶端數據,響應後繼續監聽。
如果客戶端斷開或者發送quit指令,關閉socket 並減少連接計數。
使用usleep()減少CPU 過度佔用。
設置超時:檢測客戶端連接空閒時間,超時自動斷開。
限制單IP連接數:防止單一IP製造大量連接。
使用防火牆:在服務器層面限制異常連接。
使用負載均衡:分散請求壓力。
監控日誌:及時發現異常流量。
通過在PHP 的socket 服務器中限制最大連接數,可以有效抵禦一定程度的DoS 攻擊,避免服務器資源被惡意耗盡。結合其他安全措施,能為服務器提供更堅實的防護,保障服務的穩定運行。