doushouj966020 2015-04-02 22:08
浏览 461
已采纳

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

I've been searching back and forth looking for a solution to this problem I'm having. It appears that socket_select() will always find accepted sockets (resources returned by socket_accept()) as available to read from, even though there are no packets waiting. I'm sure there's a little something I forgot to do, but I can't figure out what that is.

Here's the relevant code:

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

I know I'm not catching some exceptions, as socket_recv === FALSE, but this code is just a proof of concept, that I had to get down to while debugging the main code.

$this->socket is the server socket, and is non-blocking.

Thank's in advance!

  • 写回答

1条回答 默认 最新

  • douqie1852 2015-04-10 05:28
    关注
    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;
    }
    

    Method read_data never return false, so the codes below will never run.

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

    When socket_recv return false ,you should check socket_last_error() and decide if to socket_close($pending_socket) and unset($this->client_sockets[..]).

    When socket_recv return 0, may be socket closed and you should call unset($this->client_sockets[..]).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog