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

📄 csocket.cpp

📁 symbina上可以使用一个xml解析器,对开发网络应用很有好处
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

CSocketRx* CSocketRx::NewL(CSocket* pOwner, TBool autoRestart)
{
  CSocketRx* self = new (ELeave) CSocketRx(pOwner, autoRestart);
  CleanupStack::PushL(self);
  self->ConstructL();
  CleanupStack::Pop(); // self
  return self;
}

CSocketRx::CSocketRx(CSocket* pOwner, TBool autoRestart)
  : CActive(EPriorityStandard), iSocket(pOwner), iAutoRestart(autoRestart)
{
}

CSocketRx::~CSocketRx()
{
  Cancel();
}
void CSocketRx::ConstructL()
{
  CActiveScheduler::Add(this);
}

TBool CSocketRx::Read(TBool bEnabled)
{
  __ASSERT_ALWAYS(iSocket->State() == CSocket::EConnected,
                  CSocketPanic(CSocket::INVFAILED));
  
  if (bEnabled && (!IsActive())) {
    if (iSendLastChar && (iSocket->State() == CSocket::EConnected)) {
      // REDFLAG: test this code path.
      // Special case send of last character if the buffer 
      // was completely full.
      iBuffer.SetLength(2);
      iBuffer[0] = iLastChar;
      iBuffer[1] = 0;
      iSendLastChar = EFalse;
      if (iSocket->Notify(MSocketObserver::ERead)) { return ETrue; }
      if (iSocket->State() != CSocket::EConnected) { return EFalse; }
    }      

    EnqueueRead();
  }
  else if ((!bEnabled) && IsActive()) {
    // REDFLAG think this through.  I am not sure that this code
    // path has ever been tested.
    CSOCKET_LOG(this, "CSocketRx::Read -- canceled.");
    Cancel();
  }
  return EFalse;
}

const TDesC8& CSocketRx::RecvdData() const
{
  return iBuffer;
}

void CSocketRx::DoCancel()
{
  iSocket->Socket()->CancelRecv();
}

void CSocketRx::RunL()
{
  iSendLastChar = EFalse;
  iLastChar = '\0';
  TInt len = 0;
  if (iStatus == KErrNone) {
    if (iXfrLen() == RX_BUFFER_LEN) {
      CSOCKET_LOG(this, "CSocketRx::RunL -- Hit buffer wrap case.");
      // Special case to handle full buffer.
      iLastChar = iBuffer[RX_BUFFER_LEN - 1];
      iSendLastChar = ETrue;
      len = RX_BUFFER_LEN - 1;
    }
    else {
      __ASSERT_ALWAYS(iXfrLen() < RX_BUFFER_LEN, CSocketPanic(CSocket::INVFAILED));
      len = iXfrLen();
    }

    // Set the length of the buffer.
    iBuffer.SetLength(len + 1);

    // Push a \0 ahead of the end of the
    // buffer so that we can read the 
    // buffer constents as an old school
    // C string.
    iBuffer[len] = 0;

    if (iSocket->State() == CSocket::EConnected) {
      // Notify client.
      // They can call CSocket::RecvdData() to
      // get the data, but only within the scope of this
      // callback. OBC
      if (iSocket->Notify(MSocketObserver::ERead)) {return;}
      if (iSocket->State() != CSocket::EConnected) { return; }

      if (iSendLastChar && (iSocket->State() == CSocket::EConnected)) {
        // Special case send of last character if the buffer 
        // was completely full.
        iBuffer.SetLength(2);
        iBuffer[0] = iLastChar;
        iBuffer[1] = 0;
	iSendLastChar = EFalse;
        if (iSocket->Notify(MSocketObserver::ERead)) { return; }
	if (iSocket->State() != CSocket::EConnected) { return; }
      }      
      
      if (iSocket->State() == CSocket::EConnected && iAutoRestart) {      
        // Kick off the next read.
        EnqueueRead();
      }
    }
    else {
      CSOCKET_LOG_ERR(this, "CSocketRx::RunL -- Unexpected state!, state: ", iSocket->State());
    }
  }
  else {
    iSocket->HandleError(iStatus.Int());
  }
}

TInt CSocketRx::RunError()
{
  CSOCKET_LOG(this, "CSocketRx::RunError -- called");
  // Underwhelming. But this shouldn't happen
  iSocket->HandleError(KErrUnknown);
  return KErrNone;
}

void CSocketRx::EnqueueRead()
{
  __ASSERT_ALWAYS(!IsActive(),
                  CSocketPanic(CSocket::INVFAILED));
  iBuffer.Zero();
  iSocket->Socket()->RecvOneOrMore(iBuffer,0,iStatus, iXfrLen);
  SetActive();
}

////////////////////////////////////////////////////////////
// CSocket implementation.
// Almost all of CSocket's actual functionality is
// delegated to the Active Object implementations.
////////////////////////////////////////////////////////////

EXPORT_C CSocket* CSocket::NewL()
{
  CSocket* self = new (ELeave) CSocket();
  CleanupStack::PushL(self);
  self->ConstructL();
  CleanupStack::Pop(); // self
  return self;
}

CSocket::CSocket() :  
  iObserver(NULL),
  iSetupAO(NULL), iTxAO(NULL), iRxAO(NULL), iState(CSocket::EClosed), iLastError(0)
{
  __ASSERT_DEBUG(sizeof(char) == sizeof(TUint8),
                 CSocketPanic(INVFAILED));
  CSOCKET_LOG(this, "CSocket::CSocket");
}

EXPORT_C CSocket::~CSocket()
{
  CSOCKET_LOG(this, "CSocket::~CSocket");

  // This lets callers up the stack know that
  // the instance has been deleted.
  CNotifyOnDelete* victim = iDeletionNotifier; 
  iDeletionNotifier = NULL;
  delete victim;

  Close();

  DeleteDelegates();

  iSocketServ.Close();

  iState = EClosed;
}

void CSocket::ConstructL()
{
  // Make a connection to the socket server
  TInt err=iSocketServ.Connect();
  User::LeaveIfError(err);
  iDeletionNotifier = new (ELeave) CNotifyOnDelete;
}

EXPORT_C void CSocket::SetObserver(MSocketObserver* pObserver)
{
  iObserver = pObserver;
}

EXPORT_C TBool CSocket::ConnectL(const TDesC& host, TInt port, TBool readAutoRestart)
{
  CSOCKET_LOG(this, "CSocket::ConnectL -- called");
  // Reset to a known state.
  if (Close()) {
    return ETrue;
  }
  DeleteDelegates(); 

  // Open a socket
  TInt err=iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp);
  User::LeaveIfError(err);

  iSetupAO = CSocketSetup::NewL(this);
  iTxAO = CSocketTx::NewL(this);
  iRxAO = CSocketRx::NewL(this, readAutoRestart);

  return iSetupAO->ResolveL(host, port);
}
 
EXPORT_C const TDesC8& CSocket::RecvdData() const
{
  return iRxAO->RecvdData();
}

EXPORT_C TInt CSocket::SendLen() const
{
  return iTxAO->SendLen();
}

EXPORT_C TInt CSocket::BytesBuffered() const
{
  return iTxAO->BytesBuffered();
}

EXPORT_C TInt CSocket::BytesWriteable() const
{
  return TX_BUFFER_LEN - iTxAO->BytesBuffered();
}

EXPORT_C TInt CSocket::LastError() const
{
  return iLastError;
}

EXPORT_C TBool CSocket::EnableRead(TBool bEnabled)
{
  return iRxAO->Read(bEnabled);
}

EXPORT_C void CSocket::Write(const TDesC8& data)
{
  iTxAO->Write(data);
}

EXPORT_C TBool CSocket::Close()
{
  CSOCKET_LOG(this, "CSocket::Close -- called");
  if (iState == EClosed) {
    return EFalse;
  } 

  CSOCKET_LOG(this, "CSocket::Close -- closing");

  iSetupAO->Cancel();
  iTxAO->Cancel();
  iRxAO->Cancel();
  iSocket.CancelAll();
  iSocket.Close();
  iState = EClosed;
  if (Notify(MSocketObserver::EClosed)) { return ETrue; }
  return EFalse;
}

EXPORT_C CSocket::TState CSocket::State() const 
{
  return iState;
}

RSocket* CSocket::Socket()
{
  return &iSocket;
}

RSocketServ* CSocket::SocketServ()
{
  return &iSocketServ;
}

TBool CSocket::Notify(const MSocketObserver::TSocketReason& r)
{
  // Don't do this if you are logging over the socket! or you get a loop.
  CSOCKET_LOG_ERR(this, "CSocket::Notify -- called, reason: ", (TInt)r);
  if (iObserver) {
    if (iDeletionNotifier) {
      TDeletionMonitor monitor(iDeletionNotifier);
      iObserver->SocketNotify(this, r);
      return monitor.WasDeleted();
    }
    else {
      iObserver->SocketNotify(NULL, r);
      return ETrue;
    }
  }
  return EFalse;
}

void CSocket::HandleError(TInt error)
{
  CSOCKET_LOG_ERR(this, "CSocket::HandleError -- error: ", error);
  iLastError = error;
  iState = EError;
  if (Notify(MSocketObserver::EError)) {
    return;
  }
  // It is up to the client code to call Close at this point.
}

void CSocket::DeleteDelegates()
{
  if (iSetupAO) {
    delete iSetupAO;
    iSetupAO = NULL;
  }
  if (iTxAO) {
    delete iTxAO;
    iTxAO = NULL;
  }
  if (iRxAO) {
    delete iRxAO;
    iRxAO = NULL;
  }
}

void CSocket::SetState(const TState& state)
{
  iState = state;
}


////////////////////////////////////////////////////////////
// Quick and dirty logging to file.

#ifdef ENABLE_CSOCKET_LOGGING

#include <stdio.h>

void DumpStringToFile(const char* msg)
{
  FILE* fOut = fopen("c:/csocket.log", "a+");
  if (fOut) {
    fprintf(fOut, msg);
    fflush(fOut);
    fclose(fOut);
  }
}

void Log(void* p, const char* txt)
{
  TBuf8<256> msg;
  msg.AppendNum((TUint)p, EHex);
  msg.Append(_L8(" "));
  msg.Append(TPtrC8((const TUint8*)txt, strlen(txt)));
  msg.Append(_L8("\n"));
  DumpStringToFile((const char*)msg.PtrZ());
}

void Log(void* p, const char* txt, TInt errCode)
{
  TBuf8<256> msg;
  msg.AppendNum((TUint)p, EHex);
  msg.Append(_L8(" "));
  msg.Append(TPtrC8((const TUint8*)txt, strlen(txt)));
  msg.Append(_L8(" "));
  msg.AppendNum(errCode);
  msg.Append(_L8("\n"));
  DumpStringToFile((const char*)msg.PtrZ());
}

#endif


⌨️ 快捷键说明

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