Socket

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

Un socket è un tipo di connessione di rete stabilita tra due processi di computer. In genere, i processi sono eseguiti su due computer diversi collegati alla stessa rete IP (Internet Protocol). Tuttavia, i processi connessi possono essere in esecuzione sullo stesso computer utilizzando lo speciale indirizzo IP “host locale”.

Adobe Flash Player supporta socket TCP (Transport Control Protocol) lato client. Un'applicazione Flash Player può connettersi a un altro processo che agisce come un server socket, ma non può accettare richieste di connessione in entrata da altri processi. In altre parole, un'applicazione Flash può connettersi a un server TCP, ma non può agire come tale.

L'API Flash Player include anche la classe XMLSocket. La classe XMLSocket utilizza un protocollo specifico di Flash Player che consente di scambiare messaggi XML con un server in grado di comprendere tale protocollo. La classe XMLSocket è stata introdotta in ActionScript 1 ed è ancora supportata per fornire la compatibilità con le versioni precedenti. In generale, la classe Socket deve essere utilizzata per nuove applicazioni a meno che non vi connettete a un server creato specificatamente per comunicare con XMLSocket di Flash.

Adobe AIR aggiunge diverse classi per la programmazione di rete basata su socket. Le applicazioni AIR possono agire come server socket TCP con la classe ServerSocket e possono connettersi a server socket che richiedono la protezione SSL o TLS con la classe SecureSocket. Le applicazioni AIR possono inoltre inviare e ricevere messaggi UDP (Universal Datagram Protocol) con la classe DatagramSocket.

Socket TCP

Il protocollo TCP (Transmission Control Protocol) fornisce un modo per scambiare messaggi su una connessione di rete persistente. TCP garantisce che tutti i messaggi inviati arrivino nell'ordine corretto (bloccando i principali problemi di rete). Le connessioni TCP richiedono un “client” e un “server”. Flash Player è in grado di creare socket client. Adobe AIR può, in aggiunta, creare socket server.

Le API di ActionScript seguenti forniscono le connessioni TCP:

  • Socket: consente a un'applicazione client di connettersi a un server. La classe Socket non è in grado di intercettare connessioni in entrata.

  • SecureSocket (AIR): consente ad un'applicazione client di connettersi a un server trusted e partecipare a comunicazioni crittografate.

  • ServerSocket (AIR): consente ad un'applicazione di intercettare connessioni in entrata e svolgere la funzione di server.

  • XMLSocket: consente a un'applicazione client di connettersi a un server XMLSocket.

Socket client binari

Una connessione socket binaria è simile a un socket XML tranne per il fatto che il client e il server non si limitano a scambiare messaggi XML. Al contrario, sulla connessione possono essere trasferiti dati come informazioni binarie. In questo modo, potete connettervi a una più ampia gamma di servizi, compresi i server di posta (POP3, SMTP e IMAP) e i server delle news (NNTP).

Classe Socket

La classe Socket consente di effettuare connessioni socket e di leggere e scrivere dati binari originari. La classe Socket è utile per interagire con i server che utilizzano protocolli binari. Utilizzando le connessioni socket binarie potete scrivere codice che consente l'interazione con più protocolli Internet diversi, ad esempio POP3, SMTP, IMAP e NNTP. Ciò consente alle applicazioni di connettersi a loro volta ai server di posta e delle news.

Flash Player è in grado di interfacciarsi con un server utilizzando direttamente il protocollo binario di quel server. Alcuni server utilizzano l'ordine dei byte bigEndian e altri littleEndian. La maggior parte dei server in Internet utilizza l'ordine dei byte bigEndian perché questo è “l'ordine dei byte di rete”. L'ordine dei byte little-endian è molto comune perché è quello utilizzato dall'architettura Intel® x86. È necessario utilizzare l'ordine dei byte Endian corrispondente a quello del server che invia o riceve i dati. Tutte le operazioni eseguite dalle interfacce IDataInput e IDataOutput e le classi che implementano tali interfacce (ByteArray, Socket e URLStream) sono codificate per impostazione predefinita nel formato bigEndian, ovvero con il byte più significativo all'inizio. Questo ordine dei byte predefinito è stato scelto per corrispondere all'ordine dei byte Java e ufficiale della rete. Per scegliere di utilizzare l'ordine dei byte bigEndian o littleEndian, è possibile impostare la proprietà endian su Endian.BIG_ENDIAN o Endian.LITTLE_ENDIAN .

La classe Socket eredita tutti i metodi definiti dalle interfacce IDataInput e IDataOutput (situate nel pacchetto flash.utils) e utilizzati per scrivere e leggere da Socket.

Per ulteriori informazioni, vedete:

Socket client sicuri (AIR)

Potete usare la classe SecureSocket per connettervi a server socket che utilizzano Secure Sockets Layer versione 4 (SSLv4) o Transport Layer Security versione 1 (TLSv1). Un socket protetto offre tre vantaggi: autenticazione server, integrità dei dati e riservatezza dei messaggi. Il runtime autentica un server utilizzando il certificato server e la sua relazione ai certificati dell'autorità di certificazione principale o intermedia nell'archivio delle fonti attendibili dell'utente. Il runtime si basa sull'algoritmo di crittografia utilizzato dalle implementazioni dei protocolli SSL e TLS per fornire integrità dei dati e riservatezza dei messaggi.

Quando ci si connette a un server utilizzando l'oggetto SecureSocket, il runtime convalida il certificato server utilizzando l'archivio delle fonti attenibili del certificato. In Windows e Mac, il sistema operativo fornisce un archivio delle fonti attendibili. In Linux, il runtime fornisce il proprio archivio delle fonti attendibili.

Se il certificato server non è valido o non è attendibile, il runtime invia un evento ioError . Potete controllare la proprietà serverCertificateStatus dell'oggetto SecureSocket per determinare perché la convalida non è riuscita. Nessuna fornitura viene fornita per la comunicazione con un server che non dispone di un certificato valido e attendibile.

La classe CertificateStatus definisce costanti di stringa che rappresentano i possibili risultati della convalida:

  • Scaduto: è stata superata la data di scadenza del certificato.

  • Non valido: un certificato può essere non valido per diversi motivi. Ad esempio, il certificato potrebbe essere stato alterato, danneggiato, o semplicemente del tipo errato.

  • Catena non valida: almeno uno dei certificati nella catena dei certificati del server non è valido.

  • Errata corrispondenza principale: il nome host del server e il nome comune del certificato non corrispondono. In altre parole, il certificato usato dal server è errato.

  • Revocato: il certificato è stato revocato dall'autorità di emissione.

  • Attendibile: il certificato è valido e attendibile. Un oggetto SecureSocket può essere connesso solo a un server che utilizza un certificato valido attendibile.

  • Sconosciuto: l'oggetto SecureSocket non ha ancora convalidato il certificato. La proprietà serverCertificateStatus ha questo valore di stato prima di chiamare connect() e prima di inviare un evento connect o ioError .

  • Identità dei firmatari non attendibile: il certificato non si concatena a un certificato di una fonte attendibile nell'archivio delle fonti attendibili del computer client.

La comunicazione con un oggetto SecureSocket richiede che il server utilizzi un protocollo protetto e che disponga di un certificato valido attendibile. Per altri aspetti, l'utilizzo di un oggetto SecureSocket è identico all'utilizzo di un oggetto Socket.

L'oggetto SecureSocket non è supportato su tutte le piattaforme. Utilizzare la proprietà isSupported della classe SecureSocket per verificare se il runtime supporta l'utilizzo dell'oggetto SecureSocket sul computer client corrente.

Per ulteriori informazioni, vedete:

Esempio di socket TCP: creazione di un client Telnet

L'esempio relativo a Telnet illustra le tecniche necessarie per connettersi a un server remoto e trasmettere i dati utilizzando la classe Socket. Nell'esempio vengono descritte le seguenti tecniche:

  • Creazione di un client telnet personalizzato utilizzando la classe Socket

  • Invio di testo al server remoto utilizzando un oggetto ByteArray

  • Gestione dei dati ricevuti da un server remoto

Per ottenere i file dell'applicazione per questo esempio, visitate la pagina www.adobe.com/go/learn_programmingAS3samples_flash_it . I file dell'applicazione Telnet sono disponibili nella cartella Samples/Telnet. L'applicazione è composta dai seguenti file:

File

Descrizione

TelnetSocket.fla

o

TelnetSocket.mxml

File principale dell'applicazione che contiene l'interfaccia utente per Flex (MXML) o Flash (FLA).

TelnetSocket.as

Classe di documento che fornisce la logica dell'interfaccia utente (solo Flash).

com/example/programmingas3/Telnet/Telnet.as

Fornisce la funzionalità del client Telnet per l'applicazione, ad esempio per connettersi a un server remoto e inviare, ricevere e visualizzare i dati.

Panoramica dell'applicazione socket Telnet

Il file TelnetSocket.mxml principale viene utilizzato per la creazione dell'interfaccia utente (UI) dell'applicazione.

Oltre all'interfaccia utente, questo file definisce due metodi, login() e sendCommand() , per connettere l'utente al server specificato.

Il codice riportato di seguito elenca il codice ActionScript nel file dell'applicazione principale:

import com.example.programmingas3.socket.Telnet; 
 
private var telnetClient:Telnet; 
private function connect():void 
{ 
    telnetClient = new Telnet(serverName.text, int(portNumber.text), output); 
    console.title = "Connecting to " + serverName.text + ":" + portNumber.text; 
    console.enabled = true; 
} 
private function sendCommand():void 
{ 
    var ba:ByteArray = new ByteArray(); 
    ba.writeMultiByte(command.text + "\n", "UTF-8"); 
    telnetClient.writeBytesToSocket(ba); 
    command.text = ""; 
}

La prima riga di codice importa la classe Telnet dal pacchetto personalizzato com.example.programmingas.socket. La seconda riga di codice dichiara un'istanza della classe Telnet, telnetClient , che viene inizializzata successivamente dal metodo connect() . Viene quindi dichiarato il metodo connect() e viene inizializzata la variabile telnetClient dichiarata in precedenza. Questo metodo passa il nome del server specificato dall'utente, la porta del server telnet e un riferimento a un componente TextArea nell'elenco di visualizzazione, che viene utilizzato per visualizzare le risposte in formato testo del server socket. Le ultime due righe del metodo connect() impostano la proprietà title per il pannello e attivano il componente pannello, che consente all'utente di inviare dati al server remoto. Il metodo finale nel file dell'applicazione principale, sendCommand() , viene utilizzato per inviare i comandi dell'utente al server remoto come oggetto ByteArray.

Panoramica della classe Telnet

La classe Telnet viene utilizzata per connettersi al server Telnet remoto e per inviare/ricevere i dati.

La classe Telnet dichiara le seguenti variabili private:

private var serverURL:String; 
private var portNumber:int; 
private var socket:Socket; 
private var ta:TextArea; 
private var state:int = 0;

La prima variabile, serverURL , contiene l'indirizzo del server a cui connettersi specificato dall'utente.

La seconda variabile, portNumber , specifica il numero di porta su cui è attualmente in esecuzione il server Telnet. Per impostazione predefinita, il servizio Telnet viene eseguito sulla porta 23e.

La terza variabile, socket , è un'istanza di Socket che tenta di connettersi al server definito dalle variabili serverURL e portNumber .

La quarta variabile, ta , è un riferimento a un'istanza del componente TextArea sullo stage. Questo componente viene utilizzato per visualizzare le risposte dal server Telnet remoto o gli eventuali messaggi di errore.

La variabile finale, state , è un valore numerico che viene utilizzato per determinare le opzioni supportate dal client Telnet.

Come è già stato illustrato in precedenza, la funzione di costruzione della classe Telnet viene chiamata dal metodo connect() nel file dell'applicazione principale.

La funzione di costruzione Telnet accetta tre parametri: server , port e output . I parametri server e port specificano il nome del server e il numero di porta su cui è in esecuzione il server Telnet. Il parametro finale, output , è un riferimento a un'istanza del componente TextArea sullo stage dove viene visualizzato l'output del server.

public function Telnet(server:String, port:int, output:TextArea) 
{ 
    serverURL = server; 
    portNumber = port; 
    ta = output; 
    socket = new Socket(); 
    socket.addEventListener(Event.CONNECT, connectHandler); 
    socket.addEventListener(Event.CLOSE, closeHandler); 
    socket.addEventListener(ErrorEvent.ERROR, errorHandler); 
    socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 
    socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler); 
    Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml"); 
    try 
    { 
        msg("Trying to connect to " + serverURL + ":" + portNumber + "\n"); 
        socket.connect(serverURL, portNumber); 
    } 
    catch (error:Error) 
    { 
        msg(error.message + "\n"); 
        socket.close(); 
    } 
}
Scrittura dei dati su un socket

Per scrivere dati su una connessione socket, chiamate uno dei metodi di scrittura nella classe Socket. Questi metodi includono writeBoolean() , writeByte() , writeBytes() , writeDouble() e altri. Quindi, scaricate i dati nel buffer di output utilizzando il metodo flush() . Nel server Telnet, i dati vengono scritti sulla connessione socket utilizzando il metodo writeBytes() che utilizza l'array di byte come parametro e lo invia al buffer di output. Di seguito è riportato il metodo writeBytesToSocket() :

public function writeBytesToSocket(ba:ByteArray):void 
{ 
    socket.writeBytes(ba); 
    socket.flush(); 
}

Questo metodo viene chiamato dal metodo sendCommand() del file dell'applicazione principale.

Visualizzazione di messaggi dal server socket

Ogni volta che si riceve un messaggio dal server socket o si verifica un evento, viene chiamato il metodo personalizzato msg() . Questo metodo aggiunge una stringa al componente TextArea sullo stage e chiama un metodo personalizzato setScroll() , che scorre il componente TextArea fino alla fine. Di seguito è riportato il metodo msg() :

private function msg(value:String):void 
{ 
    ta.text += value; 
    setScroll(); 
}

Se il contenuto del componente TextArea non scorre automaticamente fino alla fine, gli utenti dovranno trascinare manualmente le barre di scorrimento nell'area di testo per visualizzare l'ultima risposta dal server.

Scorrimento di un componente TextArea

Il metodo setScroll() contiene un'unica riga di codice ActionScript che attiva lo scorrimento verticale del contenuto del componente TextArea, in modo che l'utente possa visualizzare l'ultima riga del testo restituito. Nello snippet di codice seguente, viene illustrato il metodo setScroll() :

public function setScroll():void 
{ 
    ta.verticalScrollPosition = ta.maxVerticalScrollPosition; 
}

Questo metodo imposta la proprietà verticalScrollPosition che corrisponde al numero di riga della prima riga di caratteri attualmente visualizzata e lo imposta come valore della proprietà maxVerticalScrollPosition .

Socket XML

Un socket XML consente di creare una connessione a un server remoto che rimane aperta finché non viene chiusa in maniera esplicita. Potete scambiare dati stringa, ad esempio XML, tra il server e il client. Un vantaggio legato all'uso di un server socket XML è rappresentato dal fatto che il client non deve richiedere esplicitamente i dati. Il server può inviare i dati a qualsiasi client connesso senza attendere una richiesta.

In Flash Player, e nel contenuto Adobe AIR esterno alla sandbox dell'applicazione, le connessioni socket XML richiedono la presenza di un file dei criteri per i socket sul server di destinazione. Per ulteriori informazioni, vedete Controlli del sito Web (file di criteri) e Connessione a socket .

La classe XMLSocket non può eseguire il tunneling automatico attraverso i firewall perché, a differenza del protocollo RTMP (Real-Time Messaging Protocol), XMLSocket non dispone di capacità di tunneling HTTP. Se è necessario il tunneling HTTP, valutate la possibilità di utilizzare Flash Remoting o Flash Media Server (che supporta RTMP).

Le restrizioni seguenti si applicano al contenuto in Flash Player o in un'applicazione AIR esterno alla sandbox di sicurezza dell'applicazione e riguardano la modalità di connessione al server da parte di un oggetto XMLSocket:

  • Per contenuto esterno alla sandbox di sicurezza dell'applicazione, il metodo XMLSocket.connect() può connettersi solo a numeri porta TCP maggiori o uguali a 1024. Una conseguenza di questa limitazione è che anche i daemon dei server che comunicano con l'oggetto XMLSocket devono essere assegnati a numeri di porta superiori o uguali a 1024. I numeri di porta inferiori a 1024 vengono spesso utilizzati dai servizi di sistema come FTP (21), Telnet (23), SMTP (25), HTTP (80) e POP3 (110) e pertanto gli oggetti XMLSocket sono esclusi da queste porte per motivi di sicurezza. La restrizione dei numeri di porta riduce le possibilità di accesso inappropriato e abuso di queste risorse.

  • Per contenuto esterno alla sandbox di sicurezza dell'applicazione, il metodo XMLSocket.connect() può connettersi solo a computer nello stesso dominio in cui risiede il contenuto (questa restrizione è identica alle regole di sicurezza per URLLoader.load() ). Per connettersi a un daemon di un server in esecuzione su un dominio diverso da quello su cui risiede il contenuto, è possibile creare un file di criteri validi tra più domini sul server che consenta l'accesso da alcuni domini specifici. Per ulteriori informazioni sui file di criteri validi tra più domini, consultate Sicurezza in AIR .

Nota: la procedura di configurazione di un server per la comunicazione con l'oggetto XMLSocket può rivelarsi un'operazione complessa. Se l'applicazione in uso non richiede l'interattività in tempo reale, utilizzate la classe URLLoader anziché la classe XMLSocket.

Per trasferire il codice XML verso e dal server su una connessione socket, potete utilizzare i metodi XMLSocket.connect() e XMLSocket.send() della classe XMLSocket. Il metodo XMLSocket.connect() stabilisce una connessione socket con una porta di un server Web. Il metodo XMLSocket.send() passa un oggetto XML al server specificato nella connessione socket.

Quando richiamate il metodo XMLSocket.connect() , l'applicazione apre una connessione TCP/IP al server e la mantiene aperta fino al verificarsi di uno dei seguenti eventi:

  • Viene chiamato il metodo XMLSocket.close() della classe XMLSocket.

  • Non sono più presenti riferimenti all'oggetto XMLSocket.

  • Flash Player viene chiuso.

  • La connessione viene interrotta, ad esempio il modem si disconnette.

Connessione a un server con la classe XMLSocket

Per creare una connessione socket, è necessario creare un'applicazione sul lato server che attende la richiesta della connessione socket e invia la risposta a Flash Player o all'applicazione AIR. Questo tipo di applicazione sul lato server può essere scritta in AIR o in un altro linguaggio di programmazione come Java, Python o Perl. Per utilizzare la classe XMLSocket, sul server deve essere in esecuzione un daemon in grado interpretare il semplice protocollo utilizzato dalla classe XMLSocket:

  • I messaggi XML vengono inviati su una connessione socket di streaming TCP/IP full-duplex.

  • Ogni messaggio XML è un documento XML completo, terminato da un byte zero (0).

  • Su una singola connessione XMLSocket può essere inviato e ricevuto un numero illimitato di messaggi XML.

Creazione e connessione a un server socket XML Java

Il codice riportato di seguito dimostra un semplice server XMLSocket scritto in Java che accetta le connessioni in entrata e visualizza i messaggi ricevuti nella finestra del prompt dei comandi. Per impostazione predefinita, viene creato un nuovo server sulla porta 8080 del computer locale, anche se è possibile specificare un numero di porta diverso quando si avvia il server dalla riga di comando.

Create un nuovo documento di testo e aggiungete il codice riportato di seguito:

import java.io.*; 
import java.net.*; 
 
class SimpleServer 
{ 
    private static SimpleServer server; 
    ServerSocket socket; 
    Socket incoming; 
    BufferedReader readerIn; 
    PrintStream printOut; 
 
    public static void main(String[] args) 
    { 
        int port = 8080; 
 
        try 
        { 
            port = Integer.parseInt(args[0]); 
        } 
        catch (ArrayIndexOutOfBoundsException e) 
        { 
            // Catch exception and keep going. 
        } 
 
        server = new SimpleServer(port); 
    } 
 
    private SimpleServer(int port) 
    { 
        System.out.println(">> Starting SimpleServer"); 
        try 
        { 
            socket = new ServerSocket(port); 
            incoming = socket.accept(); 
            readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream())); 
            printOut = new PrintStream(incoming.getOutputStream()); 
            printOut.println("Enter EXIT to exit.\r"); 
            out("Enter EXIT to exit.\r"); 
            boolean done = false; 
            while (!done) 
            { 
                String str = readerIn.readLine(); 
                if (str == null) 
                { 
                    done = true; 
                } 
                else 
                { 
                    out("Echo: " + str + "\r"); 
                    if(str.trim().equals("EXIT")) 
                    { 
                        done = true; 
                    } 
                } 
                incoming.close(); 
            } 
        } 
        catch (Exception e) 
        { 
            System.out.println(e); 
        } 
    } 
 
    private void out(String str) 
    { 
        printOut.println(str); 
        System.out.println(str); 
    } 
}

Salvate il documento sul disco rigido come SimpleServer.java e utilizzate un compilatore Java compilarlo, che crea un file di classe Java di nome SimpleServer.class.

Potete avviare il server XMLSocket aprendo un prompt dei comandi e digitando java SimpleServer . Il file SimpleServer.class può trovarsi in qualsiasi percorso del computer locale o della rete; non è necessario collocarlo nella directory principale del server Web.

Se non è possibile avviare il server perché i file non si trovano nel percorso di classe Java, provate ad avviarlo con java -classpath. SimpleServer .

Per connettervi a XMLSocket dall'applicazione, dovete creare una nuova istanza della classe XMLSocket e chiamare il metodo XMLSocket.connect() passando un nome host e un numero di porta, come riportato di seguito:

var xmlsock:XMLSocket = new XMLSocket(); 
xmlsock.connect("127.0.0.1", 8080);

Ogni volta che ricevete dati dal server, viene inviato l'evento data ( flash.events.DataEvent.DATA ):

xmlsock.addEventListener(DataEvent.DATA, onData); 
private function onData(event:DataEvent):void 
{ 
    trace("[" + event.type + "] " + event.data); 
}

Per inviare dati al server XMLSocket, utilizzate il metodo XMLSocket.send() e passate una stringa o un oggetto XML. Flash Player converte il parametro fornito in un oggetto String e invia il contenuto al server XMLSocket seguito da un byte zero (0):

xmlsock.send(xmlFormattedData);

Il metodo XMLSocket.send() non restituisce un valore che indica se i dati sono stati trasmessi correttamente. Se durante il tentativo di invio dei dati si è verificato un errore, viene generato un errore IOError.

Ogni messaggio inviato al server socket XML deve essere terminato da un carattere newline ( \n ).

Per ulteriori informazioni, vedete XMLSocket .

Socket server

Utilizzate la classe ServerSocket per consentire ad altri processi di connettersi all'applicazione utilizzando un socket TCP (Transport Control Protocol). Il processo di connessione può essere eseguito sul computer locale o su un altro computer connesso in rete. Quando un oggetto ServerSocket riceve una richiesta di connessione, invia un evento connect . L'oggetto ServerSocketConnectEvent inviato con l'evento contiene un oggetto Socket. Potete utilizzare questo oggetto Socket per le successive comunicazioni con l'altro processo.

Per intercettare connessioni socket in entrata:

  1. Create un oggetto ServerSocket e associatelo a una porta locale

  2. Aggiungete listener di eventi per l'evento connect

  3. Chiamate il metodo listen()

  4. Rispondete all'evento connect che fornisce un oggetto Socket per ogni connessione in entrata

L'oggetto ServerSocket continua a rimanere in ascolto di nuove connessioni finché non chiamate il metodo close() .

Nell'esempio di codice seguente viene mostrato come creare un'applicazione server socket. L'esempio intercetta connessioni in entrata sulla porta 8087. Quando si riceve una connessione, l'esempio invia un messaggio (la stringa “Connesso.”) al socket client. In seguito, il server rimanda eventuali messaggi ricevuti al client.

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.IOErrorEvent; 
    import flash.events.ProgressEvent; 
    import flash.events.ServerSocketConnectEvent; 
    import flash.net.ServerSocket; 
    import flash.net.Socket; 
     
    public class ServerSocketExample extends Sprite 
    { 
        private var serverSocket:ServerSocket; 
        private var clientSockets:Array = new Array(); 
 
        public function ServerSocketExample() 
        { 
            try 
            { 
                // Create the server socket 
                serverSocket = new ServerSocket(); 
                 
                // Add the event listener 
                serverSocket.addEventListener( Event.CONNECT, connectHandler ); 
                serverSocket.addEventListener( Event.CLOSE, onClose ); 
                 
                // Bind to local port 8087 
                serverSocket.bind( 8087, "127.0.0.1" ); 
                 
                // Listen for connections 
                serverSocket.listen(); 
                trace( "Listening on " + serverSocket.localPort ); 
 
            } 
            catch(e:SecurityError) 
            { 
                trace(e); 
            } 
        } 
 
        public function connectHandler(event:ServerSocketConnectEvent):void 
        { 
            //The socket is provided by the event object 
            var socket:Socket = event.socket as Socket; 
            clientSockets.push( socket ); 
             
            socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler); 
            socket.addEventListener( Event.CLOSE, onClientClose ); 
            socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); 
             
            //Send a connect message 
            socket.writeUTFBytes("Connected."); 
            socket.flush(); 
             
            trace( "Sending connect message" ); 
        } 
         
        public function socketDataHandler(event:ProgressEvent):void 
        { 
            var socket:Socket = event.target as Socket 
                 
            //Read the message from the socket 
            var message:String = socket.readUTFBytes( socket.bytesAvailable ); 
            trace( "Received: " + message); 
 
            // Echo the received message back to the sender 
            message = "Echo -- " + message; 
            socket.writeUTFBytes( message ); 
            socket.flush(); 
            trace( "Sending: " + message ); 
        } 
         
        private function onClientClose( event:Event ):void 
        { 
            trace( "Connection to client closed." ); 
            //Should also remove from clientSockets array... 
        } 
 
        private function onIOError( errorEvent:IOErrorEvent ):void 
        { 
            trace( "IOError: " + errorEvent.text ); 
        } 
 
        private function onClose( event:Event ):void 
        { 
            trace( "Server socket closed by OS." ); 
        } 
}}

Per ulteriori informazioni, vedete:

Socket UDP (AIR)

Il protocollo UDP (Universal Datagram Protocol) fornisce un modo per scambiare messaggi su una connessione di rete senza stato. UDP non offre alcuna garanzia che i messaggi siano consegnati nell'ordine in cui sono stati ricevuti o che siano effettivamente consegnati. Con UDP, il codice di rete del sistema operativo è in genere meno occupato a eseguire il marshaling, il monitoraggio e il riconoscimento dei messaggi. Pertanto, i messaggi UDP in genere arrivano all'applicazione di destinazione con un ritardo inferiore rispetto ai messaggi TCP.

La comunicazione socket UDP è utile quando dovete inviare informazioni in tempo reale, ad esempio aggiornamenti di posizione in un gioco o pacchetti audio in un'applicazione chat audio. In tali applicazioni, una certa perdita di dati è accettabile e una bassa latenza di trasmissione è più importante di un arrivo garantito. Per quasi tutti gli altri scopi, i socket TCP sono una scelta migliore.

L'applicazione AIR può inviare e ricevere messaggi UDP con le classi DatagramSocket e DatagramSocketDataEvent. Per inviare e ricevere un messaggio UDP:

  1. Create un oggetto DatagramSocket

  2. Aggiungete un listener di eventi per l'evento data

  3. Associate il socket a un indirizzo IP e una porta locali utilizzando il metodo bind()

  4. Inviate messaggi chiamando il metodo send() , passando l'indirizzo IP e la porta del computer di destinazione

  5. Ricevete messaggi rispondendo dall'evento data . L'oggetto DatagramSocketDataEvent inviato per questo evento contiene un oggetto ByteArray contenente i dati del messaggio.

Nell'esempio di codice seguente viene mostrato come inviare e ricevere messaggi UDP. L'esempio invia un singolo messaggio contenente la stringa “Hello.” al computer di destinazione, inoltre traccia il contenuto dei messaggi ricevuti.

package 
{ 
import flash.display.Sprite; 
import flash.events.DatagramSocketDataEvent; 
import flash.events.Event; 
import flash.net.DatagramSocket; 
import flash.utils.ByteArray; 
 
public class DatagramSocketExample extends Sprite 
{ 
    private var datagramSocket:DatagramSocket; 
     
    //The IP and port for this computer 
    private var localIP:String = "192.168.0.1"; 
    private var localPort:int = 55555; 
     
    //The IP and port for the target computer 
    private var targetIP:String = "192.168.0.2"; 
    private var targetPort:int = 55555; 
     
    public function DatagramSocketExample() 
    { 
        //Create the socket 
        datagramSocket = new DatagramSocket(); 
        datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); 
         
        //Bind the socket to the local network interface and port 
        datagramSocket.bind( localPort, localIP ); 
         
        //Listen for incoming datagrams 
        datagramSocket.receive(); 
         
        //Create a message in a ByteArray 
        var data:ByteArray = new ByteArray(); 
        data.writeUTFBytes("Hello."); 
         
        //Send the datagram message 
        datagramSocket.send( data, 0, 0, targetIP, targetPort); 
    } 
     
    private function dataReceived( event:DatagramSocketDataEvent ):void 
    { 
        //Read the data from the datagram 
        trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + 
            event.data.readUTFBytes( event.data.bytesAvailable ) ); 
    } 
}}

Quando utilizzate i socket UDP, tenete presenti le considerazioni seguenti:

  • Un singolo pacchetto di dati non può essere più grande dell'MTU (maximum transmission unit) più piccola dell'interfaccia di rete o di qualsiasi nodo di rete tra il mittente e il destinatario. Tutti i dati nell'oggetto ByteArray passati al metodo send() vengono inviati come un pacchetto singolo. (In TCP, i messaggi di grandi dimensioni vengono suddivisi in pacchetti separati.)

  • Non c'é handshake tra il mittente e la destinazione. I messaggi vengono eliminati senza errore se la destinazione non esiste o non dispone di un listener attivo sulla porta specificata.

  • Quando utilizzate il metodo connect() , i messaggi inviati da altre origini vengono ignorati. Una connessione UDP fornisce solo filtraggio pacchetti pratico. Questo non significa che esiste necessariamente un processo di intercettamento valido in corrispondenza dell'indirizzo e della porta di destinazione.

  • Il traffico UDP può intasare una rete. Se si verifica una congestione di rete, gli amministratori di rete devono implementare controlli di qualità del servizio. (TCP è dotato di un controllo del traffico incorporato per ridurre l'impatto della congestione di rete.)

Per ulteriori informazioni, vedete:

Indirizzi IPv6

Flash Player 9.0.115.0 e versioni successive supportano IPv6 (Internet Protocol versione 6). IPv6 è una versione del protocollo Internet che supporta gli indirizzi a 128 bit (rappresenta un miglioramento rispetto al precedente protocollo IPv4 che supportava indirizzi a 32 bit). Potrebbe essere necessario attivare Ipv6 sulle interfacce di rete. Per maggiori informazioni, vedete la guida del sistema operativo sul quale si trovano i dati.

Se il sistema ospite supporta IPv6, potete specificare il valore letterale numerico IPv6 degli indirizzi posti tra parentesi quadre ([]), come nel seguente esempio:

[2001:db8:ccc3:ffff:0:444d:555e:666f]

Flash Player restituisce valori IPv6 letterali, in base alle seguenti regole:

  • Flash Player restituisce il formato esteso della stringa degli indirizzi IPv6.

  • Il valore IP non contiene abbreviazioni con doppio segno di due punti.

  • Le cifre esadecimali sono solo minuscole.

  • Gli indirizzi IPv6 sono racchiusi tra parentesi quadre ([]).

  • Ogni quartetto di indirizzo viene restituito come un numero di cifre esadecimali compreso tra 0 e 4, in cui gli zeri iniziali sono omessi.

  • Un quartetto di indirizzo di soli zeri viene restituito come un unico zero (non doppio segno di due punti) tranne come indicato nell'elenco di accezioni seguente.

I valori IPv6 restituiti da Flash Player contengono le eccezioni seguenti:

  • Un indirizzo IPv6 non specificato (tutti zero) viene restituito come [::].

  • L'indirizzo IPv6 loopback o localhost viene restituito come [::1].

  • Gli indirizzi mappati IPv4 (convertiti in IPv6) vengono restituiti come [::ffff:a.b.c.d], in cui a.b.c.d è un tipico valore decimale puntato IPv4.

  • Indirizzi compatibili IPv4 vengono restituiti come [::a.b.c.d], in cui a.b.c.d è un tipico valore decimale puntato IPv4.