PHP socket_select()始终检测可读取的套接字

时间:2015-04-02 22:08:32

标签: php sockets

我一直在寻找解决这个问题的方法。即使没有数据包等待,socket_select()似乎总是会发现可接受的套接字(socket_accept()返回的资源)可供读取。我确定有一些我忘了做的事情,但我无法弄清楚那是什么。

以下是相关代码:

while(TRUE){
    $read_sockets=$this->client_sockets;
    $write_sockets=NULL;
    $except=NULL;

    if(socket_select($read_sockets, $write_sockets, $except, NULL)<1) continue;
    foreach($read_sockets as $pending_socket){
        echo "Read request received...".PHP_EOL;

        if($this->socket==$pending_socket){
            $new_client_socket=socket_accept($this->socket);
            socket_write($new_client_socket,$this->read_data($new_client_socket),2048);
            $this->client_sockets[]=$new_client_socket;
            echo "New client...".PHP_EOL;
        } else {
            $pending_socket_data=$this->read_data($pending_socket);
            if($pending_socket_data===false){
                unset($this->client_sockets[array_search($pending_socket,$this->client_sockets)]);
                continue;
            }
            socket_write($pending_socket,$pending_socket_data,2048);
            echo "Old client...".PHP_EOL;
        }
    }
}

private function read_data(&$socket){
    echo 'Reading data...'.PHP_EOL;
        $client_data='';$tmp='';
    while(socket_recv($socket,$tmp,$this->max_length,0) > 0){
        $client_data .= $tmp;
    }
    return $client_data;
}

我知道我没有捕获一些异常,因为socket_recv === FALSE,但是这段代码只是一个概念证明,我必须在调试主代码时开始使用。

$this->socket是服务器套接字,并且是非阻塞的。

提前感谢!

1 个答案:

答案 0 :(得分:0)

private function read_data(&$socket){
    echo 'Reading data...'.PHP_EOL;
        $client_data='';$tmp='';
    while(socket_recv($socket,$tmp,$this->max_length,0) > 0){
        $client_data .= $tmp;
    }
    return $client_data;
}

方法read_data永远不会返回false,因此下面的代码永远不会运行。

if($pending_socket_data===false){
     unset($this->client_sockets[array_search($pending_socket,$this->client_sockets)]);
     continue;
}

socket_recv返回false时,您应该检查socket_last_error()并决定是否socket_close($pending_socket)unset($this->client_sockets[..])

socket_recv返回0时,可能会关闭套接字,您应该致电unset($this->client_sockets[..])