Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [Pillola] Come interfacciarsi con TCPServer e XINETD

    Questa pillola è dedicata a tutti quelli che hanno le manine lunghe come me e nelle domeniche pomeriggio invece di lavorare passano tempo a sperimentare
    Era da tempo che ero curioso di capire come di preciso TCPServer e XINETD funzionassero!

    Premetto che già un po conoscevo il funzionamento base di questi 2 applicativi per linux xo se non si prova...non si può essere certi...
    Qui farò le prove solo con TCPServer, comunque, questi due hanno un funzionamento praticamente identico al max cambiano le variabili di ambiente

    ---===[ COSA SONO ]===---
    TCPServer e XINETD sono 2 utilissimi utility, se cosi le vogliamo chiamare, che consentono di sviluppare potenti applicativi di rete in maniera semplice e veloce!
    TCPServer e XINETD infatti sono un tramite tra il vostro applicativo ed il client che si connette!

    ---===[ COME FUNZIONANO ]===---
    La mia parte ascii non ha resistito...^^

    codice:
     INTERNET
    ----------> Macchina Linux ----> TCPServer\XINETD ----> Programma richiesto
    ovvero arriva una richiesta di connessione da internet al vostro pc. Mettiamo che abbiate detto a TCPServer che deve avviare il programma chiamato XYZ quando c'è una richiesta di connessione all'indirizzo IP 0.0.0.0 (quindi tutti quelli disponibili) e alla porta 1234.
    Quando vi connetterete a quella porta e all'ip della vostra macchina all'istante TCPServer avvierà il programma che gli avete indicato. Prima di avviare il programma imposterà alcune variabili di ambiente. Stesso tipo di operazione la fa ovviamente anche XINETD. A questo punto comunicherete con le due utility tramite lo standard input e lo standard output!
    Ogni cosa che il client vi invierà sarà disponibile sullo standard input ed ogni che vorrete inviare dovrà essere inviata allo standard output.

    Per chiarirvi un po l'idea su cosa sono lo standard input e lo standard output date 1 occhio a:
    http://www.phpfreaks.com/tutorials/86/0.php
    http://www.phpbuilder.com/columns/darrell20000319.php3

    Trattano come usare PHP come scripting da shell, ovviamente sono in inglese. Se non ricordo male ci dovrebbe anche essere 1 articolo su http://freephp.html.it

    Quindi tornando al discorso di prima ci sarà 1 situazione di questo tipo

    Client <---> Utility <---> Vostro Programma

    spero di essere stato chiaro ^^
    Purtroppo questi sono concetti di base quindi è bene che ve li studiate prima di continuare a leggere ^^

    ---===[ COME USARLI ]===---

    Ho fatto un piccolo script nel quale ogni volta che viene battuto invio sul client lui invia il testo inviato con una stringa davanti tipo "### Echo: "
    Lo script è veramente banale, i commenti lo spiegano da solo, comunque qui di seguito lo spezzato...e ogni spezzone è spiegato

    codice:
    #!/usr/bin/php -q
    dico al sistema linux (o comunque posix\bsd) che questo file deve essere interpretato con l'interprete da console (ovvero l'interprete CLI) di php
    mettendo in un file eseguibile #! il sistema linux capisce che quel file va "interpretato" da un programma apposito quindi avvia il programma e gli passa, tramite lo standard input tutto il resto del file

    codice:
    <?php
    
            // Definisco la configurazione
            define('MAX_BUFFER', 100);
    
            // Definisco le costanti per lo standard INPUT e lo standard OUTPUT
            define('STDIN', 'php//stdin');
            define('STDOUT', 'php//stdout');
    
            // Definisco alcune stringhe standard
            define('MSGS_BEGIN', '### Server ECHO sviluppato in PHP ' . phpversion());
            define('MSGS_BEGIN2', '### Connessione proveniente da: %s:%s');
            define('MSGS_ECHO', '### Echo: %s');
    in questa sezione definisco alcune costanti come la configurazione, alcuni messaggi standard e lo standard input e standard output (in seguito chiamati STDIN e STDOUT)
    Come si vede il secondo e terzo messaggio contengono delle %s perche utilizzo sprintf per riempire quei dati
    Una cosa molto importante da notare è che le due costanti STDIN e STDOUT non contengono una stringa ma bensi una risorsa! PHP ha riconosciuto che php://stdin e php://stdout non erano 2 stringhe qualsiasi ma bensi lo standard input e lo standard output. Queste due risorse sono tranquillamente utilizzabili con le funzioni per la gestione dei file

    codice:
            // Invio una stringa di riconoscimento
            fwrite($fp['output'], MSGS_BEGIN . "\r\n");
            fwrite($fp['output'], sprintf(MSGS_BEGIN2, $_ENV['TCPREMOTEIP'], $_ENV['TCPREMOTEPORT']) . "\r\n");
    Invia i due messaggi di benvenuto al client inviando le stringe allo standard output. I messaggi sono definite nelle costanti di su.
    Le due variabili $_ENV['TCPREMOTEIP'] e $_ENV['TCPREMOTEPORT'] le definisce TCPServer al momento della connessione

    codice:
            // Inizializzo il buffer
            $buffer = '';
    
            // Raccolgo i dati
            while($data = fread($fp['input'], 1)) {
    Inizializzo il buffer, ovvero imposto la variabile, e leggo un carattere per volta dallo stdin. Questo per evitare problemi, infatti non essendo una socket, ma un file non l'ho impostato sulla modalità non blocking.
    Se avessi usato gli stream per gestire il tutto avrei potuto impostare la modalità non blocking e quindi leggere blocchi di dato maggiori. Se avessi messo 10 al posto di uno finche sullo standard input non ci sarebberò stati 10 byte a me non sarebbe ritornato nulla. Quindi, anche premendo invio, non sarebbe successo niente.
    Invece in questo modo ogni volta che arriva un carattare viene processato.

    codice:
                    // Controllo se il byte letto corrisponde all'invio
                    if ($data != "\n") {
    
                            // Se non corrisponde controlla la dimensione del buffer
                            if (strlen($buffer) > MAX_BUFFER) {
    
                                    // Se la dimensione massima del buffer e' superata resetta
                                    // il buffer con il dato appena letto
                                    $buffer = $data;
                            } else {
    
                                    // Se la dimensione massima non e' stata superata aggiunge
                                    // il dato al buffer attuale
                                    $buffer .= $data;
                            }
    A questo punto devo processare il byte ricevuto, quindi controllo se è un carattere di invio, ovvero se contiene uno \n o meno.
    Se non contiene lo \n, quindi l'andata a capo processo se la stringa ha superato la lunghezza massima del buffer con un semplice if. Se il buffer è stato riempito tutto lo svuoto e lo riempo con il nuovo carattere, alrtimenti, se c'è ancora spazio, aggiungo il byte appena letto.

    codice:
                    } else {
    
                            // E' arrivato il momento di replicare i dati
                            // quindi stampiamo il buffer e poi lo svuotiamo
                            fwrite($fp['output'], sprintf(MSGS_ECHO, $buffer) . "\r\n");
    
                            // Svuotiamo il buffer
                            $buffer = '';
                    }
            }
    
            // --- Esecuzione terminata ---
    ?>
    Se invece al programma arriva l'invio invia alla risorsa dello standard output la stringa che contiene il messaggio ripetuto e svuota il buffer. Come vedete anche qui uso sprintf per impostare il dato dentro la stringa
    Il programma poi termina e li potete fare quello che volete, tcpserver non termina il processo fin quando non è il processo stesso a morire quindi potete fare quello di cui avete bisogno

    Qui c'è il codice per intero
    codice:
    #!/usr/bin/php -q
    <?php
    
            // Definisco la configurazione
            define('MAX_BUFFER', 100);
    
            // Definisco le costanti per lo standard INPUT e lo standard OUTPUT
            define('STDIN', 'php//stdin');
            define('STDOUT', 'php//stdout');
    
            // Definisco alcune stringhe standard
            define('MSGS_BEGIN', '### Server ECHO sviluppato in PHP ' . phpversion());
            define('MSGS_BEGIN2', '### Connessione proveniente da: %s:%s');
            define('MSGS_ECHO', '### Echo: %s');
    
            // Invio una stringa di riconoscimento
            fwrite($fp['output'], MSGS_BEGIN . "\r\n");
            fwrite($fp['output'], sprintf(MSGS_BEGIN2, $_ENV['TCPREMOTEIP'], $_ENV['TCPREMOTEPORT']) . "\r\n");
    
            // Inizializzo il buffer
            $buffer = '';
    
            // Raccolgo i dati
            while($data = fread($fp['input'], 1)) {
    
                    // Controllo se il byte letto corrisponde all'invio
                    if ($data != "\n") {
    
                            // Se non corrisponde controlla la dimensione del buffer
                            if (strlen($buffer) > MAX_BUFFER) {
    
                                    // Se la dimensione massima del buffer e' superata resetta
                                    // il buffer con il dato appena letto
                                    $buffer = $data;
                            } else {
    
                                    // Se la dimensione massima non e' stata superata aggiunge
                                    // il dato al buffer attuale
                                    $buffer .= $data;
                            }
                    } else {
    
                            // E' arrivato il momento di replicare i dati
                            // quindi stampiamo il buffer e poi lo svuotiamo
                            fwrite($fp['output'], sprintf(MSGS_ECHO, $buffer) . "\r\n");
    
                            // Svuotiamo il buffer
                            $buffer = '';
                    }
            }
    
            // --- Esecuzione terminata ---
    ?>
    ---===[ RIASSUMENDO ]===---
    Utilizzando le funzioni per la gestione dei file in accoppiata allo stdin e stdout e questi applicativi è possibile scrivere svariati tipi di server! Ovviamente se avete bisogno dell'intercomunicazione tra i processo non è tra le migliore scelte ma comunque è realizzabile

    ---===[ COSA REALMENTE SI PUO' FARE ]===---
    Questo dipende dalla vostra fantsia potete fare un server di posta...un server ftp...un server web...qualsiasi cosa stuzzichi la vostra fantasia!
    Se invece volete fare cose + complesse potete anche fare 1 server centralizzato...ovvero vi spiego subito...

    mettiamo che dobbiate fare l'intercomunicazione tra i processi che spuntano...per farlo è veramente semplice! Dovete creare un piccolissimo server che lavora su socket unix...e gestisce le connessioni li su...e poi i vostri client quando partono si connettono a quella socket...oppure potete usare la memoria condivisa...potete usare le pipe...insomma qualsiasi cosa vogliate come vi ho detto...dipene dalla vostra fantasia

    ---===[ RIFERIMENTI ]===---
    Il pacchetto che contiene TCPServer si chiama uscpi-tcp ed è usatissimo con QMAIL, il più sicuro server di posta elettronica che esiste, oltre che il più potente
    XINETD è standard in qualsiasi distribuzione, sostituisce il vecchio INETD, che eseguiva lo stesso dipo di operazioni.

    Per aggiungere il vostro server a XINETD basta che creiate un file dentro la dir /etc/xinetd.d e li dentro aggiungiate una configurazione. Per maggiori info lanciate il comando:
    man xinetd.conf

    Vi mostrerà come scrivere un file di configurazione per xinetd per lanciare i vostri programmi

    TCPServer invece non ha un man, per avere maggiori info guardate qui
    http://cr.yp.to/ucspi-tcp/tcpserver.html

    Per scaricare i vari sorgenti
    http://cr.yp.to/ucspi-tcp.html

    Per avere altre info sulle variabili di ambiente...
    http://cr.yp.to/ucspi-tcp/environment.html

    ---
    qui finisce questa mini pillola...a breve metto online il codice dello script su file ^^



    PS: se notate Orrori...avvertite ... idem se trovate qualche idiozia ^^

  2. #2

  3. #3
    C'ho impiegato un pò a leggerla tutta ma ne è valsa la pena, anche se alcune parti non mi sono chiare ... ma spero che rileggendo caprirò.


  4. #4
    Originariamente inviato da piero06
    C'ho impiegato un pò a leggerla tutta ma ne è valsa la pena, anche se alcune parti non mi sono chiare ... ma spero che rileggendo caprirò.

    che parti? che magari aggiungo e poi faccio sistemare ai mod

    il succo del discorso è che tramite questi programmi puoi sviluppare completissimi server senza avere problemi per quanto riguarda la gestione dei socket...numero di connessioni e quant'altro ^^

    PS: hai avuto problemi xche è scritto in maniera orrida?

  5. #5
    Utente bannato
    Registrato dal
    Aug 2001
    Messaggi
    696
    aggiunta :metallica

  6. #6
    bump

    (sto aggiornando la data alle vecchie pillole per evitare che vengano cancellate. non scrivete ca22ate se non avete nulla da dire)
    Addio Aldo, amico mio... [03/12/70 - 16/08/03]

  7. #7
    BUMP
    Addio Aldo, amico mio... [03/12/70 - 16/08/03]

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.