Sockets

Flash Player 9 and later, Adobe AIR 1.0 and later

A socket is a type of network connection established between two computer processes. Typically, the processes are running on two different computers attached to the same Internet Protocol (IP) network. However, the connected processes can be running on the same computer using the special “local host” IP address.

Adobe Flash Player supports client-side Transport Control Protocol (TCP) sockets. A Flash Player application can connect to another process acting as a socket server, but cannot accept incoming connection requests from other processes. In other words, a Flash Player application can connect to a TCP server, but cannot serve as one.

The Flash Player API also includes the XMLSocket class. The XMLSocket class uses a Flash Player-specific protocol that allows you to exchange XML messages with a server that understands that protocol. The XMLSocket class was introduced in ActionScript 1 and is still supported to provide backward compatibility. In general, the Socket class should be used for new applications unless you are connecting to a server specifically created to communicate with Flash XMLSockets.

Adobe AIR adds several additional classes for socket-based network programming. AIR applications can act as TCP socket servers with the ServerSocket class and can connect to socket servers requiring SSL or TLS security with the SecureSocket class. AIR applications can also send and receive Universal Datagram Protocol (UDP) messages with the DatagramSocket class.

TCP sockets

The Transmission Control Protocol (TCP) provides a way to exchange messages over a persistent network connection. TCP guarantees that any messages sent arrive in the correct order (barring major network problems). TCP connections require a “client” and a “server.” Flash Player can create client sockets. Adobe AIR can, additionally, create server sockets.

The following ActionScript APIs provide TCP connections:

  • Socket — allows a client application to connect to a server. The Socket class cannot listen for incoming connections.

  • SecureSocket (AIR) — allows a client application to connect to a trusted server and engage in encrypted communications.

  • ServerSocket (AIR) — allows an application to listen for incoming connections and act as a server.

  • XMLSocket — allows a client application to connect to an XMLSocket server.

Binary client sockets

A binary socket connection is similar to an XML socket except that the client and server are not limited to exchanging XML messages. Instead, the connection can transfer data as binary information. Thus, you can connect to a wider range of services, including mail servers (POP3, SMTP, and IMAP), and news servers (NNTP).

Socket class

The Socket class enables you to make socket connections and to read and write raw binary data. The Socket class is useful for interoperating with servers that use binary protocols. By using binary socket connections, you can write code that interacts with several different Internet protocols, such as POP3, SMTP, IMAP, and NNTP. This interaction, in turn, enables your applications to connect to mail and news servers.

Flash Player can interface with a server by using the binary protocol of that server directly. Some servers use the big-endian byte order, and some use the little-endian byte order. Most servers on the Internet use the big-endian byte order because “network byte order” is big-endian. The little-endian byte order is popular because the Intel® x86 architecture uses it. You should use the endian byte order that matches the byte order of the server that is sending or receiving data. All operations that are performed by the IDataInput and IDataOutput interfaces, and the classes that implement those interfaces (ByteArray, Socket, and URLStream), are encoded by default in big-endian format; that is, with the most significant byte first. This default byte order was chosen to match Java and the official network byte order. To change whether big-endian or little-endian byte order is used, you can set the endian property to Endian.BIG_ENDIAN or Endian.LITTLE_ENDIAN .

The Socket class inherits all the methods defined by the IDataInput and IDataOutput interfaces (located in the flash.utils package). Those methods must be used to write to and read from the Socket.

For more information, see:

Secure client sockets (AIR)

You can use the SecureSocket class to connect to socket servers that use Secure Sockets Layer version 4 (SSLv4) or Transport Layer Security version 1 (TLSv1). A secure socket provides three benefits: server authentication, data integrity, and message confidentiality. The runtime authenticates a server using the server certificate and its relationship to the root or intermediate certificate authority certificates in the user’s trust store. The runtime relies on the cryptography algorithms used by the SSL and TLS protocol implementations to provide data integrity and message confidentiality.

When you connect to a server using the SecureSocket object, the runtime validates the server certificate using the certificate trust store. On Windows and Mac, the operating system provides the trust store. On Linux, the runtime provides its own trust store.

If the server certificate is not valid or not trusted, the runtime dispatches an ioError event. You can check the serverCertificateStatus property of the SecureSocket object to determine why validation failed. No provision is provided for communicating with a server that does not have a valid and trusted certificate.

The CertificateStatus class defines string constants that represent the possible validation results:

  • Expired—the certificate expiration date has passed.

  • Invalid—there are a number of reasons that a certificate can be invalid. For example, the certificate could have been altered, corrupted, or it could be the wrong type of certificate.

  • Invalid chain—one or more of the certificates in the server’s chain of certificates are invalid.

  • Principal mismatch—the host name of the server and the certificate common name do not match. In other words, the server is using the wrong certificate.

  • Revoked—the issuing certificate authority has revoked the certificate.

  • Trusted—the certificate is valid and trusted. A SecureSocket object can only connect to a server that uses a valid, trusted certificate.

  • Unknown—the SecureSocket object has not validated the certificate yet. The serverCertificateStatus property has this status value before you call connect() and before either a connect or an ioError event is dispatched.

  • Untrusted signers—the certificate does not “chain” to a trusted root certificate in the trust store of the client computer.

Communicating with a SecureSocket object requires a server that uses a secure protocol and has a valid, trusted certificate. In other respects, using a SecureSocket object is the same as using a Socket object.

The SecureSocket object is not supported on all platforms. Use the SecureSocket class isSupported property to test whether the runtime supports use of the SecureSocket object on the current client computer.

For more information, see:

XML sockets

An XML socket lets you create a connection to a remote server that remains open until explicitly closed. You can exchange string data, such as XML, between the server and client. A benefit of using an XML socket server is that the client does not need to explicitly request data. The server can send data without waiting for a request and can send data to every connected client connected.

In Flash Player, and in Adobe AIR content outside the application sandbox, XML socket connections require the presence of a socket policy file on the target server. For more information, see Website controls (policy files) and Connecting to sockets .

The XMLSocket class cannot tunnel through firewalls automatically because, unlike the Real-Time Messaging Protocol (RTMP), XMLSocket has no HTTP tunneling capability. If you need to use HTTP tunneling, consider using Flash Remoting or Flash Media Server (which supports RTMP) instead.

The following restrictions apply to how and where content in Flash Player or in an AIR application outside of the application security sandbox can use an XMLSocket object to connect to the server:

  • For content outside of the application security sandbox, the XMLSocket.connect() method can connect only to TCP port numbers greater than or equal to 1024. One consequence of this restriction is that the server daemons that communicate with the XMLSocket object must also be assigned to port numbers greater than or equal to 1024. Port numbers below 1024 are often used by system services such as FTP (21), Telnet (23), SMTP (25), HTTP (80), and POP3 (110), so XMLSocket objects are barred from these ports for security reasons. The port number restriction limits the possibility that these resources will be inappropriately accessed and abused.

  • For content outside of the application security sandbox, the XMLSocket.connect() method can connect only to computers in the same domain where the content resides. (This restriction is identical to the security rules for URLLoader.load() .) To connect to a server daemon running in a domain other than the one where the content resides, you can create a cross-domain policy file on the server that allows access from specific domains. For details on cross-domain policy files, see AIR security .

Note: Setting up a server to communicate with the XMLSocket object can be challenging. If your application does not require real-time interactivity, use the URLLoader class instead of the XMLSocket class.

You can use the XMLSocket.connect() and XMLSocket.send() methods of the XMLSocket class to transfer XML to and from a server over a socket connection. The XMLSocket.connect() method establishes a socket connection with a web server port. The XMLSocket.send() method passes an XML object to the server specified in the socket connection.

When you invoke the XMLSocket.connect() method, the application opens a TCP/IP connection to the server and keeps that connection open until one of the following occurs:

  • The XMLSocket.close() method of the XMLSocket class is called.

  • No more references to the XMLSocket object exist.

  • The connection is broken (for example, the modem disconnects).

Connecting to a server with the XMLSocket class

To create a socket connection, you must create a server-side application to wait for the socket connection request and send a response to the Flash Player or AIR application. This type of server-side application can be written in AIR or in another programming language such as Java, Python, or Perl. To use the XMLSocket class, the server computer must run a daemon that understands the simple protocol used by the XMLSocket class:

  • XML messages are sent over a full-duplex TCP/IP stream socket connection.

  • Each XML message is a complete XML document, terminated by a zero (0) byte.

  • An unlimited number of XML messages can be sent and received over a single XMLSocket connection.

Server sockets

Use the ServerSocket class to allow other processes to connect to your application using a Transport Control Protocol (TCP) socket. The connecting process can be running on the local computer or on another network-connected computer. When a ServerSocket object receives a connection request, it dispatches a connect event. The ServerSocketConnectEvent object dispatched with the event contains a Socket object. You can use this Socket object for subsequent communication with the other process.

To listen for incoming socket connections:

  1. Create a ServerSocket object and bind it to a local port

  2. Add event listeners for the connect event

  3. Call the listen() method

  4. Respond to the connect event, which provides a Socket object for each incoming connection

The ServerSocket object continues to listen for new connections until you call the close() method.

The following code example illustrates how to create a socket server application. The example listens for incoming connections on port 8087. When a connection is received, the example sends a message (the string “Connected.”) to the client socket. Thereafter, the server echoes any messages received back to the client.

<html> 
<head> 
<script src="AIRAliases.js"></script> 
<script language="javascript"> 
        var serverSocket; 
        var clientSockets = new Array(); 
        function startServer() 
        { 
            try 
            { 
                // Create the server socket 
                serverSocket = new air.ServerSocket(); 
                 
                // Add the event listener 
                serverSocket.addEventListener( air.Event.CONNECT, connectHandler ); 
                serverSocket.addEventListener( air.Event.CLOSE, onClose ); 
                 
                // Bind to local port 8087 
                serverSocket.bind( 8087, "127.0.0.1" ); 
                 
                // Listen for connections 
                serverSocket.listen(); 
                air.trace( "Listening on " + serverSocket.localPort ); 
            } 
            catch( e ) 
            { 
                air.trace( e ); 
            } 
        } 
        function connectHandler( event ) 
        { 
            //The socket is provided by the event object 
            var socket = event.socket; 
            clientSockets.push( socket ); 
             
            socket.addEventListener( air.ProgressEvent.SOCKET_DATA, socketDataHandler); 
            socket.addEventListener( air.Event.CLOSE, onClientClose ); 
            socket.addEventListener( air.IOErrorEvent.IO_ERROR, onIOError ); 
             
            //Send a connect message 
            socket.writeUTFBytes("Connected."); 
            socket.flush(); 
             
            air.trace( "Sending connect message" ); 
        } 
         
        function socketDataHandler( event ) 
        { 
            var socket = event.target 
                 
            //Read the message from the socket 
            var message = socket.readUTFBytes( socket.bytesAvailable ); 
            air.trace( "Received: " + message); 
            // Echo the received message back to the sender 
            message = "Echo -- " + message; 
            socket.writeUTFBytes( message ); 
            socket.flush(); 
            air.trace( "Sending: " + message ); 
        } 
         
        function onClientClose( event ) 
        { 
            air.trace( "Connection to client closed." ); 
            //Should also remove from clientSockets array... 
        } 
        function onIOError( errorEvent ) 
        { 
            air.trace( "IOError: " + errorEvent.text ); 
        } 
        function onClose( event ) 
        { 
            air.trace( "Server socket closed by OS." ); 
        } 
</script> 
</head> 
<body onload="startServer()"> 
</body> 
</html>

For more information, see:

UDP sockets (AIR)

The Universal Datagram Protocol (UDP) provides a way to exchange messages over a stateless network connection. UDP provides no guarantees that messages are delivered in order or even that messages are delivered at all. With UDP, the operating system’s network code usually spends less time marshaling, tracking, and acknowledging messages. Thus, UDP messages typically arrive at the destination application with a shorter delay than do TCP messages.

UDP socket communication is helpful when you must send real-time information such as position updates in a game, or sound packets in an audio chat application. In such applications, some data loss is acceptable, and low transmission latency is more important than guaranteed arrival. For almost all other purposes, TCP sockets are a better choice.

Your AIR application can send and receive UDP messages with the DatagramSocket and DatagramSocketDataEvent classes. To send or receive a UDP message:

  1. Create a DatagramSocket object

  2. Add an event listener for the data event

  3. Bind the socket to a local IP address and port using the bind() method

  4. Send messages by calling the send() method, passing in the IP address and port of the target computer

  5. Receive messages by responding to the data event. The DatagramSocketDataEvent object dispatched for this event contains a ByteArray object containing the message data.

The following code example illustrates how an application can send and receive UDP messages. The example sends a single message containing the string, “Hello.”, to the target computer. It also traces the contents of any messages received.

<html> 
<head> 
<script src="AIRAliases.js"></script> 
<script language="javascript"> 
    var datagramSocket; 
     
    //The IP and port for this computer 
    var localIP = "192.168.0.1"; 
    var localPort = 55555; 
     
    //The IP and port for the target computer 
    var targetIP = "192.168.0.2"; 
    var targetPort = 55555; 
     
    function createDatagramSocket() 
    { 
        //Create the socket 
        datagramSocket = new air.DatagramSocket(); 
        datagramSocket.addEventListener( air.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 = new air.ByteArray(); 
        data.writeUTFBytes("Hello."); 
         
        //Send the datagram message 
        datagramSocket.send( data, 0, 0, targetIP, targetPort); 
    } 
     
    function dataReceived( event ) 
    { 
        //Read the data from the datagram 
        air.trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + 
            event.data.readUTFBytes( event.data.bytesAvailable ) ); 
    } 
</script> 
</head> 
<body onload="createDatagramSocket()"> 
</body> 
</html>

Keep in mind the following considerations when using UDP sockets:

  • A single packet of data cannot be larger than the smallest maximum transmission unit (MTU) of the network interface or any network nodes between the sender and the recipient. All of the data in the ByteArray object passed to the send() method is sent as a single packet. (In TCP, large messages are broken up into separate packets.)

  • There is no handshaking between the sender and the target. Messages are discarded without error if the target does not exist or does not have an active listener at the specified port.

  • When you use the connect() method, messages sent from other sources are ignored. A UDP connection provides convenient packet filtering only. It does not mean that there is necessarily a valid, listening process at the target address and port.

  • UDP traffic can swamp a network. Network administrators might need to implement quality-of-service controls if network congestion occurs. (TCP has built-in traffic control to reduce the impact of network congestion.)

For more information, see:

IPv6 addresses

Flash Player 9.0.115.0 and later support IPv6 (Internet Protocol version 6). IPv6 is a version of Internet Protocol that supports 128-bit addresses (an improvement on the earlier IPv4 protocol that supports 32-bit addresses). You might need to activate IPv6 on your networking interfaces. For more information, see the Help for the operating system hosting the data.

If IPv6 is supported on the hosting system, you can specify numeric IPv6 literal addresses in URLs enclosed in brackets ([]), as in the following:

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

Flash Player returns literal IPv6 values, according to the following rules:

  • Flash Player returns the long form of the string for IPv6 addresses.

  • The IP value has no double-colon abbreviations.

  • Hexadecimal digits are lowercase only.

  • IPv6 addresses are enclosed in square brackets ([]).

  • Each address quartet is output as 0 to 4 hexadecimal digits, with the leading zeros omitted.

  • An address quartet of all zeros is output as a single zero (not a double colon) except as noted in the following list of exceptions.

The IPv6 values that Flash Player returns have the following exceptions:

  • An unspecified IPv6 address (all zeros) is output as [::].

  • The loopback or localhost IPv6 address is output as [::1].

  • IPv4 mapped (converted to IPv6) addresses are output as [::ffff:a.b.c.d], where a.b.c.d is a typical IPv4 dotted-decimal value.

  • IPv4 compatible addresses are output as [::a.b.c.d], where a.b.c.d is a typical IPv4 dotted-decimal value.

// Ethnio survey code removed