【问题标题】:PHP: Read from socket or STDINPHP:从套接字或 STDIN 读取
【发布时间】:2013-04-16 16:48:25
【问题描述】:

我正在学习 PHP 中的套接字编程,所以我正在尝试一个简单的 echo-chat 服务器。

我写了一个服务器,它可以工作。我可以将两个 netcat 连接到它,当我在一个 netcat 中写入时,我会在另一个 netcat 中接收它。现在,我想实现 NC 在 PHP 中所做的事情

我想使用 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 工作?


PS:在 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 时,似乎没有显示此警告
  • 不,当我将 tv_sec 设置为 1 时,它只会将警告延迟 1 秒...

标签: php stream stdin


【解决方案1】:

我找到了解决方案。当我使用时,它似乎有效:

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

而不仅仅是标准输入。尽管 php.net 说,STDIN 已经打开并保存使用 $stdin = fopen('php://stdin', 'r'); 如果你想将它传递给stream_select,它似乎不是。 此外,应该使用 $sock = fsockopen($host); 创建到服务器的套接字。而不是在客户端使用socket_create...一定要喜欢这种语言,它的合理性和清晰的手册...

这是一个使用 select 连接到 echo 服务器的客户端的工作示例。

<?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;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2010-12-17
    • 1970-01-01
    • 2016-08-10
    • 2011-10-29
    • 2015-09-01
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多