[zz]C++与Flex之间socket通信policy-file-request解决方案

/ 2评 / 2

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 。并且在连接时, 服务端收到客户端发来的消息 消息。

发表评论

邮箱地址不会被公开。 必填项已用*标注