📄 tcpipmultihomingexengine.cpp
字号:
/**
*
* @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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -