PHP多连接套接字(广播问题)


PHP multiple-connection socket (broadcasting issue)

我试图实现的是一个套接字服务器,它向所有连接的对等端广播一些数据。这是服务器循环的代码:

while(TRUE) {
    $read = array();
    $read[] = $socket;
    for($i = 0; $i < $max_clients; $i++) {
        if($client_sockets[$i] != NULL) {
            $read[$i+1] = $client_sockets[$i];
        }
    }
    #This is broadcasting loop
    foreach($client_sockets as $send_sock)
    {
        socket_write($send_sock, "broadcasting".PHP_EOL);
    }
    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( in_array($socket, $read) ) {
        for($i = 0; $i < $max_clients; $i++) {
            if($client_sockets[$i] == NULL) {
                $client_sockets[$i] = socket_accept($socket);
                if( socket_getpeername($client_sockets[$i], $client_address, $client_port) ) {
                    echo "Client $client_address : $client_port is now connected to us. 'n";
                }
                $message = "Connected to php socket server".PHP_EOL;
                socket_write($client_sockets[$i], $message);
                break;
            }
        }
    }
}

这段代码运行良好,接受多个连接并广播数据,除了一个时刻:只有在我通过telnet从任何连接的客户端键入任何输入后,循环才会开始。我知道这是因为socket_select等待这个输入,但我不知道如何在客户端连接后立即开始广播。

感谢在这方面的任何帮助,因为我觉得我在某个地方大错特错了。

自身回答

socket_select($read, $write, $except, NULL)确实存在问题;实际上并不是一个问题。最后一个NULL参数开始无限阻塞,等待客户端响应;为了使脚本正常工作,我更改了这个超时,所以它看起来是这样的:socket_select($read, $write, $except, 0, 500000)。然而,在客户端,参数应设置为NULLNOT0!),因此脚本在等待服务器广播消息时保持空闲。

我还发现,这种阻塞行为类似于socket_read()socket_write()函数,默认情况下它们是无限的;要更改它,请使用socket_set_option:

socket_set_option($master_socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 1000));
socket_set_option($master_socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 0, "usec" => 1000));

1000微秒是我所能得到的最低值。

事实上,我已经更新了投票人的答案;但我希望这个解决方案无论如何都是有用的。