为什么 Flash Player 在这种情况下会抛出沙盒错误?

Why does the Flash Player throw a sandbox error in this case?

提问人:Simon 提问时间:11/11/2009 最后编辑:Simon 更新时间:12/8/2009 访问量:5337

问:

连接到 Java (1.5) 服务器上的套接字后,我收到 Flex 3 沙盒错误 #2048。服务器代码都是我的,即不在Apache下运行。Flash Player 10.0 版本32。

顺序如下...

1 Java 服务器启动,在端口 843 上侦听策略文件请求,在端口 45455 上侦听我的其他请求。

2 Apache提供的Flex客户端(尽管如果我从文件系统运行它,我会得到相同的结果),套接字连接在host:45455上建立。

3 Flash Player 从端口 843 请求策略文件。这是查找主文件的新安全设置的标准行为。无论是否指定了其他策略文件,都会发生这种情况。

4 我通过端口 843 从 Java 提供以下 XML:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
</cross-domain-policy>

5 播放器将以下内容写入调试策略日志...

OK: Root-level SWF loaded: http://localhost/bst/BasicSocketTest.swf
OK: Searching for <allow-access-from> in policy files to authorize data loading from resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf
OK: Policy file accepted: xmlsocket://192.168.2.3:843
OK: Request for resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf is permitted due to policy file at xmlsocket://192.168.2.3:843

6 我使用 和 从客户端向端口 45455 上的服务器发送一条短信(这是我自己烘焙的消息协议,并且在每一端都正确处理)writeUTFBytes()flush()

REG/REGISTER;simon;Si

7 侦听端口 45455 的 Java 服务器线程响应

REG:0/REGISTER:SUCCESS;simon;Si

8 Flex 客户端接收到 ProgressEvent,并调用我绑定到套接字的事件侦听器。我处理消息(将其写入屏幕上的文本框)

9 Flash 播放器抛出 2048 沙盒错误,套接字断开连接!这是在成功接收和处理消息之后。事实上,它大约是 12 秒后。没有其他东西可以通过插座工作。

我尝试在 Flex 客户端中显式加载带有调用的策略文件,但新播放器安全性的现实是它基本上被忽略了。步骤是,在发生套接字 I/O 操作之前,不会发送策略请求。此时,玩家总是首先转到端口 843 寻找主策略文件。如果它找到了一个,而且它是宽容的,它就不会再进一步了。Security.loadPolicyFile()

我尝试了各种终止策略文件和策略文件内容的替代方法,包括故意出错只是为了查看 Flash Player 是否处于唤醒状态。

我看不出为什么我会扔一个 2048。我准确地在指定的主安全端口上提供套接字策略文件,播放器本身将其记录为正确。然后,套接字成功发送和接收来自服务器的消息,其内容可供我的代码使用。

有没有人知道为什么会发生这种情况?Flash Player 错误?

P.S. 请不要告诉我使用 BlazeDS 或 LCDS 或 Granite 或其他东西作为服务器,我正在寻找解决这个问题的方法,而不是重新设计。请不要要求我改用 XMLSocket - 我试过了,得到了完全相同的结果。我仔细而深思熟虑地选择了我的架构,我想要一个二进制套接字。

编辑为了回应詹姆斯·沃德(James Ward)在评论中的请求,以下是整个错误消息:

Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

我有一个精简的测试客户端,它有一个用于每个套接字事件的处理程序,并将一条消息输出到屏幕。这是它显示的内容:

RequestPolicy: 192.168.2.3:843
Create Socket: 192.168.2.3:45455
Connect: [Event type="connect" bubbles=false cancelable=false eventPhase=2]
Sending: REG/REGISTER;[email protected];Si
Receiving: REG:0/REGISTER:SUCCESS;[email protected];Si/
Close: [Event type="close" bubbles=false cancelable=false eventPhase=2]
Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

成功收到来自服务器的响应后,会立即触发关闭事件,但错误 #2048 直到大约 20 秒后才会出现。如果我尝试在关闭后但在错误之前发送另一条消息,Flash Player 将引发无效套接字异常。

我在Adobe上记录了一个关于此的错误。

如果有人感兴趣,我可以提供客户端和服务器的完整源代码。

apache-flex 闪存 套接字 沙箱

评论

0赞 Michael Brewer-Davis 11/12/2009
写入 flashlog 或 policyfiles 日志的任何进一步详细信息?如果是这样,你能添加确切的消息吗?
0赞 Simon 11/12/2009
flashlog 中有一条消息说正在加载 SWF,但这就是策略日志,我已经逐字展示了整个内容。
0赞 James Ward 12/1/2009
你能发布整个错误消息吗?
0赞 James Ward 12/1/2009
您可以将测试源代码上传到 FP-3302 错误吗?
0赞 Simon 12/2/2009
@James,完成了。我已将我的服务器代码和我可以制作的最简单的客户端放在一个 zip 文件中,并将其附加到问题中。

答:

1赞 Phil Hayward 11/11/2009 #1

此处的类似问题表明 localhost 未解析为 127.0.0.1。

您可以尝试切换到 IP 地址,看看是否有帮助。

评论

0赞 Simon 11/11/2009
感谢您的建议,但是我只在绑定套接字时使用IP地址,因此另一个线程中的localhost解析不适用
1赞 Ryan Christensen 11/13/2009
True 但输出日志显示 localhost/bst/BasicSocketTest.swf 另一种测试它的方法,将其放在某个地方的公共服务器上并测试该 url 而不是来自 localhost。
1赞 Ryan Christensen #2

除了 yoru 之外,您还可以使用 Security 类在代码中进一步尝试一些操作crossdomain.xml

尝试:

Security.allowDomain("*")
Security.allowInsecureDomain("*")

或者,如果您从允许的主机外部的外部服务器加载:

Security.allowDomain(loader.contentLoaderInfo.url)

然后慢慢重新打开它,直到你遇到错误。

确保您可以直接点击策略文件,并且该端口上没有运行任何块或其他应用程序。通常,当我运行套接字时,我会高于 5000,以确保没有任何东西会占用端口。或者尝试几个不同的端口。

此外,就像一个简单的检查一样,请确保您将其命名为crossdomain.xml并且都是小写的。我曾让程序员拔掉头发,结果证明这就是原因。

评论

0赞 Simon 11/13/2009
感谢您的代码建议,我尝试将两者都添加到我的代码中,但遇到了相同的沙盒错误。我的服务器成功打开了 843 和 45455,因此我没有任何端口阻塞问题。正如我在问题中所说,第一条消息会通过,除非套接字正常工作,否则不会发生这种情况。此外,我没有使用 HTTP,因此crossdomain.xml无关紧要,因为播放器正在端口 843 上查找套接字主策略文件。这有效,我提供了一个开放的策略文件。我仍然收到沙盒错误。adobe.com/devnet/flashplayer/articles/fplayer9_security_04.html
2赞 dan_nl 11/15/2009 #3

您是否尝试过添加allow-http-request-headers-from元素?

<allow-http-request-headers-from domain="*" headers="*" />

或者为 allow-access-from 元素指定实际端口而不是 *?

<allow-access-from domain="*" to-ports="843,45455" />

评论

0赞 Simon 11/15/2009
我尝试指定端口,但没有任何成功。第一个不适用,因为套接字策略文件规范不需要标记。请记住,我不是在发出 HTTP 请求,而是直接针对带有二进制套接字的端口。adobe.com/devnet/flashplayer/articles/socket_policy_files.html
0赞 Simon 11/15/2009
以下是policyfiles.txt的正常情况: 在策略文件中搜索 <allow-access-from> 以授权请求者从 localhost/bst/BasicSocketTest.swf xmlsocket://192.168.2.3:45455 处从资源加载数据 警告:忽略策略文件中 xmlsocket://192.168.2.3:843 处域“*”的无效 <allow-http-request-headers-from>标记 OK:接受策略文件:xmlsocket://192.168.2.3:843 OK:请求者在 xmlsocket://192.168.2.3:45455 请求资源localhost/bst/BasicSocketTest.swf 是允许的,因为 2048 xmlsocket://192.168.2.3:843 的策略文件
0赞 dan_nl 11/15/2009
allow-http-request-headers-from 很奇怪,因为它遵循 dtd 和一个示例 - kb2.adobe.com/cps/403/kb403185.html;这一行并指定实际端口对以前的项目有所帮助。这可能微不足道,但您是否已将本地文件夹添加到全局安全设置 macromedia.com/support/documentation/en/flashplayer/help/...
0赞 dan_nl 11/30/2009
您是否有机会仔细检查全局安全设置?macromedia.com/support/documentation/en/flashplayer/help/......
1赞 Luca Bortot 11/16/2009 #4

尝试在 xml 结束标记“/>”之前留空,就像dan_nl建议一样,例如:

<allow-access-from 域=“*” />

不要嘲笑它,我刚刚解决了一个与你非常相似的问题(恕我直言,它看起来真的像一个解析错误)

1赞 wallyk 11/21/2009 #5

无论如何......这是否发生在 Windows Vista 上?是否将 IP 地址指定为主机名?如果是这样,请看这个

或者它可能是在探查器处于活动状态时发生的?如果是这样,请看这个

评论

0赞 Simon 11/22/2009
谢谢,但没有,XP。您的第一个链接也是由 @Phil Hayward 发布的。我不能肯定地说这不会在公共互联网上消失,我正准备租一台公共服务器来尝试一下 - 一个昂贵的错误调查。没有分析器在起作用。
1赞 Vlad Grigorov 11/27/2009 #6

发送策略文件时,服务器应始终在策略 xml 后发送零字节。从上面的描述中不清楚是否发送了零字节,这最终可能会混淆 Flash 播放器。

评论

0赞 Simon 11/29/2009
我知道 null 终止字节,并尝试过没有任何效果。但是,我在其他一些更改中尝试了它,所以也许我会再试一次。谢谢你的回答。
1赞 Duncan 12/2/2009 #7

这可能会也可能不会对您有所帮助,但我们遇到了类似的问题。我们收到安全错误,但不一致。我构建了前端,并与一位开发人员合作,他正在处理用 PHP 编写的 Socket。问题似乎在于确实存在争用条件,即 Flash 会在收到策略文件之前尝试连接到套接字。因此,在前端,我在安全错误处理程序中创建了一个重试,该处理程序将在放弃之前运行设定的次数,还将超时从默认的 20 秒设置为 6 或 8。它通常会在第二次尝试时流行起来,这确实有所帮助,但有时需要 8-10 秒才能连接,这不是最佳解决方案。

在我的搜索中遇到了一些链接,这个链接说了一些关于在服务器上设置延迟的内容,第 7 个帖子下来:http://projectdarkstar.com/forum/?action=printpage;topic=1134.0

最后,我们从这篇 Adobe 文章中下载并使用了 Python 策略文件服务器,它一直完美无缺地工作,我无法解释为什么,我不是服务器人员,但可能值得一试:

好吧,我只能发布 1 个超链接,因为我是新用户,很奇怪。搜索“设置套接字策略文件服务器”,它应该会出现,Adobe 网站上的那篇文章中有示例文件。

评论

0赞 Simon 12/2/2009
这是一个非常有用的线索,非常感谢。我将稍微改变我的服务器代码以尝试其中的一些操作。如何更改超时?
0赞 Duncan 12/2/2009
希望您需要 Flash 10,似乎这就是它被引入的时候:help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/......
0赞 Simon 12/2/2009
我在该线程上尝试了与 OP 相同的方法,即添加延迟并确保服务器端的套接字关闭,我得到的时间略有不同,但净结果相同。我应该把 Flash 播放器版本放在原来的问题中 - 谢谢你指出这一点,我会进行编辑。
3赞 James Ward 12/5/2009 #8

我一直在本地测试它,在套接字关闭之前一切似乎都正常工作。插座不应该关闭吗?将消息发送到 Flex 客户端后,Java 代码将执行以下操作:

_in.close();
_out.close();
_socket.close();

然后,Flex 客户端在下次尝试与套接字通信时会收到沙盒冲突。如果我再次创建一个新的套接字连接,那么发送和接收工作正常,然后关闭。但是大约一分钟后,我又遇到了另一个沙盒违规。我想知道 Flash 是否正在尝试 ping 套接字并且由于它已关闭,它抛出了沙盒违规?

评论

0赞 Simon 12/6/2009
_in 和 _out 只是应该关闭的打印流,但_socket是侦听端口 843 的 SocketServer 返回的 TCP 套接字。我会注释掉所有的内容,看看会发生什么。非常感谢您观看它。close
0赞 Simon 12/8/2009
进展!我不再收到沙盒错误,但套接字也不再起作用,因此通过它发送的第二条和后续消息无法到达服务器。我正在进一步调查,但这感觉像是向前迈出了一步。谢谢詹姆斯。
0赞 James Ward 12/8/2009
出于某种原因,即使在我注释掉了 _socket.close() 行之后,我仍然得到一个关闭事件。不知道为什么它会关闭。奇怪。
0赞 Maciek Sakrejda 12/8/2009 #9

我认为 James Ward 是对的——我现在正在使用 Sockets,前几天我遇到了这个问题。我发现了一个帖子,建议如果 Flash 客户端在调度 COMPLETE 事件时没有关闭套接字,这可能会导致您看到的错误。我已经添加了代码以在 COMPLETE 上关闭客户端套接字,到目前为止一切正常。

评论

0赞 Simon 12/8/2009
这很有趣,虽然有点令人困惑。那么,您是否为每个请求创建一个新的客户端套接字?我正在捕获从客户端套接字发出的所有事件,但我根本没有得到一个完整的事件 - 事实上,我无法完全发现这可能是哪个事件,你能提供精确的事件细节吗?我在套接字触发的ProgressEvent.SOCKET_DATA事件上处理数据。