BREW應用向其他平臺的移植

把一個BREW上功能移植到Symbian平臺爲例,看一下具體的實現方式。由於網絡應用的重要地位,這裏先使用BREW3.x中ISockPort建立一個TCP的連接。首先,初始化服務器的地址:

pME->m_saSockAddr.wFamily = AEE_AF_INET;

pME->m_saSockAddr.inet.port = HTONS(SERVER_PORT);

INET_PTON(pMe->saSockAddr.wFamily, SERVER_ADDR, &(pMe->saSockAddr.inet.addr));

然後創建並打開ISockPort,

ret = ISHELL_CreateInstance(pME->m_pIShell, AEECLSID_SOCKPORT, (void**)&(pME->m_pISockPort));

ret = ISOCKPORT_OpenEx(pME->m_pISockPort, AEE_AF_INET, AEE_SOCKPORT_STREAM, 0);

接下來建立TCP連接,

ret = ISOCKPORT_Connect(pME->m_pISockPort, &pME->m_saSockAddr);

if (AEEPORT_WAIT == ret){

ISOCKPORT_WriteableEx(pME->m_pISockPort,&pME->m_cbWriteCallback, MyApp_TryConnect, pME);

return;

}

建立連接成功後,就可以從服務器讀寫數據了

ret=ISOCKPORT_Write(pME->m_pISockPort,pME->m_caWriteBuffer + pME->m_nBytesWritten, BUFFER_SIZE - pME->m_nBytesWritten);

// retry later

if (AEEPORT_WAIT == ret){

ISOCKPORT_WriteableEx(pME->m_pISockPort, &pME->m_cbWriteCallback, CApp_TryWrite, pME);

return;

}

最後,取消回調並釋放ISockPort接口。

CALLBACK_Cancel(&pME->m_cbReadCallback);

CALLBACK_Cancel(&pME->m_cbWriteCallback);

IBASE_Release((IBase*)(pME->m_pISockPort));

 

Symbian 是使用C++的,移植以上功能的時候,需要使用Symbian OS 中客戶端服務器框架。首先從 CActive 創建自己的對象:

#include <e32base.h>

#include <in_sock.h>

#include <es_sock.h>

class CTCPConnector : public CActive

{

private:

// these are some of the classes relevant to opening a TCP connection:

TInt iState;

RSocket iSocket;

RSocketServ iSocketServer;

RHostResolver iResolver;

TInetAddr iAddress;

}

然後定義服務方法

void CTCPConnector::MakeOutgoingConnectionL(const TDesC& aHost, TInt aPort){

...

iState = EGetByName;

iResolver.GetByName( /* parameters required for resolving a host */);

...

}

接下來實現建立連接的方法

void CSEIConnector::ConnectSocketL(void){

...

iSocketServer.Connect();

...

iSocket.Open(iSocketServer, KAfInet, KSockStream, KProtocolInetTcp);

...

iSocket.Connect(/*parameters required connecting */);

...

iSocket.Connect(iAddress, iStatus);

iState = ESocketConnect;

...

}

最後實現RunL() 來處理事件通知:

void CTCPConnector::RunL(){

TInt error = KErrNone;

switch(iState)

{

case EGetByName:

{

ConnectSocketL();

break;

}

case ESocketConnect:

{

Proce***equestL();

break;

}

}

}

在Symbian中的工作流程是這樣的,客戶端調用MakeOutgoingConnectionL(), MakeOutgoingConnectionL()首先發起 DNS 查詢,如果域名被成功解析,則開始調用CTCPConnector::RunL()。在CTCPConnector::RunL()中,先要檢查請求的狀態,如果當前狀態值是EGetByName就可以調用ConnectSocketL()了。在ConnectSocketL()中,要創建客戶端和服務器的類以及相應的RSocket 和 RSocketServer。最後,調用RSocket::Connect() 來創建正在的TCP連接,無論連接成功或者失敗,都將再一次運行RunL(),具體的數據讀寫過程以此類推。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章