PHP Socket Programming. Need to support 300 multiple connection at same instance

602 views Asked by At

I have created a PHP socket on my server on port "11011". Which is working properly for multiple connections. But it only supports around 20-60 parallel connection. That is also not constant. I I want my server to at least support 300 parallel connection. Please Help.

Here is my code at server side :

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
set_time_limit (0);
date_default_timezone_set('UTC');

$address = "0.0.0.0";
$port = 11011;
$max_clients = 1024;


if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
//  echo "Couldn't create socket: [$errorcode] $errormsg \n";
    die("Couldn't create socket: [$errorcode] $errormsg \n");
}
echo "\n\n".date('Y-m-d H:i:s')." Socket created\n";

if( !socket_bind($sock, $address , $port) ){
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    die("Could not bind socket : [$errorcode] $errormsg \n");
}
echo "\n\n".date('Y-m-d H:i:s')." Socket bind OK\n";

if(!socket_listen ($sock , 10))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    
    die("Could not listen on socket : [$errorcode] $errormsg \n");
}
echo "\n\n".date('Y-m-d H:i:s')." Socket listen OK \n";

echo "\n\n".date('Y-m-d H:i:s')." Waiting for incoming connections... \n";

//array of client sockets
$client_socks = array();

//array of sockets to read
$read = array();

while (true) 
{
    $read = array();
    //first socket is the master socket
    $read[0] = $sock;
    //now add the existing client sockets
    for ($i = 0; $i < $max_clients; $i++)
    {
        if(!empty($client_socks[$i]))
        {
            $read[$i+1] = $client_socks[$i];
        }
    }
    //now call select - blocking call
    if(socket_select($read , $write , $except , null) === false)
    {
        $errorcode = socket_last_error();
        $errormsg = socket_strerror($errorcode);
        die("Could not listen on socket : [$errorcode] $errormsg \n");
    }
    //if ready contains the master socket, then a new connection has come in
    if (in_array($sock, $read)) 
    {
        for ($i = 0; $i < $max_clients; $i++){
            if (empty($client_socks[$i])) {
                $client_socks[$i] = socket_accept($sock);
                if(socket_getpeername($client_socks[$i], $address, $port))
                {
                    echo "\n".date('Y-m-d H:i:s')." Client $address : $port is now connected to us. \n";
//                  echo date('Y-m-d H:i:s')." Client $address : $port is now connected to us. \n";
//                  $clientTimestamp[$i] = time();
                }
                break;
            }
        }
    }
    
    //check each client if they send any data
    for ($i = 0; $i < $max_clients; $i++)
    {
        if (!empty($client_socks[$i]) && in_array($client_socks[$i] , $read))
        {
            $input = socket_read($client_socks[$i], 2048);
            echo "\n\n".date('Y-m-d H:i:s')." INPUT :  $input\n";
            
            if($input != null){
                $output = "\x06";
                socket_write($client_socks[$i] , $output);
            }else{
                socket_close($client_socks[$i]);
                unset($client_socks[$i]);
            }
        }
        
    }
}
?>

Here is my code at client side, which I hit for multiple times at same time to connect with server and check the load. However, it only opens random 60-70 connections when I run 100 such scripts. If I run 50 such scripts, it works taking all 50 connections. But sometimes only take 25-30 connections.

Code at client side.

<?php
$host    = SERVER_IP;
$port    = 11011;
callSocket("\x05",true,false);//ENQ
$message = "\x02 Hello How are you\x03";
callSocket($message,false,false);
callSocket("\x04",false,true);//EOT

function callSocket($message,$connect,$disconnect){
    global $host,$port,$socket;
    // create socket
    if($connect){
        $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
            
        // connect to server
        $result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");  
    }
    // send string to server
    socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
    // get server response
    $result = socket_read ($socket, 1024) or die("Could not read server response\n");
    echo "Reply From Server  :".$result;
    // close socket
    if(empty($result) || $disconnect){
        echo "\n--Close ASTM connection--\n";
        socket_close($socket);
    }
}

?>

Here are the server setting:

Red Hat Enterprise Linux Server release 6.8 (Santiago)
PHP version 5.6

soft nofile 300000
hard nofile 300000
sysctl net.core.somaxconn=1024
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
ifconfig eth0 txqueuelen 5000

echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local

Here are the server setting on client side:

sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
0

There are 0 answers