PDA

Visualizza la versione completa : Perl & networking


maiosyet_2
17-01-2005, 13:12
Al di là del chiaro utilizzo di Perl suggerito dal nome, cioè quello di manipolare stringhe di testo, è sensato apprendere Perl per occuparsi di networking, da semplici applicazioni client-server fino al networking di basso livello?

Vorrei utilizzare le potenzialità di cui dispone il C in questo campo, ma sfruttando le caratteristiche di Perl... possibile, o devo rassegnarmi a usare programmazione di basso livello? :fagiano:

Grazie :)

Edit: il tutto in ambiene Linux :madai!?:

LordSaga640
17-01-2005, 14:13
Le ultimi applicazione che ho sviluppato si basano esclusivamenti su socket e connessioni.

Mi trovo benissimo ed è facile realizzare in perl ciò che in altri linguaggi è complesso.

L'unico problema che ti puoi ritrovare ad affrontare è non c'è molta documentazione. Ci ho mosso molto a capire cosa fossero gli oggetti socket.

Ho messo qualche giorno fa una libreria per ua gestione particolare degli socket:
http://forum.html.it/forum/showthread.php?s=&threadid=772224
Però server più che altro per applicazioni che gestiscono decine di connessioni alla volta con necessità particolari.

Cmq tornando a bomba se vuoi iniziare a programmare il networking il perl lo trovo un ottimo punto di partenza anche se in futuro ti conviene migrare ad altri linguaggi.
Usa questo forum se ti serve qualcosa!

Ciao

maiosyet_2
17-01-2005, 14:50
Mi permetto di porti qualche ulteriore domanda :)


Originariamente inviato da LordSaga640
Mi trovo benissimo ed è facile realizzare in perl ciò che in altri linguaggi è complesso.

Proprio quello che intendevo io :D
Spesso mi capita di sentir dire che con Perl puoi sviluppare rapidamente e facilmente, mentre fare networking con C dev'essere veramente faticoso :fagiano:

Quello che mi preoccupa è...questa "facilità" di Perl non ne compromette i risultati? Quali sono i limiti di Perl in questo ambito?



L'unico problema che ti puoi ritrovare ad affrontare è non c'è molta documentazione. Ci ho mosso molto a capire cosa fossero gli oggetti socket.


Di questo me ne sono reso conto subito...per quanto abbia trovato parecchia documentazioni relativa a Perl in generale, online non trovo nulla per il networking :fagiano:



Cmq tornando a bomba se vuoi iniziare a programmare il networking il perl lo trovo un ottimo punto di partenza anche se in futuro ti conviene migrare ad altri linguaggi.


Why?

LordSaga640
17-01-2005, 18:00
Originariamente inviato da maiosyet_2
Mi permetto di porti qualche ulteriore domanda :)



Proprio quello che intendevo io :D
Spesso mi capita di sentir dire che con Perl puoi sviluppare rapidamente e facilmente, mentre fare networking con C dev'essere veramente faticoso :fagiano:

Quello che mi preoccupa è...questa "facilità" di Perl non ne compromette i risultati? Quali sono i limiti di Perl in questo ambito?



Di questo me ne sono reso conto subito...per quanto abbia trovato parecchia documentazioni relativa a Perl in generale, online non trovo nulla per il networking :fagiano:



Why?
Perchè il perl non è molto trasportabile. I programmi sono più lenti (anche se quando si parla di socket la velocità di elaborare i dati è insignificante) occupano più RAM.
Cioè, non puoi farci certo programmi commerciali.
CMq resta sempre un validissimo punto per partire.

Parli di limiti?
Uhm...un limite può essere il fatto che l'interfaccia non è molto userfriendly (o come si dice).

Un po' di tempo fa ho scritto un breve articolo che mi sono tenuto nel computer. Non avevo più voglia di continuarlo @_@



[PILLOLA] Comunicazione tramite rete (introduzione allo socket)

In questa prima parte introdurremo gli socket bloccanti, come si creano, si usano e come si distruggono.
Le comunicazioni tra due processi possono essere con connessione o senza connessione.

L'UDP:
Un protocollo senza connessione è l'UDP che non garantisce che il pacchetto sia giunto a destinazione. Possiamo paragonare questo protocollo ad una lettere inviata ad un amico della quale non sappiamo se è arrivata a destinazione.

Il TCP:
Il TCP è un protocollo bidirezionale garantito. Viene effettuata una connessione con un altro processo e se qualcosa va storto il protocollo ci avverte del problema. Possiamo immaginarlo come una telefonata e mentre parliamo il nostro interlocutore fa ogni tanto segno di essere ancora presente.

Ho accennato che parleremo di Socket "BLOCCANTI" che è una particolarità dei protocolli con connessione. Per ritornare all'esempio della telefonata bisogna immaginare che il nostro amico ci abbia chiesto di dettargli un esercizio di matematica perchè lui non lo ha. Noi iniziamo a dettare il testo. Non possiamo andare alla velocità che vogliamo ma bisogna aspettare che lui abbia finito di riscrivere quella parte per continuare. Il nostro amico non potrà mai memoriazzare un lungo esercizio a memoria e riscriverlo a fine conversazione.
Allo stesso modo il nostro amico non potrà scrivere prima che noi non abbiamo dettato la parte seguente dell'esercizio, quindi resterà in attessa.
Gli socket bloccanti funzionano alla stessa maniera. Restano in ascolto su uno socket fino a quando non si riceve qualcosa. Vedremo in seguito gli socket NON bloccanti, anche se servono in casi particolare come port scanner o creare dei P2p @_@

Una buona documentazione la trovate sulla guida ufficiale di perldoc su IO::Socket::INET

Server e Client trattano lo socket alla stessa maniera, sia per inviare i dati che per la ricezione, cambia solo l'inizializzazione.

Il client che tenta di effettuare una connessione al server X.Y.Z.T userà questo codice:
=Socket Client BLoccante TCP
-----------------------------------
my $sock = IO::Socket::INET->new (PeerAddr => 'www.gigi.com', # Anche l'IP va bennissimo
PeerPort => '1234', # La porta del server
Proto => 'tcp' # Se il protocollo è TCP si può anche omettere Proto
);
unless ($sock) { # Unless=Se la condizione è falsa esegui il blocco. Ossia se $sock ha valore nullo esegui.
print "La connessione non è avvenuta\n";
exit;
}
print $sock "Ciao server, come stai oggi?\n\r"; # La funzione print si usa anche per i file e gli socket.
my $tmphan=select $sock;
$|=1; # E' sempre meglio svuotare il buffer, per ora prendete questa istruzione come buona.
select $tmphan;
close $sock; # Chiude lo socket
-----------------------------------

=Socket Server Bloccante TCP
-----------------------------------
$server = IO::Socket::INET->new(Listen => 5,
LocalAddr => 'www.gigi.com', # Verranno accettate connessioni che hanno come
# destinazione l'ip corrispondete al dominio gigi.com
LocalPort => 1234, # La porta di ascolto
Proto => 'tcp'); # Protocollo usato
$alfa=$server->accept(); # Resta in attesa che il client tenti la connessione con gigi.com

# Seguita l'istruzione precedente avremo in $alfa l'oggetto socket che ci permette di comunicare con il client.
recv $alfa,$buf,1500,0; # Resta in attessa di ricezione di un pacchetto dal client
print "Il client mi ha spedito questa scritta;$buf\n";
close $alfa; # CHiude la comunicazione
----------------------------

Bene, la prima lezione è terminata. Consultate il man di IO::Socket e IO::Socket::INET per molti altri dettagli.
Su perlfunc trovate le giuste sintassi per la funzione send e recv.

Prossima lezione spegera come capire se in uno socket ci sono dei dati da analizzare senza mettersi in attessa.
ciao.






[PILLOLA][socket] recv non bloccante :D
Anallizzeremo ora la funzione select(RBITS,WBITS,EBITS,TIMEOUT) inclusa nel perl core e che quindi non necessita di alcuna librerie.
select prmette di selezionare alcuni filehandle e di capire quando essi accessibili in scrittura e in lettura.

Consideriamo l'oggetto socket $sock. Vogliamo sapere se ci sono dei dati in arrivo senza usare recv.
Ricordate che recv blocca il programma finche non ci sono dati in arrivo?
Il seguente ciclo si mette in loop fino a quando non ci sono dati nel buffer di $sock.
=Socket Ricezione non bloccante
--------------------------------------------
do {
$rin='';
vec($rin,fileno($sock),1) = 1;
} until (select ($rin,undef,$rin,0));

recv $sock,$buf,1500,0; # Dopo il primo ciclo ci saranno sicuramente dei dati.
---------------------------------------------
Nella chiamata select è possibile impostare come ultimo valore un tempo di timeout in secondi.
Nell'esempio era impostato a Zero, ossia controlla se ci sono dati ed esce subito.
Se avremo impostato un tempo di timeout di 10 avrebbe aspettato un tempo massimo di 10 secondi prima di uscire.
Aspetta come tempo massimo! Esce dalla chiamata select non appena gli socket selezionati avvertono un cambiamento.
E' possibile impostare come timeout anche 0.25 secondi, non solo valori interi.

La stessa funzione select si usa per limitare la banda in upload su uno socket non bloccante.
La limitazione della banda in upload (ad esempio per inviare un file) su uno socket si può limitare richiamando il modulo Benchmark e sfruttando sempre la chiamata select.





[PILLOLA][socket] Inivare file limitando la banda in uscita.
Se non l'avete installatevi il modulo Time::HiRes.
Partiamo subito con il codice:
=Socket
------------------------------------
use IO::Socket::INET;
use Time::HiRes;
my $cansend=0;
my $sock = IO::Socket::INET->new(Listen => 5,
LocalPort => 12345,
Proto => 'tcp');

my $data="questra frase di esempio mostrerà come è possibilile limitare la banda in upload su una connessione. :)";
my $speed=4; # Byte al secondo.
print "in ascolto $sock\n";
$client=$sock->accept;

my $inviati=0;
my $lastsend=Time::HiRes::time();
my $rin='';
vec($rin,fileno($client),1) = 1;
select $client;
$speed=1/$speed;
while (select (undef,$rin,$rin,2)) {
$inviati+=Time::HiRes::time()-$lastsend;
$lastsend=Time::HiRes::time();
if ($cansend=int($inviati/$speed)) {
$inviati-=$speed*$cansend;
print substr($data,0,$cansend,"");
$|=1; # Svuota il buffer.
}
$rin='';
vec($rin,fileno($client),1) = 1;

}
-------------------------------------
Questo ciclo limita molto precisamente i byte in uscita.
Per provarlo eseguite lo script e con telnet connettetevi in localhost alla porta 12345.
Per vedere cosa fa substr, int, guardatevi la guida perlfunc, sono delle istruzioni basilari di perl.
Time::HiRes::time() ve lo dico io. Fa parte del modulo Time::HiRes e ritorna i secondi trascorsi dal 1970 con una precisione di un milionesimo di secondo.
Per il resto studiatevi il codice :P
Il ciclo funzione perfettamente anche se dovesse rimanere bloccato per qualche secondo alla fine del ciclo while.
Provate ad aggiungere uno sleep(3) prima dell'ultima graffa. Vedrete che invierà un certo gruppo di X byte tutti insieme.
Questo ciclo è eseguito migliaia di volte al secondo senza sleep e usa il massimo delle risorse, ecco perchè p2p come emule fanno il controllo sui buffer in uscita ogni 0.2 secondi (mi sembra). Come se dopo il controllo ci fosse uno sleep(0.2).



Non so se ti sarà utile. Io proprio non mi so spiegare.
Scrivimi quando vuoi.

Quando volevo programmare in socket io in perl nessuno lo sapeva fare, o meglio, le indicazioni erano molto vaghe. Non so quanto avrei pagato per qualcuno che mi avesse aiutato.
Ora mi "diverto" a fare programmi in perl che gestiscono molte connessioni alla volta.
Ciao :D

FreeManX
17-01-2005, 23:54
Ammetto che non ho mai programmato client-server sotto perl (provvedero presto) cmq sotto C non è poi cosi ostico, conosci le primitive sia come usarle se a cavallo.
Cio' vale anche Perl, non fatevi ingannare dalla semplicità di programmare, questo tipo di applicazioni (a mio parere) devono essere benesate bene, per non trovarsi nei casi, dato che oltre alla rete si va a toccare la programmazione di sistema (server multiprocesso).

Indubbiamente Perl con tutti i suoi moduli è molto più semplice da apprendere e programmare, oltretutto i tipi di dato che utilizza perl semplificano ancora di più la vita, a differenza dei tipi di dato utilizzati in C.

Sbagli Lord, Perl (come tutti i linguaggi) se programmato bene è portabile molto più di C, adesso non conosco specificatamente i moduli per questo tipo di programmazione in perl, ma credo siano sufficemente adattabili.
Ma purtroppo la programmazione di rete (e sistema) è fortemente dipendente dalla piattaforma! :dhò:

Tallone d'achille di Perl è indubbiamente l'impossibilità (o quasi) di avere codice eseguibile, Perl è interpretato è ciò implica lentezza di esecuzione. Dove le prestazioni sono critiche ovviamente programmare client-server con Perl non è indicato, ma per applicazioni comuni, in cui non si hanno neanche chissacosa necessita di potenza il problema non si pone.

uff mazza quanto ho scritto, forse non tutto quello che volevo. :fagiano:

bye bye

Loading