C++winsocket服务端,Flex as3客户端。服务端Bind绑定IP127.0.0.1端口2020,在Flex中使用Socket.connect向服务器发起链接。当Flex在本地运行的时候能链接成功, 但是通过域名访问时出现Security错误, Error #2048 。并且在连接时, 服务端收到客户端发来的消息 消息。
尝试解决:
上google搜索了若干资料,我看了良久也一知半解。
出现这个问题的原因是FlashPlayer有一个安全沙箱机制 。本地运行swf时,flashPlayer默认的安全策略是可以跨预访问的,可以查看Security.sandboxType属性值为localTrusted。然而在使用IP访问swf文件时,flashPlayer会认为这个文件是不安全的此时可以查看 Security.sandboxType的属性值为remote。此时需要在服务端放置策略文件,flashPlayer才会让swf链接到此服务器。
若干人的博客上都说需要名为crossdomain.xml 的文件放置到服务端HTTP的根目录下。文件内容为
<?xml version="1.0"?> <cross-domain-policy> <site-control permitted-cross-domain-policies="all"/> <allow-access-from domain="*" to-ports="2020" /> </cross-domain-policy>
我这么做了,但是没有任何效果。(我能确定策略文件被访问到了,因为文件中出现语法错误的时候Flex调试信息中还会报出警告。)于是我猜想这个方法也许是解决不能访问远程HTTP文件的的问题,而socket通信需要另外的方法。
然后在CSDN论坛上发现有人用JavaSocket和Flex通信出现同样问题,解决方案是服务端收到 消息时,直接向客户端发送一条消息,内容就是上面的策略文件的xml 。我仿照做了,依然无效>_<
char szPolicy[1024] = ""; strcat_s(szPolicy, 1024, ""); strcat_s(szPolicy, 1024, ""); strcat_s(szPolicy, 1024, ""); strcat_s(szPolicy, 1024, ""); strcat_s(szPolicy, 1024, "/0"); sockClient = m_sockListener.Accept(&addrClient); if (sockClient.IsInvalid()) { // accept failed puts("# Error! Acceptation failed."); continue; } nRecvLen = sockClient.Receive(szRecvBuff, MAX_BUFF); if (sockClient.IsDisconnect()) { // disconnect printf_s("# Disconnect client[%d]./n", i); RemoveClient(m_vsockClients[i--]); continue; } szRecvBuff[nRecvLen] = '/0'; printf_s("# Received: [%d]%s/n", nRecvLen, szRecvBuff); if (0 == strcmp("", szRecvBuff)) { if (strlen(szPolicy) == sockClient.Send(szPolicy, strlen(szPolicy))) { printf_s("# Send policy xml string successful./n"); } else { printf_s("# Error! Send policy xml string failed./n"); } //sockClient.Close(); //***重点在这里*** //RemoveClient(m_vsockClients[i--]); continue; } // Connect successful.
各位就当是伪代码看吧……
问题解决:
最后问题的解决是看了这位大哥的博客:http://blog.csdn.net/xuxiangwin/archive/2009/07/07/4324218.aspx 居然用了goto,让我晃了一下神。
最后的关键点是:在收到并向客户端返回策略文件之后,需要关闭当前的socket。
if (0 == strcmp("", szRecvBuff)) { if (strlen(szPolicy) == sockClient.Send(szPolicy, strlen(szPolicy))) { printf_s("# Send policy xml string successful./n"); } else { printf_s("# Error! Send policy xml string failed./n"); } sockClient.Close(); //***重点在这里*** RemoveClient(m_vsockClients[i--]); continue; }
原因是请求策略文件的链接和主动发起的链接是两个独立的链接,也就是说服务端收到信息的链接并不是我们在客户端的connect函数的主链接。关闭策略文件的请求连接后,flashPlayer它会自动重连。这个现象可以在服务端看到,这是我服务端接受一次链接显示的信息:
# Accept successful [127.0.0.1:4106]
# Readable client[0].
# Received: [23] # Send policy xml string successful.
# Accept successful [ 127.0.0.1 :4107]
就是这样,收工。
补充一句:
Flash里面有这么一个规则:如果FlashPlayer需要使用基于Socket的链接,那么策略文件必须通过Socket的方式发送……
现在最终的做法是, 843端口上 另开一个exe服务器,专门用于接受FlashPlayer的策略文件请求,在返回策略文件后断开链接。这样原来的服务端程序完全不用知道有策略文件这么回事,问题完美解决。
C++winsocket服务端,Flex as3客户端。服务端Bind绑定IP127.0.0.1端口2020,在Flex中使用Socket.connect向服务器发起链接。当Flex在本地运行的时候能链接成功, 但是通过域名访问时出现Security错误, Error #2048 。并且在连接时, 服务端收到客户端发来的消息 消息。
很精彩
好教程啊