天天看點

《BREW進階與精通——3G移動增值業務的營運、定制與開發》連載之88——BREW應用向其他平台的移植

版權聲明:本文為半吊子子全棧工匠(wireless_com,同公衆号)原創文章,未經允許不得轉載。 https://blog.csdn.net/wireless_com/article/details/5981443

以把一個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

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

最後,取消回調并釋放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:

ProcessRequestL();

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

繼續閱讀