PHP: Read from socket or STDIN

安稳与你 提交于 2019-12-12 12:35:37

问题


I am learning socket programming in PHP and so I am trying a simple echo-chat server.

I wrote a server and it works. I can connect two netcats to it and when I write in the one netcat, I recive it at the other. Now, I want to implement what NC does in PHP

I want to use stream_select to see if I have data on STDIN or on the socket to either send the message from STDIN to the server or reading the incoming message from the server. Unfortunately the example at the php manual doesn't give me any clue how to do that. I tried to simply $line = fgets(STDIN) and socket_write($socket, $line) but it doesnt work. So I started to go down and just want stream_select to act up when the user typed the message.

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

while(1){

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

Gives

PHP Warning: stream_select(): No stream arrays were passed in /home/user/client.php on line 18

But when I var_dump($read) it tells me, that it is an array with a stream.

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

How do I get stream_select to work?


PS: In Python I can do something like

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

I need the same in PHP


回答1:


I found a solution. It seems to work, when I use:

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

Instead of just STDIN. Despite php.net says, STDIN is already open and saves using $stdin = fopen('php://stdin', 'r'); It seems not, if you want to pass it into stream_select. Also, the socket to the server should be created with $sock = fsockopen($host); instead of using socket_create on the client side... gotta love this language and it's reasonability and clear manual...

Here a working example of a client that connects to an echo server using 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;
            }
        }
    }
}


来源:https://stackoverflow.com/questions/16042626/php-read-from-socket-or-stdin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!