2013-04-16 110 views
3

我正在学习PHP中的套接字编程,所以我正在尝试一个简单的echo-chat服务器。

我写了一个服务器,它的工作原理。我可以将两个netcats连接到它,当我在一个netcat中写入时,我会在另一个netcat上进行重新配置。现在,我想实现NC在PHP中所做的工作PHP:从套接字或STDIN中读取

我想使用stream_select来查看我是否在STDIN上或套接字上有数据,以便将STDIN中的消息发送到服务器或从服务器读取传入消息。 不幸的是,在php手册中的例子并没有给我任何线索如何做到这一点。我尝试了$ line = fgets(STDIN)和socket_write($ socket,$ line),但它不起作用。所以我开始走下坡路,只是想让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

+0

看来这个警告,当你设置tv_sec 1 –

+0

不,当我设置tv_sec为1,它只是延缓了警告1秒不显示... – fdafgfdgfagfdagfdagfdagfdagfda

回答

2

同我找到了解决办法。它似乎工作,当我使用:

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

这里的一个客户端的工作示例,连接到回声服务器使用选择。

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