PHP:从套接字或标准输入读取 [英] PHP: Read from socket or STDIN

查看:30
本文介绍了PHP:从套接字或标准输入读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我想使用 stream_select 来查看我是否在 STDIN 或套接字上有数据,以便将消息从 STDIN 发送到服务器或从服务器读取传入消息.不幸的是,php 手册中的例子没有给我任何线索如何做到这一点.我试图简单地 $line = fgets(STDIN) 和 socket_write($socket, $line) 但它不起作用.所以我开始往下走,只希望 stream_select 在用户输入消息时起作用.

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

给予

PHP 警告:stream_select():没有传入流数组/home/user/client.php 第 18 行

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

但是当我 var_dump($read) 它告诉我,它是一个带有流的数组.

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

如何让 stream_select 工作?

How do I get stream_select to work?

PS:在 Python 中我可以做类似的事情

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

我在 PHP 中需要相同的

I need the same in PHP

推荐答案

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

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

$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 ......必须喜欢这种语言,它的合理性和清晰的手册......

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...

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

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

这篇关于PHP:从套接字或标准输入读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆