tcpipmultihomingexengine.cpp

来自「最新官方例子,图形,描述副,基本控件,通讯协议,等等,」· C++ 代码 · 共 371 行

CPP
371
字号
/**
*
* @brief Definition of CTcpipMultiHomingExEngine
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "TcpipMultiHomingExEngine.h"

#include <eikgted.h>
#include <cdbcols.h>
#include <commdb.h>
#include <es_sock.h>
#include <eikenv.h>
#include <commdbconnpref.h>
#include <StringLoader.h>	// StringLoader
#include <TcpipMultiHomingEx.rsg>

#include "TcpipMultiHomingExAppui.h"
#include "TcpipMultiHomingExTimer.h"
#include "TcpipMultiHomingEx.pan"

const TInt KTextMaxLength = 30;
const TInt KTimeOut = 30000000; // 30 seconds time-out
const TInt KDefaultPortNumber = 13;

// default values to acces daytime server
_LIT(KDefaultServerName, "time-a.nist.gov");


CTcpipMultiHomingExEngine* CTcpipMultiHomingExEngine::NewL(MTcpipMultiHomingExEngineObserver& aObserver)
    {
	CTcpipMultiHomingExEngine* self = CTcpipMultiHomingExEngine::NewLC(aObserver);
	CleanupStack::Pop(self);
	return self;
    }


CTcpipMultiHomingExEngine* CTcpipMultiHomingExEngine::NewLC(MTcpipMultiHomingExEngineObserver& aObserver)
    {
	CTcpipMultiHomingExEngine* self = new (ELeave) CTcpipMultiHomingExEngine(aObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
    }


CTcpipMultiHomingExEngine::CTcpipMultiHomingExEngine(MTcpipMultiHomingExEngineObserver& aObserver)
: CActive(EPriorityStandard),
  iObserver(aObserver),
  iPort(KDefaultPortNumber),
  iServerName(KDefaultServerName)
    {
    }


CTcpipMultiHomingExEngine::~CTcpipMultiHomingExEngine()
    {
	iEngineStatus = EDestroyed;
    Cancel();

    delete iTimer;

	if (iSocketServ.Handle() != 0)
		{
		iSocketServ.Close();
		}
    }


void CTcpipMultiHomingExEngine::ConstructL()
    {
	ChangeStatus(ENotConnected);

    // Start a timer
	iTimer = CTcpipMultiHomingExTimer::NewL(EPriorityHigh, *this);
	CActiveScheduler::Add(this);

	// Open channel to Socket Server
	User::LeaveIfError(iSocketServ.Connect());
    }


void CTcpipMultiHomingExEngine::ConnectL()
    {
    // Initiate connection process
    if (iEngineStatus == ENotConnected)
        {

		//Open an RConnection on the Socket Server
		User::LeaveIfError(iRConn.Open(iSocketServ));

		// Start the Connection
		iRConn.Start(iStatus);
		ChangeStatus(ERConnStarting);
		iTimer->After(KTimeOut);
		SetActive();
        }
    }


void CTcpipMultiHomingExEngine::ConnectL(TUint32 aAddr)
    {
    // Initiate attempt to connect to a socket by IP address
    if (iEngineStatus == ENotConnected)
        {
        // Open a TCP socket
        User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iRConn));

        // Set up address information
	    iAddress.SetPort(iPort);
	    iAddress.SetAddress(aAddr);

        // Initiate socket connection
	    iSocket.Connect(iAddress, iStatus);
	    ChangeStatus(EConnecting);

        // Start a timeout
	    iTimer->After(KTimeOut);

	    SetActive();
        }
    }


void CTcpipMultiHomingExEngine::Disconnect()
    {
	// cancel all outstanding operations
	Cancel();
	iSocket.Close();
	ChangeStatus(ENotConnected);
    }


// from CActive
void CTcpipMultiHomingExEngine::DoCancel()
    {
    iTimer->Cancel();

	TEngineState state = ENotConnected;
    // Cancel appropriate request to socket
    switch (iEngineStatus)
        {
		case EDestroyed:
			state = EDestroyed;
		case ENotConnected:
		case ERConnStarting:
        case EConnecting:
		case EConnected:
        case ELookingUp:
		case EReading:
			if (iRConn.SubSessionHandle() != 0)
				{
				iRConn.Close();
				}
            if (iResolver.SubSessionHandle() != 0)
				{
				iResolver.Cancel();
				iResolver.Close();
				}
          	if (iSocket.SubSessionHandle() != 0)
				{
				iSocket.CancelAll();
			    iSocket.Close();
				}
			break;
	    default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
	    }

    ChangeStatus(state);
    }


void CTcpipMultiHomingExEngine::Read()
    {
    // Initiate read of data from socket
	if (iEngineStatus == EConnected)
        {
		// Initiate a new read from socket into iBuffer
		__ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicTcpipMultiHomingExEngineRead, ETcpipMultiHomingExBadState));
		iSocket.RecvOneOrMore(iBuffer, 0, iStatus, iLength);
		ChangeStatus(EReading);
		SetActive();
        }
	}


// from CActive
void CTcpipMultiHomingExEngine::RunL()
    {
    // Active object request complete handler.
    // iEngineStatus flags what request was made, so its
    // completion can be handled appropriately
	iTimer->Cancel(); // Cancel TimeOut timer before completion

	switch(iEngineStatus)
	    {

		case ERConnStarting:
			// need to look up name using dns
			// Initiate DNS
			User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp, iRConn));
			// DNS request for name resolution
			iResolver.GetByName(iServerName, iNameEntry, iStatus);

			ChangeStatus(ELookingUp);
			// Request time out
			iTimer->After(KTimeOut);
			SetActive();
			break;

	    case ELookingUp:
		    iResolver.Close();
		    if (iStatus == KErrNone)
		        {
    		    // DNS look up successful
			    iNameRecord = iNameEntry();

                ChangeStatus(ENotConnected);
			    ConnectL(TInetAddr::Cast(iNameRecord.iAddr).Address());
		        }
		    else
		        {
                // DNS lookup failed
				Cancel();
				ReportErrorL(EDNSLookupFailed, iStatus.Int());
		        }
		    break;

	    case EConnecting:
		    // IP connection request
		    if (iStatus == KErrNone)
		        // Connection completed successfully
		        {
			    ChangeStatus(EConnected);
				// Get the time
			    Read();
		        }
		    else
		        {
			    Cancel();
				ReportErrorL(EConnectionFailed, iStatus.Int());
                }
		    break;
		case EReading:
			{
			switch (iStatus.Int())
				{
				case KErrNone:
					{
					// Character has been read from socket
					TBuf<KReadBufferSize> unicodeBuf;
					unicodeBuf.Copy(iBuffer);
					iObserver.ResponseReceivedL(unicodeBuf);
					Disconnect();
					}
					break;
			    case KErrDisconnected:
					{
					Cancel();
					ReportErrorL(EDisconnected, iStatus.Int());
					}
					break;
				default:
					{
					Cancel();
					ReportErrorL(EGeneralReadError,iStatus.Int());
					}
					break;
				}
			break;
			}

	    default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;

	    };
    }


void CTcpipMultiHomingExEngine::TimerExpiredL()
    {
	Cancel();
	ReportErrorL(ETimedOut,KErrTimedOut);
    }


void CTcpipMultiHomingExEngine::ReportErrorL(TErrorType aErrorType, TInt aErrorCode)
    {
    // No recovery or retries are attempted in this example so we just
    // disconnect and inform the user
    Disconnect();
	TBuf<KTextMaxLength> text;

    switch (aErrorType)
        {
        case EDisconnected:
			StringLoader::Load(text, R_DISCONNECTED_TEXT);
	        iObserver.ErrorL(text, aErrorCode);
            break;
        case EGeneralReadError:
			StringLoader::Load(text, R_READ_ERROR_TEXT);
	        iObserver.ErrorL(text, aErrorCode);
            break;
		case EConnectionFailed:
			StringLoader::Load(text, R_CONN_FAILED_TEXT);
			iObserver.ErrorL(text, aErrorCode);
			break;
		case EDNSLookupFailed:
			StringLoader::Load(text, R_DNS_ERROR_TEXT);
			iObserver.ErrorL(text, aErrorCode);
			break;
		case ETimedOut:
			StringLoader::Load(text, R_TIMED_OUT);
			iObserver.ErrorL(text, KErrTimedOut);
			break;
        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
        }
    }


void CTcpipMultiHomingExEngine::ChangeStatus(TEngineState aNewStatus)
    {
	TBuf<KTextMaxLength> text;

    // Update the status (and the status display)
    switch (aNewStatus)
        {
        case ENotConnected:
			StringLoader::Load(text, R_NOT_CONNECTED_TEXT);
            iObserver.SetStatus(text);
            break;
		case ERConnStarting:
			StringLoader::Load(text, R_RCONNECTING_TEXT);
            iObserver.SetStatus(text);
			break;
        case EConnecting:
			StringLoader::Load(text, R_CONNECTING_TEXT);
            iObserver.SetStatus(text);
            break;
        case EConnected:
            StringLoader::Load(text, R_CONNECTED_TEXT);
            iObserver.SetStatus(text);
            break;
        case ELookingUp:
			StringLoader::Load(text, R_LOOKINGUP_TEXT);
            iObserver.SetStatus(text);
            break;
		case EReading:
			StringLoader::Load(text, R_READING_TEXT);
			iObserver.SetStatus(text);
			break;
		case EDestroyed:
			break;
        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
        }

    iEngineStatus = aNewStatus;
    }

⌨️ 快捷键说明

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