📄 server.cpp
字号:
// server.cpp
#include "server.h"
#include <e32base.h>
// Called by the CServer framework
void CHerculeanSession::CreateL()
{
CHerculeanServer* server = static_cast<CHerculeanServer*>(const_cast<CServer2*>(Server()));
ASSERT(server);
server->AddSession();
iAsyncRequestHandler = CAsyncHandler::NewL();
}
CHerculeanSession::~CHerculeanSession()
{
CHerculeanServer* server = static_cast<CHerculeanServer*>(const_cast<CServer2*>(Server()));
ASSERT(server);
server->RemoveSession();
delete iAsyncRequestHandler;
delete iClientBuf;
}
// Handle a client request
// Leaves are handled by CHerculeanSession::ServiceError()
void CHerculeanSession::ServiceL(const RMessage2& aMessage)
{
switch (aMessage.Function())
{
case (ESlayNemeanLion):
SlayNemeanLionL(aMessage);
break;
case (ESlayHydra):
SlayHydraL(aMessage);
break;
case (ECaptureCeryneianHind):
CaptureCeryneianHindL(aMessage);
break;
case (ESlayErymanthianBoar):
SlayErymanthianBoarL(aMessage);
break;
case (ECleanAugeanStables):
CleanAugeanStablesL(aMessage);
break;
case ECancelCleanAugeanStables:
CancelCleanAugeanStables(aMessage);
break;
case (ESlayStymphalianBirds):
SlayStymphalianBirdsL(aMessage);
break;
case ECancelSlayStymphalianBirds:
CancelSlayStymphalianBirds(aMessage);
break;
case (ECaptureCretanBull):
case (ECaptureMaresOfDiomedes):
case (EObtainGirdleOfHippolyta):
case (ECaptureOxenOfGeryon):
case (ETakeGoldenApplesOfHesperides):
case (ECaptureCerberus):
default:
PanicClient(aMessage,EPanicNotSupported);
break;
}
}
// Handles leaves from CHerculeanSession::ServiceL()
// A bad descriptor error implies a badly programmed client, so panic it
// Report other errors to the client by completing the outstanding request with the error
void CHerculeanSession::ServiceError(const RMessage2& aMessage, TInt aError)
{
if (KErrBadDescriptor==aError)
PanicClient(aMessage,EPanicBadDescriptor);
else
aMessage.Complete(aError);
}
// message slot 0 contains const TDesC8&
// message slot 1 contains TInt
void CHerculeanSession::SlayNemeanLionL(const RMessage2& aMessage)
{
const TInt KMaxLionDes = 100;
TBuf8<KMaxLionDes> lionDes;
aMessage.ReadL(0, lionDes);
TInt val = aMessage.Int1();
// Process as apropriate server side, not shown here
// Does not re-write either value back to the client
// FOR EXAMPLE PURPOSES ONLY
// Check that the values are as expected
if ( (lionDes.Compare(KNemeanLionDes)!=0) || (KNemeanLionVal!=val) )
aMessage.Complete(KErrGeneral);
else
aMessage.Complete(KErrNone);
}
// message slot 0 contains TPckg<THydraData>
void CHerculeanSession::SlayHydraL(const RMessage2& aMessage)
{
THydraData hydraData;
TPckg<THydraData> des(hydraData);
aMessage.ReadL(0, des);
// FOR EXAMPLE PURPOSES ONLY
// Check that the values are as expected
if (hydraData.iHeadCount!=KHydraHeadCount)
aMessage.Complete(KErrGeneral);
// Process as necessary, for example here, set hydraData.iHeadCount to KNoHeads
hydraData.iHeadCount = KNoHeads;
aMessage.WriteL(0, des);
aMessage.Complete(KErrNone);
}
// message slot 0 contains TInt&
void CHerculeanSession::CaptureCeryneianHindL(const RMessage2& aMessage)
{
TInt count;
TPckg<TInt> countDes(count);
aMessage.ReadL(0, countDes);
// FOR EXAMPLE PURPOSES ONLY
// Check that the values are as expected
if (KInitialCount!=count)
aMessage.Complete(KErrGeneral);
// Process as necessary, for example here, set count to a hardcoded value
count = KCapturedCount;
aMessage.WriteL(0, countDes);
aMessage.Complete(KErrNone);
}
// message slot 0 contains streamed CHerculesData
void CHerculeanSession::SlayErymanthianBoarL(const RMessage2& aMessage)
{
TInt clientDesMaxLen = aMessage.GetDesMaxLength(0);
HBufC8* desData = HBufC8::NewLC(clientDesMaxLen);
TPtr8 readPtr(desData->Des());
aMessage.ReadL(0, readPtr);
CHerculesData* data = CHerculesData::NewLC(*desData);
// FOR EXAMPLE PURPOSES ONLY
// Check that the values are as expected
TInt completionCode = KErrNone;
if (KHercules().Compare(data->Des1())!=0)
completionCode = KErrGeneral;
if (KHeracles().Compare(data->Des2())!=0)
completionCode = KErrGeneral;
if (KHerculesDataVal!=data->Val())
completionCode = KErrGeneral;
// Process as apropriate server side, not shown here
// Does not re-write back to the client
CleanupStack::PopAndDestroy(2, desData); // data, desData
aMessage.Complete(completionCode);
}
// Asynchronous method
// No parameters passed from client
void CHerculeanSession::CleanAugeanStablesL(const RMessage2& aMessage)
{
// Make an asynchronous request
iAsyncRequestHandler->ServiceAsyncRequest(aMessage);
}
void CHerculeanSession::CancelCleanAugeanStables(const RMessage2& aMessage)
{
// Calls Cancel() on the CAsyncHandler active object
// which must complete the outstanding async activity and complete
// the original client-server request
iAsyncRequestHandler->Cancel();
aMessage.Complete(KErrNone);
}
// Asynchronous method
// message slot 0 contains TInt
// message slot 1 contains TDes8&
void CHerculeanSession::SlayStymphalianBirdsL(const RMessage2& aMessage)
{
TInt val0 = aMessage.Int0();
if (val0!=KBirdCount)
aMessage.Complete(KErrGeneral);
// Determine the length of the client descriptor passed to the server
TInt clientDesMaxLen = aMessage.GetDesMaxLength(1);
if (iClientBuf)
{
delete iClientBuf;
iClientBuf = NULL;
}
// iClientBuf owned/destroyed by session
iClientBuf = HBufC8::NewL(clientDesMaxLen);
TPtr8 ptr(iClientBuf->Des());
aMessage.ReadL(1, ptr);
if (ptr.Compare(KHercules)!=0)
aMessage.Complete(KErrGeneral);
// Make an asynchronous request
// for the purpose of example here don't worry about passing the
// descriptor retrieved above or modifying it
iAsyncRequestHandler->ServiceAsyncRequest(aMessage);
// iClientBuf is destroyed by later call to this method or destructor
}
void CHerculeanSession::CancelSlayStymphalianBirds(const RMessage2& aMessage)
{
// Calls Cancel() on the CAsyncHandler active object
// which must complete the outstanding async activity and complete
// the original client-server request
iAsyncRequestHandler->Cancel();
aMessage.Complete(KErrNone);
}
CServer2* CHerculeanServer::NewLC()
{
CHerculeanServer* self=new(ELeave) CHerculeanServer;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
// Starts the server and constructs the shutdown object, starting the timer to ensure that
// the server will exit even if the starting client connection fails
void CHerculeanServer::ConstructL()
{
StartL(KServerName);
iShutdown.ConstructL();
iShutdown.Start();
}
// Example doesn't bother checking the version
CSession2* CHerculeanServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const
{
return new(ELeave) CHerculeanSession();
}
// Cancel the shutdown timer now, the new session is connected
void CHerculeanServer::AddSession()
{
++iSessionCount;
iShutdown.Cancel(); // Cancel any outstanding shutdown timer
}
// Decrement the session counter and start the shutdown timer if the last client has disconnected
void CHerculeanServer::RemoveSession()
{
if (--iSessionCount==0)
iShutdown.Start();
}
// Initiates server exit when the timer expires
void CShutdown::RunL()
{
CActiveScheduler::Stop();
}
void PanicClient(const RMessage2& aMessage,TServerPanic aPanic)
{
_LIT(KPanic,"HerculesServer");
aMessage.Panic(KPanic,aPanic);
}
// Initialize and run the server
static void RunTheServerL()
{// First create and install the active scheduler
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
// create the server
CHerculeanServer::NewLC();
// Naming the server thread after the server helps to debug panics
User::LeaveIfError(User::RenameThread(KServerName));
RProcess::Rendezvous(KErrNone);
// Enter the wait loop
CActiveScheduler::Start();
// Exited - cleanup the server and scheduler
CleanupStack::PopAndDestroy(2, scheduler);
}
// Server process entry-point
TInt E32Main()
{
__UHEAP_MARK; // Heap checking
CTrapCleanup* cleanup=CTrapCleanup::New();
TInt r=KErrNoMemory;
if (cleanup)
{
TRAP(r,RunTheServerL());
delete cleanup;
}
__UHEAP_MARKEND;
return r;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -