实现QT与Flex、Flash的通信(基于Socket)
在Windows下,Flex可以通过ActiveX方式通过ExterneralInterface接口与Qt通信,但是在Linux下,ExternalInterface方法就无效了,只能通过Socket方式与Qt通信。进行通信的两端Flex与Qt,需要绑定指定的端口,监听端口发送的数据(字符串),双方做出相应的响应。下面展示一个Qt与Flex进行文字交互的实例,如下图所示。
在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, 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);
}
}
}
我们团队有着十几年的期货程序化交易算法与软件研发经验,基于C++ Qt技术研发了具有自主知识产权的期货智能程序化交易一体化系统平台,该平台封装了二百多个量化指标,具有低时延、高性能、小滑点、可定制和跨平台的特点。团队致力于将人工智能技术与传统的程序化交易技术相结合为客户提供灵活可定制的期货智能程序化交易服务和产品。
2013年1月6日于北京邮电大学新科研楼302室
更多推荐
所有评论(0)