实现QT与Flex、Flash的通信(基于Socket)

时间:2022-01-03 13:43:10

        在Windows下,Flex可以通过ActiveX方式通过ExterneralInterface接口与Qt通信,但是在Linux下,ExternalInterface方法就无效了,只能通过Socket方式与Qt通信。进行通信的两端Flex与Qt,需要绑定指定的端口,监听端口发送的数据(字符串),双方做出相应的响应。下面展示一个Qt与Flex进行文字交互的实例,如下图所示。

                        实现QT与Flex、Flash的通信(基于Socket)

       在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, SIGNAL(newConnection()),this, SLOT(FlexConnected()));

}

//Flex连接上事件

void Widget::FlexConnected()

{

qDebug() << "flash连接成功!";

m_socket = m_server->nextPendingConnection();

connect(m_socket,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));

}

QByteArray CreatePolicy()

{

char szPolicy[1024] = "";

memset(szPolicy,'\0',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室