Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Read from socket or STDIN

Tags:

php

stream

stdin

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

like image 269
fdafgfdgfagfdagfdagfdagfdagfda Avatar asked Jul 05 '26 01:07

fdafgfdgfagfdagfdagfdagfdagfda


1 Answers

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;
            }
        }
    }
}
like image 177
fdafgfdgfagfdagfdagfdagfdagfda Avatar answered Jul 06 '26 15:07

fdafgfdgfagfdagfdagfdagfdagfda



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!