[ActionScript 3.0] 套接字

套接字

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

 
 

套接字是在两个计算机进程之间建立的一种网络连接类型。通常,这些进程在两台连接到相同 Internet 协议 (IP) 网络的不同计算机上运行。然而,连接的进程可以在使用特定“本地主机”IP 地址的同一台计算机上运行。

Adobe Flash Player 支持客户端传输控制协议 (TCP) 套接字。Flash Player 应用程序可以作为套接字服务器连接到其他进程,但是不能接受来自其他进程的传入连接请求。换句话说,Flash Player 应用程序可以连接到 TCP 服务器,但不能用作 TCP 服务器。

Flash Player API 也包含 XMLSocket 类。XMLSocket 类使用 Flash Player 特定的协议,通过该协议,您可以与识别该协议的服务器交换 XML 消息。ActionScript 1 中引入了 XMLSocket 类,该类现在仍然受支持以提供向后兼容性。通常,除非连接到特别创建以与 Flash XMLSocket 进行通信的服务器,否则 Socket 类应该用于新应用程序。

Adobe AIR 添加了多个用于基于套接字的网络编程的附加类。借助 ServerSocket 类,AIR 应用程序可以用作 TCP 套接字服务器,并可以连接到要求 SSL 或 TLS 安全的套接字服务器。AIR 应用程序还可以使用 DatagramSocket 类发送和接收通用数据报协议 (UDP) 消息。

TCP 套接字

通过传输控制协议 (TCP),可通过永久网络连接交换消息。TCP 可确保发送的任何消息都以正确的顺序到达,出现重大网络问题时除外。TCP 连接要求具有“客户端”和“服务器”。Flash Player 可以创建客户端套接字。此外,Adobe AIR 可以创建服务器套接字。

下列 ActionScript API 提供了 TCP 连接:

  • 套接字 — 允许客户端应用程序连接到服务器。Socket 类无法侦听传入连接。

  • SecureSocket (AIR) — 允许客户端应用程序连接到受信任服务器并进行加密通信。

  • ServerSocket (AIR) — 允许应用程序侦听传入连接并用作服务器。

  • XMLSocket — 允许客户端应用程序连接到 XMLSocket 服务器。

二进制客户端套接字

二进制套接字连接与 XML 套接字类似,不同的是客户端和服务器不局限于交换 XML 消息。该连接可以将数据作为二进制信息传输。因此,您可以连接到更加丰富的服务,包括邮件服务器(POP3、SMTP 和 IMAP)和新闻服务器 (NNTP)。

Socket 类

使用 Socket 类,您可以建立套接字连接以及读取和编写原始二进制数据。在与使用二进制协议的服务器进行交互操作时,Socket 类非常有用。使用二进制套接字连接,您可以编写与多个不同的 Internet 协议(例如 POP3、SMTP、IMAP 和 NNTP)进行交互的代码。这种交互进而又使您的应用程序可以连接到邮件服务器和新闻服务器。

Flash Player 可通过使用服务器的二进制协议直接与该服务器连接。某些服务器使用 big-endian 字节顺序,某些服务器则使用 little-endian 字节顺序。Internet 上的大多数服务器使用 big-endian 字节顺序,因为“网络字节顺序”为 big-endian。little-endian 字节顺序很常用,因为 Intel® x86 体系结构使用该字节顺序。您应使用与收发数据的服务器的字节顺序相匹配的 endian 字节顺序。默认情况下,IDataInput 和 IDataOutput 接口执行的所有操作和实现这些接口的类(ByteArray、Socket 和 URLStream)都以 big-endian 格式编码;即,最高有效字节位于前面。选择的这种默认字节顺序与 Java 和正式网络字节顺序匹配。要更改是使用 big-endian 还是使用 little-endian 字节顺序,可以将 endian 属性设置为 Endian.BIG_ENDIAN 或 Endian.LITTLE_ENDIAN

Socket 类继承了由 IDataInput 和 IDataOutput 接口定义的所有方法(位于 flash.utils 包中)。必须使用这些方法写入和读取套接字。

有关详细信息,请参阅:

安全客户端套接字 (AIR)

您可以使用 SecureSocket 类连接到使用第 4 版安全套接字层 (SSLv4) 或第 1 版传输层安全性 (TLSv1) 的套接字服务器。安全套接字提供了三大优势:服务器身份验证、数据完整性和消息机密性。运行时使用服务器证书及其在用户信任存储区中授权机构颁发的根证书或中级证书的相关性对服务器进行身份验证。运行时依靠 SSL 和 TLS 协议实现所使用的加密算法提供数据完整性和消息机密性。

当您使用 SecureSocket 对象连接到服务器时,运行时将使用证书信任存储区验证服务器证书。在 Windows 和 Mac 上,操作系统提供信任存储区。在 Linux 中,运行时自行提供信任存储区。

如果服务器证书无效或不可信,运行时将调度 ioError 事件。您可以检查 SecureSocket 对象的 serverCertificateStatus 属性来确定验证失败的原因。没有为与不具备有效和可信证书的服务器进行通信提供任何设置。

CertificateStatus 类用于定义表示可能的验证结果的字符串常量:

  • 过期 — 已超过证书过期日期。

  • 无效 — 多种原因可导致证书无效。例如,证书可能已更改、损坏,或者是错误类型的证书。

  • 无效链 — 证书的服务器链中有一个或多个证书无效。

  • 主体不匹配 — 服务器的主机名与证书公用名不匹配。换句话说,服务器使用的是错误的证书。

  • 吊销 — 证书颁发机构已吊销该证书。

  • 受信任 — 证书有效且受信任。SecureSocket 对象仅可以连接到使用有效的受信任证书的服务器。

  • 未知 — SecureSocket 对象尚未验证证书。serverCertificateStatus 属性在您调用 connect() 和调度 connect 或 ioError 事件之前具有此状态值。

  • 不受信任的签名者 — 证书不能“链接”到客户端计算机的信任存储区中的受信任根证书。

与 SecureSocket 对象通信要求服务器使用安全协议,并包含有效的受信任证书。在其他方面,使用 SecureSocket 对象与使用 Socket 对象是相同的。

并不是所有平台都支持 SecureSocket 对象。使用 SecureSocket 类 isSupported 属性测试运行时是否支持在当前客户端计算机上使用 SecureSocket 对象。

有关详细信息,请参阅:

TCP 套接字示例:构建 Telnet 客户端

Telnet 示例说明了使用 Socket 类连接远程服务器和传输数据的方法。该示例演示下列方法:

  • 使用 Socket 类创建自定义 telnet 客户端

  • 使用 ByteArray 对象将文本发送到远程服务器

  • 处理从远程服务器收到的数据

若要获取此范例的应用程序文件,请参阅 www.adobe.com/go/learn_programmingAS3samples_flash_cn。可以在 Samples/Telnet 文件夹中找到 Telnet 应用程序文件。该应用程序包含以下文件:

文件

说明

TelnetSocket.fla

TelnetSocket.mxml

由用户界面组成的 Flex 或 Flash 的主应用程序文件(分别为 MXML 和 FLA 格式)。

TelnetSocket.as

用于提供用户界面逻辑的文档类(仅限 Flash)。

com/example/programmingas3/Telnet/Telnet.as

为应用程序提供 Telnet 客户端功能,例如连接到远程服务器以及发送、接收和显示数据。

Telnet 套接字应用程序概述

主 TelnetSocket.mxml 文件负责为整个应用程序创建用户界面 (UI)。

除了 UI,此文件还定义两个方法 login() 和 sendCommand(),以便将用户连接到指定的服务器。

下面的代码列出了主应用程序文件中的 ActionScript:

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 = ""; 
}

第一行代码从自定义 com.example.programmingas.socket 包中导入 Telnet 类。第二行代码声明 Telnet 类的实例 telnetClient,稍后由 connect() 方法初始化该实例。接下来,声明 connect() 方法,该方法初始化先前声明的 telnetClient 变量。此方法传递用户指定的 telnet 服务器名称、telnet 服务器端口和对显示列表中 TextArea 组件的引用,其中,显示列表用于显示来自套接字服务器的文本响应。connect() 方法的最后两行设置 Panel 的 title 属性并启用 Panel 组件,该组件允许用户将数据发送到远程服务器。主应用程序文件中的最后一个方法 sendCommand() 用于将用户的命令作为 ByteArray 对象发送到远程服务器。

Telnet 类概述

Telnet 类负责连接到远程 Telnet 服务器和发送/接收数据。

Telnet 类声明下列私有变量:

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

第一个变量 serverURL 包含要连接到的用户指定的服务器地址。

第二个变量 portNumber 是 Telnet 服务器当前在其上运行的端口号。默认情况下,Telnet 服务在端口 23 上运行。

第三个变量 socket 是一个 Socket 实例,该实例尝试连接到 serverURL 和 portNumber 变量定义的服务器。

第四个变量 ta 是对舞台上的 TextArea 组件实例的引用。此组件用于显示来自远程 Telnet 服务器的响应或者任何可能的错误消息。

最后一个变量 state 是数值,用于确定 Telnet 客户端支持哪些选项。

正如您之前所见,Telnet 类的构造函数由主应用程序文件中的 connect() 方法调用。

Telnet 构造函数采用三个参数:serverport 和 outputserver 和 port 参数指定 Telnet 服务器在其上运行的服务器名称和端口号。最后一个参数 output 是对舞台上的 TextArea 组件实例的引用,在该舞台上将为用户显示服务器输出。

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(); 
    } 
}
向套接字写入数据

要将数据写入套接字连接,可以调用 Socket 类中的任何写入方法。这些写入方法包括 writeBoolean()writeByte()writeBytes()writeDouble() 及其他方法。然后,使用 flush() 方法刷新输出缓冲区中的数据。在 Telnet 服务器中,使用 writeBytes() 方法向套接字连接中写入数据,该方法将字节数组作为参数,并将其发送到输出缓冲区。writeBytesToSocket() 方法如下:

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

此方法是由主应用程序文件中的 sendCommand() 方法调用的。

显示来自套接字服务器的消息

当从套接字服务器接收消息,或者发生事件时,将调用自定义 msg() 方法。此方法将字符串追加到舞台上的 TextArea 并调用自定义 setScroll() 方法,该方法使 TextArea 组件滚动到底部。msg() 方法如下:

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

如果您未将 TextArea 组件的内容设置为自动滚动,则用户需要手动拖动文本区域中的滚动条才能看到来自服务器的最新响应。

滚动 TextArea 组件

setScroll() 方法包含一行 ActionScript,用于垂直滚动 TextArea 组件内容,以便用户可以查看返回文本的最后一行。下面的片断显示了 setScroll() 方法:

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

此方法设置 verticalScrollPosition 属性(该属性是当前显示的最上面一行字符的行号),并将其设置为 maxVerticalScrollPosition 属性的值。

XML 套接字

通过 XML 套接字,可以创建与远程服务器的连接,且该服务器在明确关闭之前始终保持打开状态。您可以在服务器和客户端之间交换字符串数据,如 XML。使用 XML 套接字服务器的优点之一是客户端不需要明确请求数据。服务器无需等待请求即可发送数据,并且可以将数据发送到每个已连接的客户端。

在应用程序沙箱外的 Flash Player 和 Adobe AIR 内容中,XML 套接字连接要求在目标服务器上提供套接字策略文件。有关详细信息,请参阅网站控制(策略文件)连接到套接字

XMLSocket 类不能自动穿过防火墙,因为 XMLSocket 没有 HTTP 隧道功能(这与实时消息传递协议 (RTMP) 不同)。如果您需要使用 HTTP 隧道,应考虑改用 Flash Remoting 或 Flash Media Server(支持 RTMP)。

对于应用程序安全沙箱外的 Flash Player 或 AIR 应用程序中的内容使用 XMLSocket 对象连接到服务器的方式及位置,规定了下列限制:

  • 对于应用程序安全沙箱外部的内容,XMLSocket.connect() 方法只能连接到端口号大于或等于 1024 的 TCP 端口。这种限制所带来的后果之一是,向与 XMLSocket 对象通信的服务器守护程序分配的端口号也必须大于等于 1024。端口号小于 1024 的端口通常用于系统服务,例如 FTP (21)、Telnet (23)、SMTP (25)、HTTP (80) 和 POP3 (110),因此,出于安全方面的考虑,禁止 XMLSocket 对象使用这些端口。这种端口号方面的限制可以减少不恰当地访问和滥用这些资源的可能性。

  • 对于应用程序安全沙箱外部的内容,XMLSocket.connect() 方法只能连接到该内容所在的同一域中的计算机。(此限制与 URLLoader.load() 的安全规则相同。)若要连接到在内容所在域之外的其他域中运行的服务器守护程序,可以在该服务器上创建一个允许从特定域进行访问的跨域策略文件。有关跨域策略文件的详细信息,请参阅 AIR 安全性

注: 将服务器设置为与 XMLSocket 对象进行通信可能会遇到一些困难。如果您的应用程序不需要进行实时交互,请使用 URLLoader 类,而不要使用 XMLSocket 类。

可以使用 XMLSocket 类的 XMLSocket.connect() 和 XMLSocket.send() 方法,通过套接字连接与服务器之间传输 XML。XMLSocket.connect() 方法与 Web 服务器端口建立套接字连接。XMLSocket.send() 方法将 XML 对象传递给套接字连接中指定的服务器。

当调用 XMLSocket.connect() 方法时,应用程序会打开到服务器的 TCP/IP 连接并使该连接保持打开状态,直到出现下列情况之一:

  • XMLSocket 类的 XMLSocket.close() 方法被调用。

  • 对 XMLSocket 对象的引用不再存在。

  • Flash Player 退出。

  • 连接中断(例如,调制解调器断开连接)。

使用 XMLSocket 类连接到服务器

要创建套接字连接,必须创建服务器端应用程序以等待套接字连接请求,并将响应发送到 Flash Player 或 AIR 应用程序。此类服务器端应用程序可使用 AIR 或其他编程语言(如 Java、Python 或 Perl)编写。要使用 XMLSocket 类,服务器计算机必须运行可识别 XMLSocket 类使用的简单协议的守护程序:

  • XML 消息通过全双工 TCP/IP 流套接字连接发送。

  • 每个 XML 消息都是一个完整的 XML 文档,以一个零 (0) 字节结束。

  • 通过 XMLSocket 连接发送和接收的 XML 消息的数量没有限制。

创建并连接到 Java XML 套接字服务器

下面的代码演示了一个用 Java 编写的简单 XMLSocket 服务器,该服务器接受传入连接并在命令提示窗口中显示接收到的消息。虽然从命令行启动服务器时可以指定其他端口号,但默认情况下,在本地计算机上的 8080 端口创建新服务器。

新建一个文本文档并添加下面的代码:

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); 
    } 
}

将文档保存到硬盘,命名为 SimpleServer.java 并使用 Java 编译器对其进行编译,这会创建一个名为 SimpleServer.class 的 Java 类文件。

您可以通过打开命令提示并键入 java SimpleServer 来启动 XMLSocket 服务器。SimpleServer.class 文件可以位于本地计算机或网络上的任何位置,不需要放置在 Web 服务器的根目录中。

如果由于文件没有位于 Java 类路径中而无法启动服务器,请尝试使用 java -classpath .SimpleServer 启动服务器。

要从应用程序连接到 XMLSocket,需要新建一个 XMLSocket 类实例,并在传递主机名和端口号时调用 XMLSocket.connect() 方法,如下所示:

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

只要从服务器接收数据,就会调度 data 事件 (flash.events.DataEvent.DATA):

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

若要将数据发送到 XMLSocket 服务器,可以使用 XMLSocket.send() 方法并传递 XML 对象或字符串。Flash Player 将提供的参数转换为 String 对象,并将内容发送到 XMLSocket 服务器(后跟零 (0) 字节):

xmlsock.send(xmlFormattedData);

XMLSocket.send() 方法不返回指示数据是否成功传输的值。如果尝试发送数据时发生错误,将引发 IOError 错误。

发送到 XML 套接字服务器的每条消息必须以换行符 (\n) 结束。

有关详细信息,请参阅 XMLSocket

服务器套接字

使用 ServerSocket 类可以允许其他进程使用传输控制协议 (TCP) 套接字连接到您的应用程序。可以在本地计算机或另一台网络连接的计算机上运行连接进程。当 ServerSocket 对象收到连接请求时,会调度 connect 事件。该事件调度的 ServerSocketConnectEvent 对象包含 Socket 对象。您可以使用此 Socket 对象与其他进程进行后续通信。

要侦听传入的套接字连接,请执行以下操作:

  1. 创建一个 ServerSocket 对象并将其绑定到本地端口

  2. 为 connect 事件添加事件侦听器

  3. 调用 listen() 方法

  4. 响应 connect 事件,它为每个传入连接提供 Socket 对象

ServerSocket 对象在您调用 close() 方法之前会继续侦听新连接。

以下代码示例说明了如何创建套接字服务器应用程序。该示例侦听端口 8087 上的传入连接。收到连接时,此示例会将消息(字符串“Connected”)发送给客户端套接字。此后,服务器会将任何收到的消息回显给客户端。

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." ); 
        } 
}}

有关详细信息,请参阅:

UDP 套接字 (AIR)

通用数据报协议 (UDP) 提供了一种通过无状态网络连接交换消息的方法。UDP 无法确保消息按顺序传送,甚至无法确保消息的传送。使用 UDP,操作系统的网络代码通常在封送、跟踪和确认消息上将花费更少的时间。因此,通常 UDP 消息到达目标应用程序的延迟比 TCP 消息到达目标应用程序的延迟要短。

在必须发送实时信息(例如游戏中的位置更新或音频聊天应用程序中的声音数据包)时,UDP 套接字通信很有用。在此类应用程序中,丢失一些数据是可以接受的,并且低传输延迟比保证及时到达更重要。对于几乎所有其他目的,TCP 套接字是更好的选择。

AIR 应用程序可以使用 DatagramSocket 和 DatagramSocketDataEvent 类发送和接收 UDP 消息。要发送或接收 UDP 消息,请执行以下操作:

  1. 创建一个 DatagramSocket 对象

  2. 为 data 事件添加事件侦听器

  3. 使用 bind() 方法将套接字绑定到本地 IP 地址和端口

  4. 通过调用 send() 方法发送消息,传递目标计算机的 IP 地址和端口

  5. 通过响应 data 事件接收消息。为此事件调度的 DatagramSocketDataEvent 对象包含一个 ByteArray 对象,该对象中包含消息数据。

以下代码示例说明应用程序如何发送和接收 UDP 消息。此示例将包含字符串“Hello”的单一消息发送到目标计算机。它还跟踪接收的任何消息内容。

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 ) ); 
    } 
}}

使用 UDP 套接字时,请记住下列注意事项:

  • 单一数据包不能大于网络接口或发送方和接收方之间任何网络节点的最大传输单位 (MTU) 中最小的那一个。传递到 send() 方法的 ByteArray 对象中的所有数据都将作为单一数据包发送。(在 TCP 中,较大的消息被分为几个单独的包。)

  • 发送方和目标之间不存在信号交换。如果目标不存在或指定端口上没有活动侦听器,则会丢弃消息且不会报错。

  • 使用 connect() 方法时,将忽略从其他源发送的消息。UDP 连接仅提供方便的数据包过滤。这并不意味着目标地址和端口上必须存在有效的侦听进程。

  • UDP 流量可以造成网络拥塞。如果发生网络拥塞,网络管理员可能需要实现服务质量控制。(TCP 有内置的流量控制来减少网络拥塞的影响。)

有关详细信息,请参阅:

IPv6 地址

Flash Player 9.0.115.0 及更高版本支持 IPv6(Internet 协议版本 6)。IPv6 是支持 128 位地址的 Internet 协议版本(它是支持 32 位地址的早期 IPv4 协议的改进版本)。 您可能需要在网络接口中激活 IPv6。 有关详细信息,请参阅承载数据的操作系统的帮助。

如果承载系统中支持 IPv6,您可以在用中括号 ([]) 括起的 URL 中指定数字 IPv6 文本地址,如下所示:

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

Flash Player 根据以下规则返回 IPv6 字面值:

  • Flash Player 返回长形式的 IPv6 地址字符串。

  • IP 值没有双冒号缩写词。

  • 十六进制数字全小写。

  • IPv6 地址包含在中括号 ([]) 中。

  • 每个四重地址都输出为 0 到 4 个十六进制数字(省略前导零)。

  • 内容全为零的四重地址输出为单个零(而不是双冒号),下表所列例外情况除外。

Flash Player 返回的 IPv6 值具有以下例外:

  • 未指定的 IPv6 地址(内容全为零)输出为 [::]。

  • 环回或本地主机 IPv6 地址输出为 [::1]。

  • IPv4 映射(转换为 IPv6)地址输出为 [::ffff:a.b.c.d],其中 a.b.c.d 为典型的 IPv4 点分十进制值。

  • IPv4 兼容地址输出为 [::a.b.c.d],其中 a.b.c.d 为典型的 IPv4 点分十进制值。

 
   
 
          
posted on 2020-07-04 09:09  晏过留痕  阅读(391)  评论(0编辑  收藏  举报