Newsgroup: it.comp.lang.perl
Titolo: IO::Select

Ho letto che con IO::Select potevo riuscire a gestire più connessioni 
simultaneamente e ho trovato questi due esempi in rete:
1)
[code]
use IO::Select;
 $read_set = new IO::Select(); # create handle set for reading
 $read_set->add($s);           # add the main socket to the set
 
 while (1) { # forever
   # get a set of readable handles (blocks until at least one handle is 
ready)
   my $rh_set = IO::Select->select($read_set, undef, undef, 0);
   # take all readable handles in turn
   foreach $rh (@$rh_set) {
      # if it is the main socket then we have an incoming connection and
      # we should accept() it and then add the new socket to the 
$read_set
      if ($rh == $s) {
         $ns = $rh->accept();
         $read_set->add($ns);
      }
      # otherwise it is an ordinary socket and we should read and 
process the request
      else {
         $buf = <$rh>;
         if($buf) { # we get normal input
             # ... process $buf ...
         }
         else { # the client has closed the socket
             # remove the socket from the $read_set and close it
             $read_set->remove($rh);
             close($rh);
         }
      }
   }
 }
[/code]
2)
[code]
 use IO::Select;
 use IO::Socket;
    $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
    $sel = new IO::Select( $lsn );
    while(@ready = $sel->can_read) {
        foreach $fh (@ready) {
            if($fh == $lsn) {
                # Create a new socket
                $new = $lsn->accept;
                $sel->add($new);
            }
            else {
                # Process socket
                # Maybe we have finished with the socket
                $sel->remove($fh);
                $fh->close;
            }
        }
    }
[/code]
a intuito provo a fare il mio codice per gestire connessione multiple 
con IO::Select
[code]
use IO::Select;
use IO::Socket;
$socket = IO::Socket::INET;
$sel = new IO::Select( $socket );
while (1)
{
   @ready = $sel->can_read;
   foreach $fh (@ready) {
      if ($fh == $socket)
      {
         $client = $socket->accept;
         $sel->add($client);
      } else {
         # Process socket
         recv($client,$content,40000,0);
         #
         $sel->remove($fh);
         $fh->close;
      }
   }
}
[/code]
o forse e meglio cosi'?
[code]
use IO::Select;
use IO::Socket;
$socket = IO::Socket::INET;
$sel = new IO::Select();
$sel->add($socket);
while (1)
{
   $rh_set = IO::Select->select($sel, undef, undef, 0);
   foreach $fh (@$rh_set) {
      if ($fh == $socket)
      {
         $client = $socket->accept;
         $sel->add($client);
      } else {
         # Process socket
         recv($client,$content,40000,0);
         #
         $sel->remove($fh);
         $fh->close;
      }
   }
}
[/code]
il fatto è che non so da dove leggere la richiesta con "recv" 
se da $client o se da $fh
chiedo aiuto ai più esperti
Grazie

 Grazie
while (1)
{
   @ready = $sel->can_read;
 
   foreach $fh ( @ready ) {
 
      if ($fh == $socket)
      {
 
         $ns = $socket->accept;
         $sel->add($ns);
 
      } else {
 
         recv($fh,$content,10000,0);
         print $content;
 
         syswrite $fh, "HTTP/1.1 200 OK\n";
 
         $sel->remove($fh);
         $fh->close;
      }
 
   }
 
}
io avevo optato per questa scelta...soltanto che non so se magari c'è un 
modo per scriverlo ancora più pulito.
ad esempio mettendo...
while (1)
{
      while(@ready = $sel->can_read) {
...
oppure mettendo direttamente:
while(@ready = $sel->can_read) {
e levando del tutto il while (1)
chiedo un aiuto a voi...

 
oppure pensate che dovrei aggiungere:
$ns = $socket->accept;
if ($ns) { $sel->add($ns) };
non ci capisco piů niente...
cmq mi pare di aver capito che anche se uso IO::SELECT non posso avere 
accessi contemporanei...se un client sta scaricando una file da 1Gb gli 
altri dovranno per forza aspettare.
o no?

 altri dovranno per forza aspettare.
E' possibile, invece, gestire più connessioni contemporaneamente, a
condizione che ognuna non richieda elaborazioni troppo lunghe. L'ho già
scritto in un messaggio, se ricordi. Il problema, con IO::Select, è che è
difficile mettere in piedi un meccanismo di demultiplexing
straordinariamente efficiente. 
Pensa dapprima a come gestire una singola connessione in modo che
l'esecuzione non rimanga bloccata né nella parte che legge i dati né in
quella che li invia al client.
Non dovrai usare 'can_read', ma il metodo 'select', che permette di
specificare sia gli handler da cui vuoi leggere sia quelli su cui vuoi
scrivere. Quando arriva la nuova connessione inserirai l'handler nella
lista di di quelli da cui vuoi leggere. Continuerai a leggere i dati man
mano disponibili finché non ne avrai a sufficienza. (Questo dipende dal
protocollo che vuoi implementare, ovviamente.) Quando decidi di rispondere
al client, togli l'handler dalla suddetta lista e lo metti in quella degli
handler su cui vuoi scrivere. Ogni volta che 'select' comunica che
l'handler è scrivibile, esegui una scrittura e tieni traccia di quanto sei
riuscito a scrivere, che poi è il valore restituito da syswrite. Prosegui
così, finché non hai esaurito i dati.
Ora, se vuoi estendere questo sistema a più sessioni, dovrai adoperare
handler e strutture di dati distinti per ogni connessione e implementare un
meccanismo che all'uscita della 'select' riconosca quali connessioni
richiedano un qualche tipo di operazione, che in sostanza vuoi dire
risalire partendo da un handler alla struttra di dati che mantiene le
informazioni necessarie per proseguire (se devo leggere, se devo scrivere
quanto ho letto, quanto ho scritto, etc...).
Max


Per questo ho deciso di creare una libreria bastata su IO::Select che facili
di gran lunga l'uso degli socket multipli.
Non posso metterla ne su FTP ne su HTTP.
L'ho messa ora su 
html.it
 :
http://forum.html.it/forum/showthread.php?s=&postid=7152069

 Non posso metterla ne su FTP ne su HTTP.
Perché non la metti su CPAN? E' fatto apposta.
Max

 ha scritto nel messaggio
news:cs6hfv$vse$1...@newsreader.mailgate.org...

Ci vorebbe una dozumentazione in inglese e li cado molto in basso. :(
CMQ, grazie, prenderò la proposta e vedrò cosa fare ^^.
ciao