Gestione di socket
Da Hacknowledge.
La gestione di socket in Perl è estremamente semplice e immediata rispetto a quella di molti altri linguaggi di programmazione, caratteristica che lo ha reso un linguaggio estremamente usato per la creazione di script per la comunicazione client/server. In Perl basta infatti usare il modulo IO::Socket e inizializzare un oggetto di questo tipo. In molti casi basta specificare l'host a cui ci si vuole connettere, la porta e il protocollo di trasporto per poter usare un socket bidirezionale perfettamente funzionante con l'host in questione. Creato il socket, per leggervi e scriverci su basta usare i normali metodi usati per la lettura e la scrittura su file (print per la scrittura, <SOCK_NAME> per la lettura). Ecco un esempio pratico di script in Perl che richiede l'home page ad un web server inviando una richiesta HTTP e stampa il risultato su stdout:
#!/usr/bin/perl use IO::Socket; $srv=shift or die "Usage: perl script.pl <web_server>\n"; # Inizializzo il mio oggetto -> host, porta e protocollo di trasporto my $sock = new IO::Socket::INET( PeerHost => $srv, PeerPort => '80', Proto => 'tcp', ); # Controllo eventuali errori nella creazione die "Socket not created: $!\n" unless $sock; # Scrivo la richiesta HTTP su socket print $sock "GET /\n\n"; # Finché il server ha da inviarmi qualcosa, lo scrivo su stdout while (<$sock>) { print $_; } # Chiudo il socket close($sock);
Semplice e indolore. Ecco invece come implementare un potenziale server in ascolto su una porta arbitraria, che legge una riga inviata dal client e la stampa su stdout:
#!/usr/bin/perl use IO::Socket; # Inizializzo indirizzo locale, porta su cui stare in ascolto, protocollo di trasporto e # proprietà del socket (listen=max un client per volta, ri-uso del socket==true) my $sock = new IO::Socket::INET( LocalHost => '127.0.0.1', LocalPort => '4444', Proto => 'tcp', Listen => 1, Reuse => 1, ); # Controllo eventuali errori die "Impossibile creare il socket: $!\n" unless $sock; # Creo un nuovo socket per accettare le connessioni dal client my $new_sd=$sock->accept(); # Finché il client ha righe da inviare, le scrivo su stdout while (<$new_sd>) { print "Il client ha inviato $_\n"; } # Chiudo il socket close ($sock);
Ed ecco un semplice client che sfrutta questo server:
#!/usr/bin/perl use IO::Socket; $host=shift or die "Usage: perl client.pl <host> <stringa>"; $buff=shift or die "Usage: perl client.pl <host> <stringa>"; my $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => '4444', Proto => 'tcp', ); die "Impossibile creare il socket: $!\n" unless $sock; print $sock $buff; close($sock);
Per completezza, riporto tutti i possibili parametri settabili all'interno di un oggetto di tipo IO::Socket::INET (fonte: documentazione Perl):
PeerAddr Remote host address <hostname>[:<port>] PeerHost Synonym for PeerAddr PeerPort Remote port or service <service>[(<no>)] | <no> LocalAddr Local host bind address hostname[:port] LocalHost Synonym for LocalAddr LocalPort Local host bind port <service>[(<no>)] | <no> Proto Protocol name (or number) "tcp" | "udp" | ... Type Socket type SOCK_STREAM | SOCK_DGRAM | ... Listen Queue size for listen ReuseAddr Set SO_REUSEADDR before binding Reuse Set SO_REUSEADDR before binding (deprecated, prefer ReuseAddr) ReusePort Set SO_REUSEPORT before binding Broadcast Set SO_BROADCAST before binding Timeout Timeout value for various operations MultiHomed Try all addresses for multi-homed hosts Blocking Determine if connection will be blocking mode

