0

I'm running a PHP (5.4.12) script on a Windows Server 2008 machine. When the total concurrent connections hit 255, the script crashes.

On a PHP 5.2.x system the SocketServer end with an error: "An operation was attempted on something that is not a socket."

PHP 5.4.12, does not crash but does not handle the connections anymore.

I'm using the following code, taken from the PHP.net website: http://php.net/manual/en/sockets.examples.php

    <?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();

$address = '192.168.1.7';
$port = 8676;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() last error " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() last error " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (socket_listen($sock, 5) === false) {
    echo "socket_listen() last error " . socket_strerror(socket_last_error($sock)) . "\n";
}

$clients = array();

do {
    $read = array();
    $read[] = $sock;

    $read = array_merge($read,$clients);

    $write = NULL;
    $except = NULL;
    if(socket_select($read,$write , $except , $tv_sec = 5)===false)
    {
        echo(PHP_EOL.'\n\ncrash\n\n'.PHP_EOL);
        exit();
    }

    if (in_array($sock, $read)) {        

        if (($msgsock = socket_accept($sock)) === false) {
            echo "socket_accept() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
//            break;
        }
        $clients[] = $msgsock;
        $key = array_keys($clients, $msgsock);
        $msg = "{$key[0]} welcome msg\n".PHP_EOL;
        socket_write($msgsock, $msg, strlen($msg));

    }

    // Handle Input
    foreach ($clients as $key => $client) { // for each client        
        if (in_array($client, $read)) {
            if (false === ($buf = socket_read($client, 2048))) {
                echo "socket_read() last error: " . socket_strerror(socket_last_error($client)) . "\n";
//                break 2;
            }
            if (!$buf = trim($buf)) {
                continue;
            }
            if ($buf == 'quit') {
                $talkback = print_r($clients);
                socket_write($client, $talkback, strlen($talkback));
                unset($clients[$key]);
                socket_close($client);
                break;
            }
            if ($buf == 'shutdown') {
                socket_close($client);
                break 2;
            }
            $talkback = "Client {$key}: Echo: '$buf'.\n";
            socket_write($client, $talkback, strlen($talkback));
            echo "$buf\n";
        }

    }        
} while (true);

socket_close($sock);
?>

I've tested the script by running "EchoServerTest.exe". I creates a number of concurrent connections.

First I thought it was a problem in WinSock, but I can't find that there is a limitation on 255 connections with WinSock.

I also changed the registry settings TcpNumConnections, TcpTimedWaitDelay and MaxUserPort.

I used the same code on a Ubuntu server, so the problem much be related to Windows. I tested this on two different servers, both Windows Server 2008 (32bit and 64bit). One locally and one on the internet. So firewall or other external problems should be ruled out.

I'm out of options.

Before you ask, do you really need so many connections? Yes. There are many 'dead' connections, so I've altered the code. Now those 'dead' connection are now 'Timed-out'. So I have some time to solve this, but eventually the number of concurrent connections will reach 255 again.

Any ideas on this one?

1 Answers1

0

I think the problem is in this line:

if (socket_listen($sock, 5) === false) {

You are manually restricting to 5 the number of backlog incoming connections queued for processing. In Linux this is silently truncated to SOMAXCONN, not that way on Windows. Try using SOMAXCONN instead of 5.

juco
  • 6,331
  • 3
  • 25
  • 42
albert
  • 1