International PHP Conference 2015

socket_select

(PHP 4 >= 4.1.0, PHP 5)

socket_select Esegue la system call select() su un set di socket con un dato timeout

Descrizione

int socket_select ( array $lettura , array $scrittura , array $except , int $tv_sec [, int $tv_usec ] )
Avviso

Questa funzione è SPERIMENTALE. Ovvero, il comportamento di questa funzione, il nome di questa funzione, in definitiva tutto ciò che è documentato qui può cambiare nei futuri rilasci del PHP senza preavviso. Siete avvisati, l'uso di questa funzione è a vostro rischio.

La funzione socket_select() accetta un array di socket e si mette in attesa di una variazione di stato su questi. Questa, derivando come background dai socket BSD, riconoscerà che questi array di risorse socket sono in realtà dei set di descrittori di file. Saranno monitorati 3 set di socket.

I socket indicati nell'array lettura, saranno monitorati in attesa dell'arrivo di caratteri disponibili per la lettura (più precisamente, per verificare che una lettura non sia bloccata, una risorsa socket viene definita pronta anche su fine file, in questo caso la funzione socket_read() restituirà una stringa di lunghezza zero).

I socket indicati nell'array di scrittura, sarranno monitorati per verificare che una scrittura non si blocchi.

I socket indicati nell'array except saranno monitorati per rilevare delle eccezioni.

Avviso

In uscita, gli array sarrano modificati in modo da indicare quale risorsa di tipo socket ha variato il proprio stato.

Non si è obbligati a passare tutti gli array a socket_select(). Se ne possono tralasciare, al loro posto utilizzare un array vuoto oppure NULL. Inoltre non si dimentichi che gli array sono passati per riferimento e che saranno modificati all'uscita dalla funzione socket_select().

Example #1 Esempio di socket_select()

<?php
/* Preparo l'array di lettura */  
$read = array($socket1$socket2);  
  
$num_changed_sockets socket_select($read$write NULL$except NULL0);


if (
$num_changed_sockets === false) {
    
/* Gestione dell'errore */  
} else if ($num_changed_sockets 0) {
    
/* Su almeno un socket è accaduto qualcosa di interessante */  
}  
?>

Nota:

A causa delle limitazioni della versione attuale del Zend Engine, non è possibile passare direttamente una costante, ad esempio NULL, come parametro ad una funzione che si aspetti questo passato per riferimento. Si utilizzi, invece, una variabile temporanea oppura una espressione il cui membro di sinistra sia una variabile temporanea:

Example #2 Uso di NULL con socket_select()

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

I parametri tv_sec ed tv_usec insieme indicano il timeout. Il timeout indica il limite superiore di tempo che deve trascorrere prima che la funzione socket_select() esca. tv_sec può essere a zero, ciò causa una uscita immediata di socket_select(). Ciò risulta utile nei casi di polling. Se tv_sec viene impostato a NULL (nessun timeout), la funzione resta in attesa per un tempo indefinito.

Se ha successo socket_select() restituisce il numero di risorse socket contenute nell'array modificato, tale valore può essere zero se scade il timeout prima che sia accaduto qualcosa. La funzione restituisce FALSE se si verifica un errore. Il codice di errore può essere recuperato tramite la funzione socket_last_error().

Nota:

Si utilizzi l'operatore === quanto si eseguono dei test per rilevare un errore. Poiché la funzione socket_select() può restituire 0 il confronto eseguito con == sarebbe valutato come TRUE:

Example #3 Comprensione dei risultati di socket_select()

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

Nota:

Si presti attenzione alle implementazioni di certi socket che richiedono di essere gestiti molto attentamente. Alcune regole di base:

  • Si cerchi di utilizzare sempre socket_select() senza il timeout. Il programma non dovrebbe avere nulla da fare se non ci sono dati disponibili. Il codice basato sui timeout solitamente non è migrabile ed è difficile da testare.
  • Nei tre set, non inserire una risorsa socket di cui non si intende controllarne il risultato dopo la chiamata a socket_select(), e ne si intende rispondere in modo appropriato. Dopo la chiamata a socket_select(), occorre verificare tutti i socket in tutti gli array. Si deve scrivere su qualsiasi socket disponibile per la scrittura, e deve essere letto qualsiasi socket diponibile per la lettura.
  • Se si ha il ritorno della disponibilità di un socket, sia in lettura che in scrittura, non è detto che sia disponile per l'intero ammontare dei dati da scrivere/leggere. Occorre essere preparati a gestire il caso in cui la disponibilità sia limitata anche ad un solo byte.
  • Nella maggior parte delle implementazioni dei socket, l'unica eccezione catturata con il parametro except è l'arrivo di dati fuori banda.

Vedere anche socket_read(), socket_write(), socket_last_error() e socket_strerror().

add a note add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top