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

标签 php sockets

我想要实现的是一个套接字服务器,该服务器将一些数据广播到所有连接的对等方。这是服务器循环的代码:

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)。但是,在客户端,应将参数设置为NULL(而不是 0!),因此脚本在等待服务器广播消息时保持空闲状态。

我还发现,这种阻塞行为类似于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微秒是我所能得到的。

实际上,我已经为投票的人更新了答案。但我希望该解决方案仍然有用。

关于php - PHP多连接套接字(广播问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20521863/

相关文章:

php - 如何通过mysql获取表中最流行的词?

php - 如何从多个表中获取结果

php - 如何预选多项选择的选项? (html + php)

linux - 我怎样才能避免僵尸进程

php - 如何通过 WebDAV 部署 git 版本的 Web 应用程序?

php - 查询不适用于 LIKE

java - 从 InputStream 读取数据包 - 正确的设计

python - 如何处理可变长度消息并自动关闭套接字?

java - 如何将 Java 类转换为其子类之一(SocketAddress 和 InetSocketAddress)

Java:如何从 InetAddress 获取连接的端口?