实现QT与Flex、Flash的通信(基于Socket)
??????? 在Windows下,Flex可以通过ActiveX方式通过ExterneralInterface接口与Qt通信,但是在Linux下,ExternalInterface方法就无效了,只能通过Socket方式与Qt通信。进行通信的两端Flex与Qt,需要绑定指定的端口,监听端口发送的数据(字符串),双方做出相应的响应。下面展示一个Qt与Flex进行文字交互的实例,如下图所示。 ??????????????????????? ?????? 在QT端,首先在主窗口中调用其成员函数initSocket()初始化QTcpSocket连接,调用openSwf()函数初始化窗口部件QWebView,并将Flash嵌入到webView中。 void Widget::initSocket() { process= new QProcess(this); m_server = new QTcpServer(this); if(true == (m_server->listen(QHostAddress::LocalHost,5150))) { qDebug() << "bandsuccess!"; } connect(m_server,SIGNAL(newConnection()),this,SLOT(FlexConnected())); } ??????? 在initSocket()函数中,调用QTcpServer::listen()方法绑定IP和端口地址,并且将newConnection()信号与flash连接完毕FlexConnected()槽相关联。在FlexConnected()槽中,将readyRead()信号与处理TCP数据流接收和处理readPendingDatagrams()槽相关联。在Flex端,首先构造一个QTSocket对象,然后在其构造函数中初始化IP地址、端口和Flex提供的Socket对象,最后调用InitConnect()函数初始化连接。 public function InitConnect():void { socket.connect(server,port); //监听套接字连接是否关闭 socket.addEventListener(Event.CLOSE,closeHandler); //监听是否连接上服务器 socket.addEventListener(Event.CONNECT,connectHandler); socket.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler); }???? 下面代码是整个工程的代码,包含QT部分和Flex部分。 ???? QT部分代码: // widget.h class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void openSwf(); void processTheDatagram(QByteArray array); private slots: void on_pushButton_clicked(); void readPendingDatagrams(); void FlexConnected(); private: void initSocket(); private: Ui::Widget *ui; QTcpServer *m_server; QTcpSocket *m_socket; QProcess* process; QString tempDir; QString tempFilename; }; //widget.cpp #define TEMP_DIR "/temp/" #define TEMP_FILE "QTFLEX/QTFLEX.html" #define REPLACE_STRING "{#AAA}" Widget::Widget(QWidget *parent) : QWidget(parent),ui(new Ui::Widget) { ui->setupUi(this); tempDir = qApp->applicationDirPath() + TEMP_DIR; qDebug()<< "tempDir: " << tempDir; tempFilename = tempDir + TEMP_FILE; qDebug() << "tempFilename" << tempFilename; initSocket(); openSwf(); } Widget::~Widget() { m_server->close(); delete m_server; delete process; } void Widget::initSocket() { process = new QProcess(this); m_server = new QTcpServer(this); if(true == (m_server->listen(QHostAddress::LocalHost,5150))) { qDebug() << "band success!"; } connect(m_server,SLOT(FlexConnected())); } //Flex连接上事件 void Widget::FlexConnected() { qDebug() << "flash连接成功!"; m_socket = m_server->nextPendingConnection(); connect(m_socket,SIGNAL(readyRead()),SLOT(readPendingDatagrams())); } QByteArray CreatePolicy() { char szPolicy[1024] = ""; memset(szPolicy,' ',1024); strcat(szPolicy,"<?xml version='1.0'?>"); strcat(szPolicy,"<cross-domain-policy>"); strcat(szPolicy,"<site-control permitted-cross-domain-policies='all'/>"); strcat(szPolicy,"<allow-access-from domain='*'to-ports='5150'/>"); strcat(szPolicy,"</cross-domain-policy>"); return QByteArray(szPolicy); } void Widget::readPendingDatagrams() { qDebug() << "准备接受!"; QByteArray datagram; datagram = m_socket->readAll(); m_socket->seek(0); if(0 ==(strcmp("<policy-file-request/>",datagram.constData() ))) { //首先发送安全协商报文,然后关闭socket,等待Flex重新连接 qDebug() << "安全认证完毕!"; QByteArray strPolicy = CreatePolicy(); m_socket->write(strPolicy); m_socket->close(); } else { processTheDatagram(datagram); } } void Widget::openSwf() { //设置webkit参数 QWebSettings *set = QWebSettings::globalSettings(); set->setAttribute(QWebSettings::JavascriptEnabled,true); set->setAttribute(QWebSettings::PluginsEnabled,true); set->setAttribute(QWebSettings::JavascriptCanOpenWindows,true); set->setAttribute(QWebSettings::DeveloperExtrasEnabled,true); QString dirPath = qApp->applicationDirPath(); dirPath = dirPath.left(dirPath.lastIndexOf('/')); qDebug() << dirPath; ui->webView->load(QUrl(tempFilename)); ui->webView->show(); } void Widget::processTheDatagram(QByteArrayarr) { qDebug()<<"comming"; QString s=""; s.append(arr); ui->textEdit->append(s); } void Widget::on_pushButton_clicked() { QString str=ui->lineEdit->text(); if(str==NULL || str=="") { return; } else { str="QT:"+str; ui->textEdit->append(str); m_socket->write(str.toAscii()); m_socket->close(); } } ??? Flex部分代码,在Flex3下编译通过: //QTFLEX.mxml <mx:Script> <![CDATA[ import mx.controls.Alert; public var socket:QTSocket; public function initApp():void { socket=new QTSocket(); socket.InitConnect(); } public function sendMsg():void { var str:String=msg.text; if(str==null ||str=="") { Alert.show("发送内容不能为空!"); return; } str="FLEX:"+str; AddMsgToArea(str); socket.MsgSendHandler(str); } public functionAddMsgToArea(str:String):void { varstr1:String=ta.text; ta.text=str1+"n"+str; } ]]> </mx:Script> <mx:Button x="188" y="264"label="发送" height="26" width="62"click="sendMsg();"/> <mx:TextInput x="10"y="264" width="170" height="26"id="msg"/> <mx:TextArea x="4"y="6" height="250" width="247"id="ta"/> </mx:Application> // QTSocket.as package { importflash.net.Socket; importflash.events.*; importflash.utils.ByteArray; importmx.controls.Alert; publicclass QTSocket { publicvar server:String; publicvar port:int=5150; publicvar socket:Socket=null; publicfunction QTSocket() { server="localhost"; port=5150; socket=newSocket(); } //Socket初始化 publicfunction InitConnect():void { socket.connect(server,port); //监听套接字连接是否关闭 socket.addEventListener(Event.CLOSE,closeHandler); //监听是否连接上服务器 socket.addEventListener(Event.CONNECT,connectHandler); socket.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler); } //发送消息 publicfunction MsgSendHandler(msg:String):void { if(socket != null) { varbytes:ByteArray=new ByteArray(); //新建一个ByteArray存放数据 bytes.writeUTFBytes(msg); //写入数据,以utf-8格式传数据避免中文乱码 socket.writeBytes(bytes); socket.flush(); } } //Socket接到消息 publicfunction MsgRecvedHandler(event:ProgressEvent):void { vararray:ByteArray=new ByteArray(); socket.readBytes(array); varmsg:String=new String(array); Alert.show(msg); } privatefunction connectHandler(event:Event):void { trace("connectHandler:" + event); socket.addEventListener(ProgressEvent.SOCKET_DATA,MsgRecvedHandler); MsgSendHandler("str");//消息体 } privatefunction closeHandler(event:Event):void { trace("closeHandler:" + event); } privatefunction ioErrorHandler(event:IOErrorEvent):void { trace("ioErrorHandler:" + event); } privatefunction securityErrorHandler(event:SecurityErrorEvent):void { trace("securityErrorHandler:" + event); } } } ??? 阿科 ??? 2013年1月6日于北京邮电大学新科研楼302室 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |