昨天做测试的时候遇到一个问题,做好的SWF在Flash AS3中调试通过,但是发布到html中之后就无法得到数据了。查了一些资料之后找到了解决办法。这里感谢 剑心 提供帮助,以及同事若水三千提供Java代码及日志记录。

1、问题描述

将flash发布为html格式后,加载页面后,swf无法与服务器进行socket通信。Flash端显示的错误为:
securityErrorHandler信息: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]

在服务器端显示的信息是由客户端尝试进行连接,但是无法接受数据。接受的数据显示为空。

2.问题原因:

最新的Flash player 9.0.124.0,当flash文件要进行socket通信的时候,需要向服务器端获取crossdomain.xml文件。如果找不到就出现客户端无法连接服务器的现象。

了解flash发起socket通信的三个过程

当封装在页面的flash发起socket通信请求的时候会先寻找服务器端的843端口,获取Crossdomain.xml文件,当服务器没有开启 843的时候,flashPlayer会检查发起请求的swf文件中中有没有使用Security.loadPolicyFile来加载策略文件 Crossdomain.xml,如果还是没有就会看这个发起请求的swf要连接的目标端口有没有策略文件。如果都没有那么连接失败,返回如上的出错提示。

为什么老版本的Flash player没有这个问题?

      从一些官方的一些资料中了解了一下。以前的Flash Player无论你采用urlRequest的http请求方式或者xmlsocket socket方式,他们都共用一个安全策略文件。这个策略文件只要你放在主域的目录下就行了。而现在不行了,现在的策略文件如果你使用http请求方式那么需要把策略文件放在目录下面,如果你使用socket请求方式就必须通过socket端口来接收这个策略文件。

对应调用的方式为:
      http请求——》Security.loadPolicyFile(“http://www.xxx.com/crossdomain.xml”)
      socket或xmlsocket请求——》Security.loadPolicyFile(“xmlsocket://www.xxx.com:port”)

怎么将Socke策略文件发给Flash Player

Flash Player在你的socket.connect("domain",port)运行之前,会按照前面描述的三个过程向你的socket服务器的843端口(据说Adobe已经向相关管理机构申请保留843端口给Flash Player用)发送一个字符串 "<policy-file-request/>",这个时候如果你有一个服务在监听843端口那么收到这个字符串之后,直接按照XML格式发回策略文件就解决了。(注意发回的时候记得加一个截止字符"\0")

当然你也可以不用843端口自己设置一个端口。因为Flash Player如果在843端口得不到信息,就会检查你是否在你的Flash文件里面自己添加了指定的获取通道,你可以定义一个自己的端口。不过这个时候你不能用http方式,而要用xmlsocket方式。(相当于自动帮你新建了一个xmlsocket对象,然后链接你指定的主机和端口)。比如你想用 1234端口可以在你的Flash里面加这一句 Security.loadPolicyFile(“xmlsocket://www.xxx.com:1234”),需要注意的是这一句要加在你的 socket.connect前面。

还有最后一个办法,就是在你的socket连接端口监听这个请求。比如你用的是 socket.connect("192.168.1.100",8888),那么在你的服务器加一段接收字符串"<policy-file- request/>"的代码,当接到这个字符串时将策略文家按照xml格式发到客户端。

关于策略文件的格式(可以在Flash CS3帮助里面的Flash Player安全性——》控制权限概述中找到)

1、针对web应用的策略文件

下面的示例显示了一个策略文件,该文件允许访问源自 *.iflashigame.com 和 192.0.34.166 的 SWF 文件。

  1. <?xml version="1.0"?>
  2. <cross-domain-policy>
  3. <allow-access-from domain="*.iflashigame.com" />
  4. <allow-access-from domain="192.0.34.166" />
  5. </cross-domain-policy>

注意事项:
      默认情况下,策略文件必须命名为 crossdomain.xml,并且必须位于服务器的根目录中。但是,SWF 文件可以通过调用 Security.loadPolicyFile() 方法检查是否为其它名称或位于其它目录中。跨域策略文件仅适用于从其中加载该文件的目录及其子目录。因此,根目录中的策略文件适用于整个服务器,但是从任意子目录加载的策略文件仅适用于该目录及其子目录。

策略文件仅影响对其所在特定服务器的访问。例如,位于https://www.adobe.com:8080/crossdomain.xml 的策略文件只适用于在端口 8080 通过 HTTPS 对www.adobe.com 进行的数据加载调用。

2、针对Socket的策略文件

  1. <cross-domain-policy>
  2. <allow-access-from domain="*" to-ports="507" />
  3. <allow-access-from domain="*.example.com" to-ports="507,516" />
  4. <allow-access-from domain="*.example2.com" to-ports="516-523" />
  5. <allow-access-from domain="www.example2.com " to-ports="507,516-523" />
  6. <allow-access-from domain="www.example3.com " to-ports="*" />
  7. </cross-domain-policy>

这个策略文件是指定允许哪些域的主机通过那些端口链接。

参考文章

flash xmlsocket policy 问题 
Policy file changes in Flash Player 9 
Setting up a socket policy file server 
Understanding Flash Player 9 April 2008 Security Update compatibility 
Flash Player升级到9.0.124后,Flex Socket安全策略更改及处理例子

获取策略文件的Java服务器端代码

    1. import java.io.BufferedReader;
    2. import java.io.BufferedWriter;
    3. import java.io.IOException;
    4. import java.io.InputStreamReader;
    5. import java.io.OutputStreamWriter;
    6. import java.net.ServerSocket;
    7. import java.net.Socket;
    8. public class SecurityXMLServer implements Runnable {
    9. private ServerSocket server;
    10. private BufferedReader reader;
    11. private BufferedWriter writer;
    12. private String xml;
    13. public SecurityXMLServer()
    14. {
    15. String path = "policyfile文件路径";
    16. //此处的换成相应的读取xml文档的方式如dom或sax
    17. //xml = readFile(path, "UTF-8");
    18. /**
    19. 注意此处xml文件的内容,为纯字符串,没有xml文档的版本号
    20. */
    21. xml="<cross-domain-policy> "
    22. +"<allow-access-from domain=\"*\" to-ports=\"1025-9999\"/>"
    23. +"</cross-domain-policy> ";
    24. System.out.println("policyfile文件路径: " + path);
    25. System.out.println(xml);
    26. //启动843端口
    27. createServerSocket(843);
    28. new Thread(this).start();
    29. }
    30. //启动服务器
    31. private void createServerSocket(int port)
    32. {
    33. try {
    34. server = new ServerSocket(port);
    35. System.out.println("服务监听端口:" + port);
    36. } catch (IOException e) {
    37. System.exit(1);
    38. }
    39. }
    40. //启动服务器线程
    41. public void run()
    42. {
    43. while (true) {
    44. Socket client = null;
    45. try {
    46. //接收客户端的连接
    47. client = server.accept();
    48. InputStreamReader input = new InputStreamReader(client.getInputStream(), "UTF-8");
    49. reader = new BufferedReader(input);
    50. OutputStreamWriter output = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
    51. writer = new BufferedWriter(output);
    52. //读取客户端发送的数据
    53. StringBuilder data = new StringBuilder();
    54. int c = 0;
    55. while ((c = reader.read()) != -1)
    56. {
    57. if (c != '\0')
    58. data.append((char) c);
    59. else
    60. break;
    61. }
    62. String info = data.toString();
    63. System.out.println("输入的请求: " + info);
    64. //接收到客户端的请求之后,将策略文件发送出去
    65. if(info.indexOf("<policy-file-request/>") >=0)
    66. {
    67. writer.write(xml + "\0");
    68. writer.flush();
    69. System.out.println("将安全策略文件发送至: " + client.getInetAddress());
    70. }
    71. else
    72. {
    73. writer.write("请求无法识别\0");
    74. writer.flush();
    75. System.out.println("请求无法识别: "+client.getInetAddress());
    76. }
    77. client.close();
    78. } catch (Exception e) {
    79. e.printStackTrace();
    80. try {
    81. //发现异常关闭连接
    82. if (client != null) {
    83. client.close();
    84. client = null;
    85. }
    86. } catch (IOException ex) {
    87. ex.printStackTrace();
    88. } finally {
    89. //调用垃圾收集方法
    90. System.gc();
    91. }
    92. }
    93. }
    94. }
    95. //测试主函数
    96. public static void main(String[] args)
    97. {
    98. new SecurityXMLServer();
    99. }
    100. }

[转]Flash Socket通信的安全策略的更多相关文章

  1. Flash Socket通信的安全策略问题 843端口

    1.问题描述       将flash发布为html格式后,加载页面后,swf无法与服务器进行socket通信.Flash端显示的错误为:securityErrorHandler信息: [Securi ...

  2. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  3. flex与C# Socket通信

    原文地址:http://blog.csdn.net/LX10752p/archive/2011/04/27/6366526.aspx Socket 通信没什么好说,一个服务端,多个客户端,很容易搭建环 ...

  4. Unity3d socket通信 切换到web版本时报错SecurityException解决办法

    原文地址:传送门 今天苦战了一天,就跟一个Unity切换到web平台的socket通信出错苦苦纠缠了一天,问了好多大牛,但他们的回复都是我没搞过web平台下的通信或者我只专研于pc或者移动平台.看来没 ...

  5. [转]浅谈Flash Socket通信安全沙箱

    用过Flash socket的同学都知道,Flash socket通讯有安全沙箱问题.就是在Flash Player发起socket通信时,会向服务端获取安全策略,如果得不到服务端响应,flash将无 ...

  6. Flash Socket简单调试工具

    写了一个简单的Flash Socket调试工具,可用来简单调试本地或者外部socket服务器,使用的时候注意Flash socket的安全策略问题,有问题请联系sky-wang@qq.com.

  7. 轮询、长轮询、长连接、flash socket 的区别

    轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源. 实例:适于小型应用. 长轮询:客 ...

  8. 我看不下去鸟。。。。Java和C#的socket通信真的简单吗?

    这几天在博客园上看到好几个写Java和C#的socket通信的帖子.但是都为指出其中关键点. C# socket通信组件有很多,在vs 使用nuget搜索socket组件有很多类似的.本人使用的是自己 ...

  9. php简单实现socket通信

    socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究一下在php里面如何实现sock ...

随机推荐

  1. 通过案例对 spark streaming 透彻理解三板斧之二:spark streaming运行机制

    本期内容: 1. Spark Streaming架构 2. Spark Streaming运行机制 Spark大数据分析框架的核心部件: spark Core.spark  Streaming流计算. ...

  2. 如何防止ElasticSearch集群出现脑裂现象(转)

    原文:http://xingxiudong.com/2015/01/05/resolve-elasticsearch-split-brain/ 什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络 ...

  3. Delphi调用REST

    Delphi调用REST很简单,首先在界面上放上: RESTClient1: TRESTClient; RESTRequest1: TRESTRequest; RESTResponse1: TREST ...

  4. Excel 数值转换为人民币大写金额字符串

    把$B$27单元格中的数值转换为人民币大写金额字符串: 目标单元格填入以下公式: =IF($B$27=0,CONCATENATE(IF($B$27<=0,,TEXT(INT($B$27),&qu ...

  5. rtsp 协议 详细讲解

    转载自:http://www.mikewootc.com/wiki/net/protocol/rtsp.html 目录: 概述 RTSP简介 协议特点 协议细节 典型的rtsp交互过程 RTSP消息格 ...

  6. Java多线程断点下载

    public static class DownloadThread extends Thread{ private int threadId; private int startIndex; pri ...

  7. C# 命令绑定

    在构建WinForm程序中,为了使系统的结构清晰,有好的用户交互体验,实现不同按钮之间的交互,不使主窗体里面的代码臃肿.将按钮的命令通过类进行绑定,实现命令的管理使很有必要的. 该文章是将如何实现Bu ...

  8. POJ 3281 Dining

    Dining Description Cows are such finicky eaters. Each cow has a preference for certain foods and dri ...

  9. WPF中设置快捷键

    方式1: 窗体中加入资源 <UserControl.Resources>        <RoutedUICommand x:Key="Cut" Text=&qu ...

  10. oracle备忘

    一.explain plan a)explain plan for select ... select * from table(dbms_xplan.display()); function dis ...