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[..]).

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

报告相同问题?

悬赏问题

  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面