sabato 17 maggio - 05:19
Google
 
Menù
  Home
  Come nasce IRC-Zone
  Glossario Informatico
  Servizio FreeBot
  News
  I nostri progetti
  I nostri servizi
  Partners
  Diventa un Partner

IRC
  Cos'è IRC
  Storia di IRC
  Netiquette su IRC
  Emoticons
  Gergo della chat
  Lista Servers
  RFC 1459
  Shell Hosting

mIRC
  Cos'è il mIRC
  FAQ mIRC
  Configurazione mIRC
  Download mIRC
  Novità
  Script Stranieri
  Script Italiani
  MTS
  MTS Engine

mIRC Addon
  mIRC addon Audio
  mIRC addon SMS
  mIRC addon Grafica
  mIRC addon Utility
  mIRC addon Uso Bot

Client IRC
  Client IRC Linux
  Client IRC Mac
  Client IRC Win

XChat
  Cos'è XChat
  XChat per Win
  XChat per Unix

KVirc
  Cos'è KVirc
  FAQ KVirc
  Installazione su Linux
  KVirc Scripting
  KVirc per Mac
  KVirc per Win
  KVirc per Unix
  KVirc addon

Eggdrop/Windrop
  Cos'è un Eggdrop
  Download Eggdrop
  Configurazione Eggdrop
  Download Windrop
  Installazione Windrop

Tcl
  Download TCL
  Tutorial TCL scripting
  Documenti/Guide

BNC
  Cos'è un psyBNC
  Download psyBNC
  Configurazione psyBNC
  Download sBNC
  Configurazione sBNC

Linkaci!

Credits


Statistiche
Ip: 38.103.63.16
Downloads: 248812 files
Totale: 290620 MB




Art of Scripting Vol. 7 - Socket e Perl in KVIrc scripting

Autore: GrifisxData: 2005-12-06
Modificato: 2005-12-17 Letture: 394
Torna indietroStampa articoloInvia ad un amico

Start:

The Server side:

In questo tutorial cercherò di essere molto conciso.
Per prima cosa andremo a costruirci un serverino cioè faremo in modo che una socket si predisponga in ascolto su una certa porta e si dichiari disponibile ad accettare eventuali connessioni verso di questa.
La classe che ci interessa è, ovviamente, la classe socket quindi da bravi studenti andiamo a leggerci un po' le funzioni che il nostro bel client ci mette a disposizione dal famoso file di help =).
Fatto questo cominciamo subito a buttar giù codice allegramente :D.
Per prima cosa, guardando la documentazione, si nota che l'elemento fondamentale di una socket sono gli eventi ed è tramite questi che  possiamo capire cosa sta succedendo sulla nostra socket, se qualcuno ci si sta connettendo, se la connessione è terminata e così via.
Questo ci fa anche pensare che la cosa migliore è andare a creare una bella classe tutta nostra che derivi da socket in modo da poter scrivere del codice più leggibile e immediato, senza troppi privateImpl(bla bla bla).
Quindi cominciamo subito a far nascere la nostra classe myserver:


class(myserver,socket)
{
    constructor(){};
}


Ok, ora che è nata possiamo cominciare a pensare a cosa debba fare e gestire la nostra socket; abbiamo detto che sarà un server quindi la prima cosa che dovrà fare è mettersi in ascolto su una porta.
Vediamo la funzione $listen() cosa ci permette di fare:
mette in ascolto una socket su una porta, usando una determinata interfaccia (più semplicemente un ip) e permettendoci la possibilità, se volessimo, di usare il protocollo ipv6, ottimo direi...
Quindi quello che dovremmo fare nel nostro caso sarebbe:

(Nostra_socket)->$listen(80,127.0.0.1,0)
Specifichiamo la porta 80, interfaccia mettiamo l'ip locale e ipv6 lo settiamo a 0 cioè FALSO.

Quindi riscriviamo il nostro codice:

class(myserver,socket)
{
    constructor()
    {
        if(!$$->$listen(80,127.0.0.1,0))
        {
            echo Err: Listen fallito.
        }
        echo Server in ascolto
    }
}


Come vedete ho messo un if per farci dire se il comando fallisce. Infatti questa funzione ci restituisce 1 se è andata a buon fine e 0 nel caso opposto, quindi posso valutare il valore restituito tramite un semplice if.
Mi scuso con gli utenti avanzati per queste precisazioni ma i tutorial devono essere leggibili da tutti ^_^.
Adesso vediamo che la socket che stiamo costruendo deve reagire alle connessioni in arrivo, quindi sarà necessario reimplementare l'evento
incomingConnectionEvent(), ma non soltanto poiché se andiamo a leggere la documentazione su questo evento ci dice:

'incomingConnectionEvent()
This function is called when an incoming connection arrives over a socket in listening state.
You must call $accept() passing a newly created socket object to accept and handle the connection.
If you don't call $accept() the incoming connection will be automatically terminated.'


Quindi, a quanto ci dice la documentazione, noi dobbiamo chiamare la funzione $accept() passandogli un nuovo oggetto socket creato sul momento e sarà poi lui a gestirsi quella particolare connessione. Vediamo un po' come dovrà essere il nuovo codice

class(myserver,socket)
{
    constructor()
    {
        if(!$$->$listen(80,127.0.0.1,0))
        {
            echo Err: Listen fallito.
        }
        echo Server in ascolto
    }
    incomingConnectionEvent()
    {
        %Tmp = $new(socket)
        $$->$accept(%Tmp)
        echo "Connessione da: %Tmp->$remoteIp : %Tmp->$remotePort"
       
        %Tmp->$close()
        # Eliminiamo la sock di appoggio
        delete %Tmp;
    }
}
%Serverside=$new(myserver)

Ora possiamo eseguirlo per vedere cosa succede, quindi apriamo il nostro Script Tester, incolliamo ed eseguiamo!
Ci dice subito:
'Server in ascolto.'
Quindi la porta è stata messa in ascolto correttamente.
Adesso vediamo se reagisce ad una connessione, apriamo la shell dei comandi (oppure ms-dos se siamo sotto windows) e diamo il comando telnet 127.0.0.1 80
Come possiamo vedere il nostro serverino ci dice:
'Connessione da: 127.0.0.1 : 2161'
adesso però dobbiamo fare in modo da creare una sorta di comunicazione tra server e client, vediamo come possiamo fare.
Dovremmo usare le funzioni $write(), $read() ed ovviamente l'evento dataAvailableEvent() per poter gestire lettura e scrittura sulla nostra socket (la socket slave ovviamente, cioè %Tmp, perché è quella  la socket alla quale ci appoggiamo per mantenere la connessione.
Scriviamo il codice:

class(myserver,socket)
{
    constructor()
    {
        if(!$$->$listen(80,127.0.0.1,0))
        {
            echo Err: Listen fallito.
        }
        echo Server in ascolto
    }
    incomingConnectionEvent()
    {
        %Tmp = $new(socket)
        $$->$accept(%Tmp)
        echo "Connessione da: %Tmp->$remoteIp : %Tmp->$remotePort"
        %Tmp->$write("Welcome on KVIrc!\r\n");
        privateImpl(%Tmp,dataAvailableEvent)
        {
            %actualData=%Tmp->$read($0)
            if(%actualData!=$cr$lf){
            %Data = %Data%actualData;}
            else{       
            echo $b %Tmp->$remoteIp() \-\> $b %Data
            %Data=
            }       
        }

    }
    destructor()
    {
        delete %Tmp
        %Data=
       
    }

}
%Serverside=$new(myserver)


Come potete vedere tramite la funzione:
%Tmp->$write("Welcome on KVIrc!\r\n");
faccio scrivere sulla nostra socket un messaggio di benvenuto, poi
gestisco l'evento dataAvailableEvent() della socket a cui ci stiamo appoggiando e gli faccio leggere i dati con la funzione:
%actualData=%Tmp->$read($0);
se i dati che ha letto sono uguali ai carattere di $cr$fl (guardatevi queste 2 funzioni, $cr e $fl, nella documentazione) allora mi faccio dare l'echo dei caratteri che ha accumulato fino a quel momento, altrimenti glieli faccio accumulare, in questo modo sul KVIrc l'echo apparirà delle stringhe inviate e non del singolo carattere (tutto questo perché telnet invia i dati uno alla volta nel moemnto stesso in cui scriviamo e non tutti insieme quando diamo l'Invio).
Adesso mettiamo il codice nello script tester, eseguiamo e poi dal prompt dei comandi diamo il:
telnet 127.0.0.1 80
e proviamo a scrivere qualche cosa nel prompt dei comandi e poi dare Invio, vedrete che sarà nata la prima forma di comunicazione tra KVIrc ed il nostro telnet tramite le socket =D. Notate che ho implementato anche il distruttore nella classe, cosi quando deleterò l'oggetto %Serverside, automaticamente mi deleterà i dati e la socket che uso come slave.

Client Side:
Adesso proviamo a fare quello che facciamo con il nostro telnet, tramite KVIrc stesso, creandoci una sorta di piccolo telnet sempre tramite script =).


class (mySocket,socket)
{
    constructor()
    {
        $$->$connect("127.0.0.1",81)
    }

    connectFailedEvent()
    {
        echo "Connection to localhost failed..."
    }

    connectEvent()
    {
        $$->$write("Connesso: $cr$lf")
    }

    dataAvailableEvent()
    {
        echo $$->$read($0)       
    }
    send()
    {
        $$->$write($0$cr$lf)
    }

}
%Connessione = $new(mySocket)


Come vedete la costruzione è abbastanza semplice non c'è niente di particolare, adesso che sapete creare un server il codice del client è chiaro.
Da notare che ho fatto la funzione $send(), questa ci permetterà di poter comunicare con il server anche dopo la connessione; basterà infatti il comando del tipo:
%Connessione->$send(frase da inviare)
La connessione la si crea tramite la funzione $connect(, ) e tutto il resto lo si gestisce più o meno come abbiamo visto con il server.
Adesso andiamo a modificare il server che abbiamo scritto prima in modo da renderlo adatto anche a questo tipo di connessione e capiremo perché è diversa da quella fatta tramite il telnet.


class(myserver,socket)
{
    constructor()
    {
        if(!$$->$listen(81,127.0.0.1,0))
        {
            echo Err: Listen fallito.
        }
        echo Server in ascolto
    }
    incomingConnectionEvent()
    {
        %Tmp = $new(socket)
        $$->$accept(%Tmp)
        echo "Connessione da: %Tmp->$remoteIp : %Tmp->$remotePort"
        privateImpl(%Tmp,dataAvailableEvent)
        {
            %actualData=%Tmp->$read($0)   
            echo $b %Tmp->$remoteIp() \-\> $b %actualData
        }
    }
    destructor()
    {
        delete %Tmp       
    }
}
%Serverside=$new(myserver)


La differenza è che, come vedete, non controllo più se c'è il carattere(in realtà sono 2 caratteri) di invio (ritorno a capo+nuova linea) ($cr$lf)prima di farmi dare l'echo e questo semplicemente perché adesso i dati li inviamo tutti insieme e non più un carattere alla volta come con il telnet.
Facciamo la prova pratica, avviate prima il server e dopo il client e dopo date il comando
/%Connessione->$send(Questa è una prova)
Come vedete, se tutto è andato per il verso giusto, il server vi avrà stampato a schermo i dati che avete inviato.
La funzione $send() che abbiamo fatto infatti invia la frase+$cr$lf tutta insieme mentre, come ho detto prima, con il telnet man mano che scrivevamo un carattere questo veniva inviato ecco perché ci serviva  controllare quando arrivavano i caratteri di fine riga e ritorno a capo prima di stampare a schermo.

Perl:

Prima di concludere questo tutorial volevo parlare un po' della possibilità del KVIrc di eseguire codice Perl il che puo' essere molto utile.
Cominciamo col dire che il codice Perl va inserito tra i comandi perl.begin e perl.end, quindi avremo un codice di questo genere


perl.begin


perl.end

dall'interno del codice Perl possiamo usare alcuni comandi, che ora andremo a vedere, per poter interagire con il KVS (KVIrc Scripting).
Come in questo esempio:

perl.begin
KVIrc::echo("Prova del Perl riuscita!");
perl.end

Se lo eseguiremo vedremo che stamperà a schermo la frase che abbiamo passato al comando KVIrc::echo, che non è altro che la 'controparte' del normale echo che usiamo in scripting.
La sintassi completa è:
KVIrc::echo([,[,]])
è il testo da stampare.
è l'equivalente dell'opzione -i dell'echo.
è l'equivalente dell'opzione -w dell'echo.
Quindi se volessimo scrivere la frase blu, ad esempio, potremmo fare:
KVIrc::echo("Prova del Perl riuscita!",4);
Ovviamente i parametri colorset e windowid possono essere omessi.
Un'altra possibilità è quella di passare delle variabili all'interno del nostro micro-ambiente Perl.
KVIrc::getLocal()
Ritorna il valore della variabile locale %x di KVIrc
KVIrc::getGlobal()
Ritorna il valore della variabile %Y di KVIrc.
KVIrc::setLocal(,)
Setta il valore della variabile locale, di KVIrc , %x a
KVIrc::setGlobal(,)
Setta il valore della variabile Globale, di KVIrc ,%Y a
Ecco un esempio direttamente dalla documentazione:

%pippo = test
%Pluto = 12345
perl.begin
$mypippo = KVIrc::getLocal("pippo");
$mypluto = KVIrc::getGlobal("Pluto");
KVIrc::setLocal("pippo",$mypluto);
KVIrc::setGlobal("Pluto",$mypippo);
perl.end
echo "\%pippo is" %pippo
echo "\%Pluto is" %Pluto

Oppure:

%x = 10
perl.begin
$x = KVIrc::getLocal("x");
KVIrc::eval("echo \"The value is ".$x."\"");
perl.end


Qui vedete anche il comando KVIrc::eval(codice) che serve ad eseguire codice di scripting in modo diretto.
Ultimo comando è KVI::say, anche questo è molto semplice nella sua utilità e nella sintassi:
KVIrc::say("Ciao a tutti!");
Fa la stessa cosa di '/say Ciao a tutti'
Ricapitolando i comandi a nostra disposizione sono:


KVIrc::echo([,[,]])
KVIrc::getLocal()
KVIrc::getGlobal()
KVIrc::setLocal(,)
KVIrc::setGlobal(,)
KVIrc::eval()
KVIrc::say()


Adesso vediamo, come fare a passare dei valori all'interno del nostro codice Perl:
La sintassi di perl.begin in realtà è questa:
perl.begin(,,,...)
Cioè possiamo passare al nostro ambiente Perl degli argomenti che poi andremo a leggere tramite lo speciale $_[InDICE] che non è altro che un array contenente i parametri che abbiamo passato.
Per questo potrete guardavi direttamente gli esempi sulla guida ufficiale inutile che ve li traduca io.
Invece adesso andiamo a fondere insieme quello che abbiamo imparato:


class(myserver,socket)
{
    constructor()
    {
        if(!$$->$listen(80,127.0.0.1,0))
        {
            echo Err: Listen fallito.
        }
        echo Server in ascolto
    }
    incomingConnectionEvent()
    {
        %Tmp = $new(socket)
        $$->$accept(%Tmp)
        echo "Connessione da: %Tmp->$remoteIp : %Tmp->$remotePort"
        $$->$makeFileList()
        %Tmp->$write("HTTP/1.0 200 OK\r\n");
        %Tmp->$write("Content-type: text/html\r\n\r\n");
        %Tmp->$write("\n")
        %Tmp->$write(" \n")
        %Tmp->$write(" \n")
        %Tmp->$write(" 
.:Kvirc Power!:.
\n")
        %Tmp->$write(%MyFiles)
        %Tmp->$write(" \n")
        %Tmp->$write("\n\r\n\r\n")
        # Chiudiamo
        %Tmp->$close()
        # Eliminiamo la sock di appoggio
        delete %Tmp;
    }
    dataAvailableEvent()
    {
        %Data = %Data + $$->$read($0)       
    }
    makeFileList()
    {
        %MyFiles=""

        perl.begin
        opendir(DIR, ".");
        @files = readdir(DIR);
        closedir(DIR);
        foreach $file (@files) {
        KVIrc::eval("%MyFiles << $file
");
        }
        perl.end
    }
}
%ServerSide=$new(myserver)

Come vedrete esaminando il codice, abbiamo creato una specie di piccolo e semplice serverino http, che dà come pagina iniziale un documento html contenente la lista di tutti i file della directory corrente, questa lista l'abbiamo realizzata tramite Perl, nella funzione $makeFileList()
Per provare come funziona, dopo averlo eseguito, connettiamoci tramite il nostro Browser preferito all'indirizzo 'http://127.0.0.1' ..magia =).
Infine, per completare, voglio farvi leggere anche il codice che si trova pubblicato sulla wiki ufficiale del KVIrc, anche qui troviamo l'uso del Perl ma per esaminare, tramite una connessione client, quello che un server ci sta dicendo... ecco a voi il GetIp:


class (mySocket,socket) {
    constructor() {
        # trying to connect
        $$->$connect("whatismyip.com",80)
    }
    connectFailedEvent() {
        # connection failed
        echo "Connection to whatismyip.com failed..."
    }
    connectEvent() {
        # Seinding request...
        $$->$write(GET / HTTP/1.1$char(13)$char(10))
        $$->$write(Host: whatismyip.com$char(13)$char(10))
        $$->$write(Connection: close$char(13)$char(10)$char(13)$char(10))
    }
    dataAvailableEvent() {
                # reading data
        %Data = %Data + $$->$read($0)       
    }
    disconnectEvent() {
        # disconnected from server
        %MyIP = ""
        perl.begin (0, %Data)
        my $data = $_[0];
        if ($data =~ /([0-9]+?)\.([0-9]+?)\.([0-9]+?)\.([0-9]+)/)
        {
            KVIrc::eval("%MyIP = $&amp;");
        }
        perl.end
        perl.destroy(0)
        %blub = "bla"       
    }
}
%Data = ""
%myCon = $new(mySocket)
echo %MyIP

Il codice di sopra non l'ho scritto io, lo trovate su 'http://we-are-teh-b.org/~kvirc/index.php/GetIP'.
A questo punto siete in grado di capirlo da soli =) ..digitiamo soddisfatti il nostro
/ECHO STOP.





Links utili

Newsletter
Iscriviti
Cancellati

Ci sono 57 iscritti

In rilievo..
  JackSMS v3
  Venom Script Lite

Documenti/Guide
  Sicurezza in rete
  Cos'è SSL
  FAQ Bot
  Documenti su IRC
  FAQ Ident
  RFC 2810
  RFC 2811
  IRCx RFC

Informatica libera
  Gli Hoaxes
  Hoaxes report
  Documenti vari
  CensorWare
  Windows
  Linux

mIRC Scripting
  Codice ASCII
  Snippet mIRC scripting
  Tutorial mIRC scripting
  Dll per mIRC
  Utilities

IRCd
  Cos'è un IRCd
  Download Unreal
  Download Hybrid 6
  Download Hybrid 7
  Download Ultimate
  Download Bahamut
  Configurazione IRCd

IRC Services
  Cosa sono i Services
  Download Anope
  Download Epona
  Ircservices 5.0
  Ircservices 5.1
  Configurazione Epona
  Configurazione Anope
  Comandi ChanServ
  Comandi NickServ
  Comandi MemoServ

NeoStats
  Cosa sono i NeoStats
  Download NeoStats
  Configurazione NeoStats
  Download Moduli

IPv6
  Cos'è IPv6
  IPv6 su Win2000
  IPv6 su WinXP
  IPv6 su Linux
  IPv6 su mIRC e Xchat

Programmazione
  Tutorial C++
  Tutorial C
  Compilatori C/C++

Altro
  Contatti
  Banners Gallery

RSS Feed




Progetti
Starlight
Linux

Sponsor
Eushells.net
TradeShell.it
EasyShell.org



©2004+ IRC-Zone | Webmaster | Sitemap
Created by Cesare 'Kaesar83' Lasorella
Designed by Manuel 'erkokki' Cabras
IRC-Zone non è responsabile del contenuto dei siti linkati
Pagina creata in: 0.021 sec con 26 queries