⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpsocketengine.cpp

📁 《基于Symbian OS的手机开发与应用实践》这本书的配套源码。
💻 CPP
字号:
/*
* ============================================================================
*  Name     : CTcpSocketEngine from TcpSocketEngine.cpp
*  Part of  : TcpSocket
*  Created  : 06.03.2006 by ToBeReplacedByAuthor
*  Implementation notes:
*  
*  Version  :
*  Copyright: ToBeReplacedByCopyright
* ============================================================================
*/

// INCLUDE FILES
#include <TcpSocket.h> // for Panic();

#include "TcpSocketEngine.h"

const TInt KTimeout = 30; // second

// ================= MEMBER FUNCTIONS =======================

// Two-phased constructor.
CTcpSocketEngine* CTcpSocketEngine::NewL(MTcpObserver& aObserver)
    {
    CTcpSocketEngine* self = new (ELeave) CTcpSocketEngine( aObserver );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop();
    return self;
    }

// destructor
CTcpSocketEngine::~CTcpSocketEngine()
    {
    delete iTimer;
    delete iSender;
    delete iReceiver;
    Cancel();
    iSocket.Close();
    iListenSocket.Close();
    iSocketServ.Close();
    }

// New functions
CTcpSocketEngine::TState CTcpSocketEngine::State()
    {
    return iState;
    }

void CTcpSocketEngine::ConnectL(const TDesC& aAddr, TUint aPort)
    {
    __ASSERT_DEBUG(iState==EStateIdle, Panic(ETcpSocketPanicFailToConnect));

    User::LeaveIfError(iAddr.Input(aAddr));
    iAddr.SetPort(aPort);

    // Open a TCP socket
    User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp));

    // Initiate socket connection
    iSocket.Connect(iAddr, iStatus);
    SetActive();

    // Start a timeout timer
    iTimer->Start(KTimeout);

    iState = EStateConnecting;
    }

void CTcpSocketEngine::Disconnect()
    {
    __ASSERT_DEBUG(iState==EStateConnected, Panic(ETcpSocketPanicFailToDisconnect));

    // cancel all outstanding operations
    // since we are connected, the only possibilities are read and write
    iReceiver->Cancel();
    iSender->Cancel();
    iSocket.Close();

    iState = EStateIdle;
    }

void CTcpSocketEngine::ListenL()
    {
    __ASSERT_DEBUG(iState==EStateIdle, Panic(ETcpSocketPanicFailToListen));

    TInetAddr addr(INET_ADDR(127,0,0,1), 8002);
    User::LeaveIfError(iListenSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp));
    User::LeaveIfError(iSocket.Open( iSocketServ ) );

    // Bind the socket to the required port.
    iListenSocket.Bind(addr);

    // Listen for incoming connections
    iListenSocket.Listen(1);
        
    // Accept incoming connections
    iListenSocket.Accept(iSocket, iStatus);
    SetActive();

    iState = EStateListening;
    }

void CTcpSocketEngine::SendL(const TDesC& aMsg)
    {
    __ASSERT_DEBUG(iState==EStateConnected, Panic(ETcpSocketPanicFailToSend));

    iSender->Send(aMsg);
    }

void CTcpSocketEngine::ReceiveL()
    {
    __ASSERT_DEBUG(iState==EStateConnected, Panic(ETcpSocketPanicFailToReceive));

    iReceiver->Receive();
    }

// Functions from CActive
void CTcpSocketEngine::DoCancel()
    {
    switch(iState)
        {
        case EStateConnecting:
            {
            iTimer->Cancel();
            iSocket.CancelConnect();
            break;
            }
        case EStateListening:
            {
            iListenSocket.CancelAccept();
            break;
            }
        default:
            {
            // unreachable
            break;
            }
        }
    iState = EStateIdle;
    }

void CTcpSocketEngine::RunL()
    {
    TInt err = iStatus.Int();
    switch(iState)
        {
        case EStateConnecting:
            {
            iTimer->Cancel();
            if (err == KErrNone)
                {
                // Connection completed successfully
                iState = EStateConnected;
                ReceiveL();
                }
            else
                {
                iSocket.Close();
                iState = EStateIdle;
                }
            iObserver.OnConnectL(err);
            break;
            }
        case EStateListening:
            {
            if(err == KErrNone)
                {
                iState = EStateConnected;
                ReceiveL();
                }
            iListenSocket.Close();
            iObserver.OnConnectL(err);
            break;
            }
        default:
            {
            // unreachable
            break;
            }
        }
    }

// Functions from CTcpSocketTimer::MTimerObserver
void CTcpSocketEngine::OnTimerL(TInt aError)
    {
    Cancel();
    TInt err = (aError==KErrNone)?KErrTimedOut:aError;
    iObserver.OnConnectL(err);
    }

// Functions from CTcpSocketSender::MObserver
void CTcpSocketEngine::OnSendL(const TDesC& aMsg, TInt aError)
    {
    iObserver.OnSendL(aMsg, aError);
    }

// Functions from CTcpSocketReceiver::MObserver
void CTcpSocketEngine::OnReceiveL(const TDesC& aData, TInt aError)
    {
    iObserver.OnReceiveL(aData, aError);
    if(aError==KErrNone)
        {
        ReceiveL();
        }
    else
        {
        Disconnect();
        }
    }

// constructor
CTcpSocketEngine::CTcpSocketEngine(MTcpObserver& aObserver)
: CActive(CActive::EPriorityStandard), iObserver(aObserver)
    {
    CActiveScheduler::Add(this);
    }

// EPOC default constructor can leave.
void CTcpSocketEngine::ConstructL()
    {
    // Open a session to Socket Server
    User::LeaveIfError(iSocketServ.Connect());

    iTimer = CTcpSocketTimer::NewL(*this);

    iSender = CTcpSocketSender::NewL(*this, iSocket);
    iReceiver = new(ELeave) CTcpSocketReceiver(*this, iSocket);
    }

// End of File  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -