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