PHP:从套接字或标准输入读取

3

我正在学习使用PHP进行套接字编程,因此尝试创建一个简单的回显聊天服务器。

我编写了一个服务器并且它能够正常工作。我可以将两个netcat连接到它上面,当我在其中一个netcat中写入时,另一个会收到它。现在,我想在PHP中实现NC的功能。

我想使用stream_select来查看STDIN或套接字上是否有数据,以便将来自STDIN的消息发送到服务器或读取来自服务器的传入消息。 不幸的是,php手册中的示例没有给我任何提示如何做到这一点。 我尝试了简单地 $line = fgets(STDIN) 和 socket_write($socket, $line),但它不起作用。因此,我开始下降,只希望在用户键入消息时,stream_select能够起作用。

$read = array(STDIN);
$write = NULL;
$exept = NULL;

while(1){

    if(stream_select($read, $write, $exept, 0) > 0)
        echo 'read';
}

提供

PHP警告:stream_select():在/home/user/client.php的第18行未传递流数组

但当我var_dump($read)时,它告诉我它是一个带有流的数组。

array(1) {
  [0]=>
  resource(1) of type (stream)
}

如何让stream_select工作?


附注:在Python中,我可以这样做:

r,w,e = select.select([sys.stdin, sock.fd], [],[])
for input in r:
    if input == sys.stdin:
        #having input on stdin, we can read it now
    if input == sock.fd
        #there is input on socket, lets read it

我需要用PHP实现同样的功能。

当将tv_sec设置为1时,似乎不会显示此警告。 - Bass Jobsen
不行,当我将tv_sec设置为1时,它只会延迟1秒钟的警告... - fdafgfdgfagfdagfdagfdagfdagfda
1个回答

5

我找到了一个解决方案。当我使用以下代码时,它似乎有效:

$stdin = fopen('php://stdin', 'r');
$read = array($sock, $stdin);
$write = NULL;
$exept = NULL;

不要只使用STDIN。尽管php.net说,STDIN已经打开并且可以使用$stdin = fopen('php://stdin', 'r')来保存它,但是如果您想将其传递到stream_select,则似乎不行。此外,应该使用$sock = fsockopen($host);在客户端上创建与服务器的套接字,而不是使用socket_create...这种语言及其合理和清晰的手册真是太棒了...

这里有一个连接到回显服务器并使用select的客户端的工作示例。

<?php
$ip     = '127.0.0.1';
$port   = 1234;

$sock = fsockopen($ip, $port, $errno) or die(
    "(EE) Couldn't connect to $ip:$port ".socket_strerror($errno)."\n");

if($sock)
    $connected = TRUE;

$stdin = fopen('php://stdin', 'r'); //open STDIN for reading

while($connected){ //continuous loop monitoring the input streams
    $read = array($sock, $stdin);
    $write = NULL;
    $exept = NULL;

    if (stream_select($read, $write, $exept, 0) > 0){
    //something happened on our monitors. let's see what it is
        foreach ($read as $input => $fd){
            if ($fd == $stdin){ //was it on STDIN?
                $line = fgets($stdin); //then read the line and send it to socket
                fwrite($sock, $line);
            } else { //else was the socket itself, we got something from server
                $line = fgets($sock); //lets read it
                echo $line;
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接