When using PHP for network programming, socket_accept() is the core function that accepts client connections. In the face of DoS (Denial of Service) attacks, attackers usually use a large number of malicious connection requests, exhausting server resources, causing the server to be unable to respond to legitimate user requests normally. This article will explain how to effectively prevent the server from being maliciously dragged down by limiting the maximum number of connections accepted by socket_accept() .
In DoS attacks, an attacker creates a large number of concurrent connections that fill the server's server's concurrent connections, causing the server to be unable to process new normal requests. Limiting the maximum number of connections and ensuring that the server only handles a certain number of client connections within the resource permission range can effectively reduce the impact of this attack.
Use variables to count the number of currently established connections.
When a new connection is received, it is determined whether the current connection number exceeds the limit.
Reject the connection when the limit is exceeded (close the new connection), and socket_accept() will no longer be called to process.
When the connection is closed, reduce the connection count in time.
The following code demonstrates how to implement a maximum connection limit based on socket_accept() in PHP, assuming that the maximum connection is 100:
<?php
set_time_limit(0);
error_reporting(E_ALL);
$address = '0.0.0.0';
$port = 12345;
$maxConnections = 100;
$currentConnections = 0;
// create TCP Socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port) or die('Binding failed');
socket_listen($sock);
echo "Server startup,monitor {$address}:{$port}\n";
$clients = [];
while (true) {
// Determine whether the maximum number of connections is exceeded
if ($currentConnections < $maxConnections) {
// Non-blocking mode accepts new connections
socket_set_nonblock($sock);
$client = @socket_accept($sock);
if ($client !== false) {
// New connection succeeded,Count one
$currentConnections++;
$clients[] = $client;
// Setting up the clientsocketNot blocking
socket_set_nonblock($client);
echo "New client connection,Current connection number: $currentConnections\n";
}
} else {
// Maximum number of connections exceeded,Reject new connection(Optional waiting time)
usleep(100000); // 100ms
}
// Polling to process data from connected clients
foreach ($clients as $key => $clientSocket) {
$data = @socket_read($clientSocket, 2048, PHP_NORMAL_READ);
if ($data === false) {
// Disconnection,Remove client
socket_close($clientSocket);
unset($clients[$key]);
$currentConnections--;
echo "Client disconnected,Current connection number: $currentConnections\n";
continue;
} elseif ($data !== '') {
$data = trim($data);
if ($data === 'quit') {
// The client disconnects actively
socket_close($clientSocket);
unset($clients[$key]);
$currentConnections--;
echo "The client is disconnected actively,Current connection number: $currentConnections\n";
continue;
}
// Process data sent by the client
$response = "Server received: {$data}\n";
socket_write($clientSocket, $response, strlen($response));
}
}
usleep(50000); // reduceCPUOccupancy
}
?>
Use $currentConnections to record the current number of active connections.
Call socket_accept() only to receive new connections when the maximum number of connections is not exceeded.
After the new connection is created, save the client socket to the $clients array and set to non-blocking mode.
By polling $clients , read client data and continue listening after response.
If the client disconnects or sends a quit command, close the socket and reduce the connection count.
Use usleep() to reduce CPU over-occupation.
Set timeout : Detect the client connection idle time, and the timeout will automatically disconnect.
Limit the number of single IP connections : Prevent a single IP from manufacturing a large number of connections.
Using Firewall : Limit exception connections at the server level.
Use load balancing : disperse request pressure.
Monitoring log : Discover abnormal traffic in time.
By limiting the maximum number of connections in PHP socket server, you can effectively resist a certain degree of DoS attacks and avoid malicious depletion of server resources. Combined with other security measures, it can provide more solid protection for the server and ensure the stable operation of services.