谈Flash客户端与C++后台的几种通信方法

一,Flash 8以前时代:

使用AS2 API根据fscommand,以及SetVariable实现双工简单通信。当时这些小儿科的东西,我玩的不亦乐乎,还用在学校学生实验平台上。简单明了的SetVariable方法在AS3里面不能用了。特点:通信量小。

Flash给C++传递参数:

fscommand("MsgBox", "helloword"); C++获取Flash传递的参数通过添加FSCommand消息函数来实现:void CCppFlashDlg::FSCommandShockwaveflash1(LPCTSTR command, LPCTSTR args){if (0 == strcmp("MsgBox", command)){MessageBox(args);}}二,Flash 9以上AS3的ExternalInterface:

通过AS3的ExternalInterface调用C++中的函数,C++端通过Flash Player ActiveX控件中接口CallFunction调用AS3中的函数,值得注意的是,通信字符串格式都是XML格式,需要对XML文档进行解析。C++类的XML解析库有CMarkup和tinyXML。刚会了这些内容,我就用在了工业测控程序上,效果不错。特点:通信量小。

C++调用Flash的函数必须先在Flash客户端里面注册,方法如下:

import mx.controls.Alert;import flash.external.*;ExternalInterface.addCallback("MsgBox2", this, MsgBox2);function MsgBox2(msg:String){Alert.show(msg);} 注册好以后VC即可调用Flash中的函数了,慢,不要着急,调用格式是XML的,所以需要多多学习XML文档的解析与生成:void CCppFlashDlg::OnOK(){swfUI.CallFunction("/<invoke name=/"MsgBox2/">/<arguments>/<string>Hi</string>/</arguments>/</invoke>");}三,通过Socket通信

建立Socket连接,需要特别处理Flash的安全策略文件。特点:通信量大,,可以远程交互。

安全策略文件参考Flex Socket 与 C++ 通讯 — 安全沙箱问题解决 其代码如下:

#include <winsock2.h>#include <windows.h>#include <iostream>using namespace std;#pragma comment(lib,"ws2_32.lib")void main(){ WORD wVersionRequested;WSADATA wsaData;int err;short port=1800;//端口号wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );//初始化套接字if ( err != 0 ){return;}if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){WSACleanup( );return;}SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建套接字SOCKET sockConn;//用来和客户端通信的套接字SOCKADDR_IN addrSrv;//用来和客户端通信的套接字地址addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(port);bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//绑定端口listen(sockSrv,5);//侦听printf("Server %d is listening……/n",port);SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);char buf[4096];//接收的数据char rbuf[100]="<cross-domain-policy> ""<allow-access-from domain=/"*/" to-ports=/"*/"/>""</cross-domain-policy> ";//套接字策略文件while(1){//接受连接sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);printf("Accept connection from %s/n",inet_ntoa(addrClient.sin_addr));recv://接收数据int bytes;if((bytes=recv(sockConn,buf,sizeof(buf),0))==SOCKET_ERROR){printf("接收数据失败!/n");exit(-1);}buf[bytes]=’/0′;printf("Message from %s: %s/n",inet_ntoa(addrClient.sin_addr),buf);if (0 == strcmp(buf,"<policy-file-request/>")){//发送数据if(send(sockConn,rbuf,strlen(rbuf)+1,0)==SOCKET_ERROR){printf("发送数据失败!");exit(-1);}printf("Message to %s: %s/n",inet_ntoa(addrClient.sin_addr),rbuf);}else{//Echoif(send(sockConn,buf,strlen(buf)+1,0)==SOCKET_ERROR){printf("发送数据失败!");exit(-1);}printf("Message to %s: %s/n",inet_ntoa(addrClient.sin_addr),buf);goto recv;}//清理套接字占用的资源closesocket(sockConn);}}

四,通过LocalConnection实现AS3与C++交互:

Flash的LocalConnection是基于内存文件读写实现的。在C++客户端开启线程监视内存文件,获取Flash建立的LocalConnection,解析其发送的数据,需要了解Adobe的AMF格式。特点:限于一台电脑上通信。

假设仿真类已完成,并定义了消息:

#define WM_LOCAL_CONN_MESSAGE_INWM_USER+7// A character was received and placed in the input buffer. 当线程检测到Flash发送消息时 ,该仿真类派发该消息:

::SendMessage(pOwner->m_hWnd, WM_LOCAL_CONN_MESSAGE_IN, (WPARAM) msgRcv, (LPARAM) len);

在对话框类定义LocalConnectionEmulator实例,监测Flash的消息发送:

protected:LocalConnEmulator lcSim; 启动LocalConnection仿真程序:lcSim.InitEmulator(this);lcSim.StartEmulator(); Flash客户端发送的信息的获取是通过仿真程序派发自定义事件捕获得到,定义自定义消息函数:// Generated message map functionsvirtual BOOL OnInitDialog();afx_msg LONG OnMessageIn(WPARAM arrayPtr, LPARAM len);afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP() 添加消息映射:BEGIN_MESSAGE_MAP(CCppLocalConnDlg, CDialogEx)ON_MESSAGE(WM_LOCAL_CONN_MESSAGE_IN, OnMessageIn)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, &CCppLocalConnDlg::OnBnClickedButton1)END_MESSAGE_MAP() 实现自定义消息函数:LONG CCppLocalConnDlg::OnMessageIn(WPARAM arrayPtr, LPARAM len){char msgRcv[256];memcpy(msgRcv,(char*)arrayPtr,len);msgRcv[len]=0;this->SetWindowText(msgRcv);return true;}五,开源软件实现RTMP Server:含泪播种的人一定能含笑收获。

谈Flash客户端与C++后台的几种通信方法

相关文章:

你感兴趣的文章:

标签云: