Forum und email

socket_select

(PHP 4 >= 4.0.7, PHP 5)

socket_select — Executa a chamada de sistema select() nos arrays dados de sockets com um timeout especificado

Descrição

int socket_select ( array $&read , array $&write , array $&except , int $tv_sec [, int $tv_usec ] )
Aviso

Esta função é EXPERIMENTAL. Isso quer dizer que o comportamento desta função e seu nome, incluindo TUDO o que está documentado aqui pode mudar em futuras versões do PHP, SEM QUALQUER NOTIFICAÇÃO. Esteja avisado, e use esta função por sua própria conta e risco.

socket_select() aceita arrays de sockets e aguarda até que seu status seja alterado. Estes vem com "background" de sockets BSD irá reconhecer aquele array de socket resource são de fato a chamada ao arquivo descritor de configuração (fds). Três arrays independentes de socket resources são observados.

A lista de sockets no array read irá ser mostrada para ver se o caractere disponível anterior à leitura (mais precisamente, para ver se a leitura não está obstruída - em particular, um socket resource está também no fim-de-arquivo (EOF) , neste caso o socket_read() irá retornar uma string com comprimento zero.

A lista de sockets no array write irá ser visualizada para mostrar se não é uma escrita não está obstruída.

A lista de sockets no array except irá mostrar caso haja exceções.

Aviso

Na saída, os arrays são modificados para indicar qual socket resource atualmente alterou seu status.

Você não precisa passar cada array para socket_select(). Você pode deixá-los de fora e usar um array vazio ou NULL ao invés disso. Também não se esqueça que esses arrays são passados by reference e irão ser modificados após o retorno de socket_select().

Example#1 Exemplo de socket_select()

<?php
/* Prepare the read array */
$read = array($socket1$socket2);

$num_changed_sockets socket_select($read$write NULL$except NULL0);

if (
$num_changed_sockets === false) {
    
/* Error handling */
} else if ($num_changed_sockets 0) {
    
/* At least at one of the sockets something interesting happened */
}
?>

Nota: Devido a uma limitação no atual Zend Engine não é possível passar um modificador de constante como NULL diretamente como parâmetro para uma função que tem exceção para este parâmetro sendo passado por referência. Ao invés disso use uma variável temporária ou uma expressão com o leftmost member sendo uma variável temporária:

Example#2 Usando NULL com socket_select()

<?php
socket_select
($r$w$e NULL0);
?>

O tv_sec e tv_usec juntos formam o parâmetro timeout. O timeout é o limite máximo da quantidade de tempo passado antes do retorno de socket_select(). tv_sec deve ser zero , causando o retorno imediato de socket_select(). Isso é útil para polling. Se tv_sec é NULL (sem timeout), socket_select() pode bloquear definitivamente.

Em caso de sucesso socket_select() retorna o número de socket resorces contidos nos arrays modificados, que deve ser zero se alguma coisa interessante acontecer antes do timeout expirar. Em caso de erro, FALSE é retornado. O código do erro pode ser retornado com socket_last_error().

Nota: Tenha certeza de usar o operador === quando checar por um erro. Desde de que socket_select() deve retornar 0 a comparação com == deve retornar TRUE:

Example#3 Entendendo resultados de socket_select()

<?php
if (false === socket_select($r$w$e NULL0)) {
    echo 
"socket_select() failed, reason: " .
        
socket_strerror(socket_last_error()) . "\n";
}
?>

Nota: Esteja consciente que algumas implementações de sockets precisam ser manuseadas com muito cuidado. As regras básicas:

  • Você deve sempre tentar usar socket_select() sem timeout. Seu programa não deve fazer nada se não há dados disponíveis. Códigos que dependem de timeouts não são usualmente portáveis e dificultam o debug.
  • No socket resource deve ser adicionado alguma configuração se você não pretende checar o resultado após a chamada de socket_select(), e responder de forma apropriada. Após o retorno de socket_select(), todos os sockets resources em todos os arrays devem ser checados. Algum socket resource que está disponível para escrita deve ser escrito, e algum socket resource disponível para leitura deve ser lido.
  • Se você está lendo/escrevendo um retorno de socket em array esteja consciente que eles não necessariamente estão lendo/escrevendo a quantidade completa de dados que você requisitou. Esteja preparado para somente habilitar para leitura/escrita um único byte.
  • Isso é comum na grande maioria de implementações de socket que pegam exceções através do except array está fora do limite de dados recebidos no socket.

Veja também socket_read(), socket_write(), socket_last_error() e socket_strerror().