PHP Socket Server不接受超过255个并发连接

时间:2013-03-29 13:32:35

标签: php windows windows-server-2008 socketserver

我在Windows Server 2008计算机上运行PHP(5.4.12)脚本。 当并发连接总数达到255时,脚本崩溃。

在PHP 5.2.x系统上,SocketServer以错误结束: “尝试对不是插座的东西进行操作。”

PHP 5.4.12,不会崩溃,但不再处理连接。

我正在使用以下代码,取自PHP.net网站: 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);
?>

我通过运行“EchoServerTest.exe”测试了脚本。我创建了许多并发连接。

首先我认为这是WinSock中的一个问题,但我发现在使用WinSock的255个连接上存在限制。

我还更改了注册表设置TcpNumConnections,TcpTimedWaitDelay和MaxUserPort。

我在Ubuntu服务器上使用了相同的代码,因此问题与Windows有很大关系。 我在两台不同的服务器上测试了这一点,包括Windows Server 2008(32位和64位)。 一个在本地,一个在互联网上。所以应该排除防火墙或其他外部问题。

我没有选择。

在你问之前,你真的需要这么多联系吗?是。 有很多'死'连接,所以我改变了代码。现在那些'死'连接现在'超时'。所以我有时间解决这个问题,但最终并发连接数将再次达到255。

关于这个的任何想法?

1 个答案:

答案 0 :(得分:0)

我认为问题出在这一行:

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

您正在手动将排队等待处理的待办事项传入连接数限制为5。在Linux中,它被静默地截断为SOMAXCONN,而不是在Windows上。尝试使用SOMAXCONN代替5。