📄 tcpipimpexengine.cpp
字号:
/**
*
* @brief Definition of CTcpipImpExEngine
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/
// INCLUDE FILES
// Class include
#include "TcpipImpExEngine.h"
// System includes
#include <eikgted.h>
#include <cdbcols.h>
#include <eikenv.h>
#include <StringLoader.h> // StringLoader
#include <TcpipImpEx.rsg>
//User Includes
#include "TcpipImpExAppui.h"
#include "TcpipImpExTimer.h"
#include "TcpipImpEx.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");
CTcpipImpExEngine* CTcpipImpExEngine::NewL(CTcpipImpExAppUi& aConsole)
{
CTcpipImpExEngine* self = CTcpipImpExEngine::NewLC(aConsole);
CleanupStack::Pop(self);
return self;
}
CTcpipImpExEngine* CTcpipImpExEngine::NewLC(CTcpipImpExAppUi& aConsole)
{
CTcpipImpExEngine* self = new (ELeave) CTcpipImpExEngine(aConsole);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CTcpipImpExEngine::CTcpipImpExEngine(CTcpipImpExAppUi& aAppUi)
: CActive(EPriorityStandard),
iAppUi(aAppUi),
iPort(KDefaultPortNumber),
iServerName(KDefaultServerName)
{
}
CTcpipImpExEngine::~CTcpipImpExEngine()
{
iEngineStatus = EDestroyed;
Cancel();
delete iTimer;
iSocketServ.Close();
}
void CTcpipImpExEngine::ConstructL()
{
ChangeStatus(ENotConnected);
// Start a timer
iTimer = CTcpipImpExTimer::NewL(EPriorityHigh, *this);
CActiveScheduler::Add(this);
// Open channel to Socket Server
User::LeaveIfError(iSocketServ.Connect());
}
void CTcpipImpExEngine::ConnectL()
{
// Initiate connection process
if (iEngineStatus == ENotConnected)
{
// need to look up name using dns
// Initiate DNS
User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp));
// DNS request for name resolution
iResolver.GetByName(iServerName, iNameEntry, iStatus);
ChangeStatus(ELookingUp);
// Request time out
iTimer->After(KTimeOut);
SetActive();
}
}
void CTcpipImpExEngine::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));
// 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 CTcpipImpExEngine::Disconnect()
{
// cancel all outstanding operations
Cancel();
iSocket.Close();
ChangeStatus(ENotConnected);
}
// from CActive
void CTcpipImpExEngine::DoCancel()
{
iTimer->Cancel();
TEngineState status = ENotConnected;
// Cancel appropriate request to socket
switch (iEngineStatus)
{
case EDestroyed:
status = EDestroyed;
case EConnecting:
case EConnected:
case ELookingUp:
case EReading:
// Cancel look up attempt
if (iResolver.SubSessionHandle() != 0)
{
iResolver.Cancel();
iResolver.Close();
}
if (iSocket.SubSessionHandle() != 0)
{
iSocket.CancelAll();
iSocket.Close();
}
break;
default:
User::Panic(KPanicTcpipImpExEngine, ETcpipImpExBadStatus);
break;
}
ChangeStatus(status);
}
void CTcpipImpExEngine::Read()
{
// Initiate read of data from socket
if (iEngineStatus == EConnected)
{
// Initiate a new read from socket into iBuffer
__ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicTcpipImpExEngineRead, ETcpipImpExBadState));
iSocket.RecvOneOrMore(iBuffer, 0, iStatus, iLength);
ChangeStatus(EReading);
SetActive();
}
}
// from CActive
void CTcpipImpExEngine::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 EConnecting:
// IP connection request
if (iStatus == KErrNone)
// Connection completed successfully
{
ChangeStatus(EConnected);
// Get the time
Read();
}
else
{
Cancel();
ReportError(EConnectionFailed, iStatus.Int());
ChangeStatus(ENotConnected);
}
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();
ReportError(EDNSLookupFailed, iStatus.Int());
}
break;
case EReading:
{
switch (iStatus.Int())
{
case KErrNone:
// Character has been read from socket
iAppUi.ResponseReceived(iBuffer);
Disconnect();
break;
case KErrDisconnected:
Cancel();
ReportError(EDisconnected,
iStatus.Int());
break;
default:
Cancel();
ReportError(EGeneralReadError,
iStatus.Int());
break;
}
break;
}
default:
User::Panic(KPanicTcpipImpExEngine, ETcpipImpExBadStatus);
break;
};
}
void CTcpipImpExEngine::TimerExpired()
{
Cancel();
ReportError(ETimedOut, KErrTimedOut);
}
void CTcpipImpExEngine::ReportError(TErrorType aErrorType, TInt aErrorCode)
{
// No recovery or retries are attempted in this example so we just
// disconnect and inform the user
Disconnect();
// Descriptors to be displayed. Use resource architecture to obtain localized strings.
TBuf<KTextMaxLength> text;
switch (aErrorType)
{
case EDisconnected:
StringLoader::Load(text, R_DISCONNECTED_TEXT);
iAppUi.Error(text, aErrorCode);
break;
case EDNSLookupFailed:
StringLoader::Load(text, R_DNS_ERROR_TEXT);
iAppUi.Error(text, aErrorCode);
break;
case EConnectionFailed:
StringLoader::Load(text, R_CONN_FAILED_TEXT);
iAppUi.Error(text, aErrorCode);
break;
case EGeneralReadError:
StringLoader::Load(text, R_READ_ERROR_TEXT);
iAppUi.Error(text, aErrorCode);
break;
case ETimedOut:
StringLoader::Load(text, R_TIMED_OUT);
iAppUi.Error(text, KErrTimedOut);
break;
default:
User::Panic(KPanicTcpipImpExEngine, ETcpipImpExBadStatus);
break;
}
}
void CTcpipImpExEngine::ChangeStatus(TEngineState aNewStatus)
{
TBuf<KTextMaxLength> text;
// Update the status (and the status display)
switch (aNewStatus)
{
case ENotConnected:
StringLoader::Load(text, R_NOT_CONNECTED_TEXT);
iAppUi.SetStatus(text);
break;
case EConnecting:
StringLoader::Load(text, R_CONNECTING_TEXT);
iAppUi.SetStatus(text);
break;
case EConnected:
StringLoader::Load(text, R_CONNECTED_TEXT);
iAppUi.SetStatus(text);
break;
case ELookingUp:
StringLoader::Load(text, R_LOOKINGUP_TEXT);
iAppUi.SetStatus(text);
break;
case EReading:
StringLoader::Load(text, R_READING_TEXT);
iAppUi.SetStatus(text);
break;
case EDestroyed:
break;
default:
User::Panic(KPanicTcpipImpExEngine, ETcpipImpExBadStatus);
break;
}
iEngineStatus = aNewStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -