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

📄 socketsengine.cpp

📁 NOKIA手机的基于C++的socket完整的开发API,非常好用
💻 CPP
字号:
/* Copyright (c) 2001, Nokia Mobile Phones. All rights reserved */

#include <eikgted.h>
#include "SocketsEngine.h"
#include "TimeOutTimer.h"
#include "SocketsReader.h"
#include "SocketsWriter.h"
#include "Sockets.pan"
#include "UINotifier.h"

const TInt CSocketsEngine::KTimeOut = 30000000; // 30 seconds time-out

_LIT(KDefaultServerName, "127.0.0.1");
const TInt CSocketsEngine::KDefaultPortNumber = 7;

CSocketsEngine* CSocketsEngine::NewL(MUINotifier& aConsole)
    {
	CSocketsEngine* self = CSocketsEngine::NewLC(aConsole);
	CleanupStack::Pop(self);
	return self;
    }

	
CSocketsEngine* CSocketsEngine::NewLC(MUINotifier& aConsole)
    {
	CSocketsEngine* self = new (ELeave) CSocketsEngine(aConsole);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
    }


CSocketsEngine::CSocketsEngine(MUINotifier& aConsole)
: CActive(EPriorityStandard),
  iConsole(aConsole),
  iPort(KDefaultPortNumber),
  iServerName(KDefaultServerName)
    {
    }


CSocketsEngine::~CSocketsEngine()
    {
    Cancel();

    delete iSocketsReader;
    iSocketsReader = NULL;

    delete iSocketsWriter;
    iSocketsWriter = NULL;

    delete iTimer;
    iTimer = NULL;

    iSocketServ.Close();
    }


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

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

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

    // Create socket read and write active objects
	iSocketsReader = CSocketsReader::NewL(*this, iSocket);
	iSocketsWriter = CSocketsWriter::NewL(*this, iSocket);
    }

void CSocketsEngine::ConnectL()
    {
    // Initiate connection process
    if (iEngineStatus == ENotConnected)
        {
        TInetAddr addr;
        if (addr.Input(iServerName) == KErrNone)
            {
            // server name is already a valid ip address
            ConnectL(addr.Address());
            }
        else // 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 CSocketsEngine::ConnectL(TUint32 aAddr) // <a name="ConnectL32">
    {
    // 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 CSocketsEngine::Disconnect()
    {
    __ASSERT_ALWAYS(iEngineStatus == EConnected, User::Panic(KPanicSocketsEngine, ESocketsBadState));

	// cancel all outstanding operations
    // since we are connected, the only possibilities are read and write
    iSocketsReader->Cancel();
    iSocketsWriter->Cancel();

	iSocket.Close();
	ChangeStatus(ENotConnected);
    }

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

    // Cancel appropriate request to socket
    switch (iEngineStatus)
        {
        case EConnecting:
            iSocket.CancelConnect();
            iSocket.Close();
            break;
        case ELookingUp:
            // Cancel look up attempt
            iResolver.Cancel();
            iResolver.Close();
            break;
	    default:
            User::Panic(KPanicSocketsEngine, ESocketsBadStatus);
            break;
	    }

    ChangeStatus(ENotConnected);
    }

void CSocketsEngine::WriteL(const TDesC8& aData)
    {
    // Write data to socket
	if (iEngineStatus == EConnected)
        {
        iSocketsWriter->IssueWriteL(aData);
        }
    }
	
void CSocketsEngine::Read()
    {
    // Initiate read of data from socket
	if ((iEngineStatus == EConnected) && (!iSocketsReader->IsActive())) 
        {
        iSocketsReader->Start();
        }
    }

// from CActive
void CSocketsEngine::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);
			    Read(); //Start CSocketsReader Active object
		        }
		    else
		        {
			    iSocket.Close();
			    iConsole.ErrorNotify(_L("CSocketsEngine\nConn. failed"), iStatus.Int());
                ChangeStatus(ENotConnected);
                }
		    break;
	    case ELookingUp:
		    iResolver.Close();
		    if (iStatus == KErrNone)
		        {
    		    // DNS look up successful
			    iNameRecord = iNameEntry();
			    // Extract domain name and IP address from name record
			    Print(_L("Domain name = "));
			    Print(iNameRecord.iName);
                TBuf<15> ipAddr;
			    TInetAddr::Cast(iNameRecord.iAddr).Output(ipAddr);
			    Print(_L("\r\nIP address = "));
			    Print(ipAddr);
                Print(_L("\r\n"));
			    // And connect to the IP address
                ChangeStatus(ENotConnected);
			    ConnectL(TInetAddr::Cast(iNameRecord.iAddr).Address());
		        }
		    else
		        {	
                // DNS lookup failed
			    iConsole.ErrorNotify(_L("CSocketsEngine\nDNS lookup failed"), iStatus.Int());
                ChangeStatus(ENotConnected);
		        }
		    break;
	    default:
            User::Panic(KPanicSocketsEngine, ESocketsBadStatus);
            break;

	    };
    }

void CSocketsEngine::TimerExpired()
    {
	Cancel();
	iConsole.ErrorNotify(_L("CSocketsEngine\nTimed out"), KErrTimedOut);
    }

void CSocketsEngine::ReportError(MEngineNotifier::TErrorType aErrorType, TInt aErrorCode)
    {
    // No recovery or retries are attempted in this example so we just
    // disconnect and inform the user
    Disconnect();

    switch (aErrorType)
        {
        case MEngineNotifier::EDisconnected:
	        iConsole.ErrorNotify(_L("CSocketsEngine\nDisconnected"), aErrorCode);
            break;
        case MEngineNotifier::EGeneralReadError:
	        iConsole.ErrorNotify(_L("CSocketsEngine\nRead Error"), aErrorCode);
            break;
        case MEngineNotifier::ETimeOutOnWrite:
	        iConsole.ErrorNotify(_L("CSocketsEngine\nTime Out on write"), aErrorCode);
            break;
        case MEngineNotifier::EGeneralWriteError:
	        iConsole.ErrorNotify(_L("CSocketsEngine\nWrite Error"), aErrorCode);
            break;
        default:
            User::Panic(KPanicSocketsEngine, ESocketsBadStatus);
            break;
        }
    }

void CSocketsEngine::ResponseReceived(const TDesC8& aBuffer)
    {
    iConsole.PrintNotify(aBuffer);
    }

void CSocketsEngine::ChangeStatus(TSocketsEngineState aNewStatus)
    {
    // Update the status (and the status display)
    switch (aNewStatus)
        {
        case ENotConnected:
            iConsole.SetStatus(_L("Not connected"));
            break;
        case EConnecting:
            iConsole.SetStatus(_L("Connecting"));
            break;
        case EConnected:
            iConsole.SetStatus(_L("Connected"));
            break;
        case ELookingUp:
            iConsole.SetStatus(_L("Looking up"));
            break;
        default:
            User::Panic(KPanicSocketsEngine, ESocketsBadStatus);
            break;
        }

    iEngineStatus = aNewStatus;
    }

void CSocketsEngine::Print(const TDesC& aDes)
    {
    // Print some text on the console
    iConsole.PrintNotify(aDes, CEikGlobalTextEditor::EItalic);
    }

void CSocketsEngine::SetServerName(const TDesC& aName)
    {
    iServerName.Copy(aName);
    }

const TDesC& CSocketsEngine::ServerName() const
    {
    return iServerName;
    }

void CSocketsEngine::SetPort(TInt aPort)
    {
    iPort = aPort;
    }

TInt CSocketsEngine::Port() const
    {
    return iPort;
    }

TBool CSocketsEngine::Connected() const
    {
    return (iEngineStatus == EConnected);
    }

⌨️ 快捷键说明

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