PHP: Чтение из сокета или стандартного ввода-вывода


Я изучаю программирование сокетов на PHP и поэтому пробую простой сервер эхо-чата.

Я написал сервер, и он работает. Я могу подключить к нему два netcat, и когда я пишу в одном netcat, я получаю его в другом. Теперь я хочу реализовать то, что NC делает в PHP

Я хочу использовать stream_select, чтобы узнать, есть ли у меня данные на STDIN или в сокете, чтобы либо отправить сообщение с STDIN на сервер, либо прочитать входящее сообщение с сервера. К сожалению, пример в руководство по php не дает мне ни малейшего представления о том, как это сделать. Я пытался просто $line = fgets(STDIN) и socket_write ($сокет, $строка), но это не работает. Поэтому я начал спускаться и просто хочу, чтобы 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

1 answers

Я нашел решение. Кажется, это работает, когда я использую:

$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;
            }
        }
    }
}
 2
Author: fdafgfdgfagfdagfdagfdagfdagfda, 2013-04-17 08:36:18