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

📄 sockstream.cpp

📁 Simple Jabber Client for Symbian Platform
💻 CPP
字号:
/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  Jabber
 *  Copyright (C) 2004 Xie Tian Lu  http://sabber.jabberstudio.org/
 */

#include "sockstream.h"
#include "osutil.h"
#include "osdlg.h"
#include "SymSock.h"
#include <string.h>

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

//
// CTimeOutTimer: timer for comms time-outs
//
CTimeOutTimer::CTimeOutTimer( const TInt aPriority ) : CTimer( aPriority )
{
}

CTimeOutTimer::~CTimeOutTimer()
{
	Cancel();
}

CTimeOutTimer* CTimeOutTimer::NewL( const TInt aPriority, MTimeOutNotify& aTimeOutNotify )
{
    CTimeOutTimer *p = new (ELeave) CTimeOutTimer(aPriority);
    CleanupStack::PushL(p);
	p->ConstructL(aTimeOutNotify);
	CleanupStack::Pop();
    return p;
}

void CTimeOutTimer::ConstructL( MTimeOutNotify& aTimeOutNotify )
{
	iNotify = &aTimeOutNotify;
	CTimer::ConstructL();
	CActiveScheduler::Add(this);
}

/**
 * Timer request has completed, so notify the timer's owner
 */
void CTimeOutTimer::RunL()
{
	iNotify->TimerExpired();
}


//-------------------------------------------------------------------------------------------
// CSockReader: active object wrapping comms read requests
//-------------------------------------------------------------------------------------------

// Construction functions
CSockReader::CSockReader() : CActive( EPriorityStandard )
{
}

CSockReader* CSockReader::NewL( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize )
{
	CSockReader* self = NewLC( aSocket, aOwner, aCacheSize );
	CleanupStack::Pop();
	return self;
}

CSockReader* CSockReader::NewLC( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize )
{
	CSockReader* self = new (ELeave) CSockReader;
	CleanupStack::PushL(self);
	self->ConstructL( aSocket, aOwner, aCacheSize );
	return self;
}

void CSockReader::ConstructL( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize  )
{
	iCache  = new CSockBuffer( aCacheSize );
	iSocket = aSocket;
	iOwner  = aOwner;
	iRecv	= 1;
	CActiveScheduler::Add(this);
}

CSockReader::~CSockReader()
{
	//DoCancel();
//#ifndef __WINS__
	Cancel();
//#endif
	delete iCache;
}

/**
 * Cancel asychronous read request
 */
void CSockReader::DoCancel()
{
//#ifndef __WINS__
	if ( !iOwner->HasSocketClosed() )
		iSocket->CancelRead();
//#endif
}

/**
 * Active object request complete handler
 */
void CSockReader::RunL()
{
	if ( iStatus == KErrNone )
	{
		// Character has been read from socket
		TInt	len;
		if ( iOwner->GetProtocol() == KProtocolInetTcp ) {
			//TInt len = iBuffer.Length();
			if ( iRecv ) 
				len = iCache->Put( iBuffer, iLen() );
		} else {
			if ( iRecv )
				len = iCache->PutPack( iBuffer, iBuffer.Length(), iFrom );
			//SYS_TRACE1( 0, "Recv a package" );
		}
		IssueRead();
		iOwner->SocketEvent( EReading );
	}
	else
	{
		if ( iStatus == KErrEof ) {
			iOwner->SocketEvent( EReadSuccess );
		} else if ( iStatus == RSocket::EStopInput ) {
			iOwner->SocketEvent( ESocketClosed );
		} else {
			iOwner->SocketEvent( EReadFailed );
		}
	}	
}

char* CSockReader::GetCacheAddr()
{
	return (char*)iCache->BuffAddr();
}

int CSockReader::GetCacheSize()
{
	return iCache->BuffSize();
}

void CSockReader::ResetCache() 
{ 
	iRecv = 1;
	iCache->Reset();
}

void CSockReader::StopRecv()
{
	iRecv = 0;
}

int CSockReader::Recv( char* buf, int len ) 
{
	IssueRead();
	return iCache->Get( buf, len );
}

int CSockReader::RecvFrom( TInetAddr& addr, char* buf, int len )
{
	IssueRead();
	return iCache->GetPack( buf, len, addr );
}

/**
 * Read data from a stream socket
 */
void CSockReader::IssueRead()
{
	if ( !IsActive() )
	{
		if ( iOwner->GetProtocol() == KProtocolInetTcp ) {
			iSocket->RecvOneOrMore( iBuffer, 0, iStatus, iLen );
			SetActive();
		} else 
		{
#ifndef __WINS__
			iSocket->RecvFrom( iBuffer, iFrom, 0, iStatus, iLen );
			SetActive();
#endif
		}
	}
}

//-------------------------------------------------------------------------------------------
// CEchoWrite: active object wrapping comms write requests
//-------------------------------------------------------------------------------------------

// Construction functions
CSockWriter::CSockWriter() : CActive( EPriorityStandard )
{
}

CSockWriter* CSockWriter::NewL( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize )
{
	CSockWriter* self = NewLC( aSocket, aOwner, aCacheSize );
	CleanupStack::Pop();
	return self;
}

CSockWriter* CSockWriter::NewLC( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize )
{
	CSockWriter* self = new(ELeave) CSockWriter;
	CleanupStack::PushL(self);
	self->ConstructL(aSocket, aOwner, aCacheSize );
	return self;
}

void CSockWriter::ConstructL( RSocket* aSocket, CSymSocket* aOwner, TUint aCacheSize )
{
	iCache  = new CSockBuffer( aCacheSize );
	iSocket = aSocket;
	iOwner  = aOwner;
	CActiveScheduler::Add(this);

	iTimeOut = KTimeOut; 
	iTimer = CTimeOutTimer::NewL(10, *this);
	iWriteStatus = EWaiting;
}

CSockWriter::~CSockWriter()
{
	//DoCancel();
//#ifndef __WINS__
	Cancel();
//#endif
	delete iCache;
	delete iTimer;
}

/**
 * Cancel asychronous write request
 */
void CSockWriter::DoCancel()
{	
//#ifndef __WINS__
	if ( !iOwner->HasSocketClosed() )
		iSocket->CancelWrite();
//#endif
}

/**
 * Implements MTimeOutNotify: called when timeout expired
 */
void CSockWriter::TimerExpired()
{
	Cancel();
	iWriteStatus = ETimeout;
	TRequestStatus* p = &iStatus;		// Signal RunL()
	SetActive();
	User::RequestComplete(p, ETimeout);
}

/**
 * Active object request complete handler
 */
void CSockWriter::RunL()
{
	if (iStatus == KErrNone)
	{
		switch(iWriteStatus)
		{
			// Character has been written to socket
			case EWriting:
				//iTimer->Cancel(); // Cancel TimeOut timer
				//SYS_TRACE2( 0, "Send byte num:", iLen() );
				iWriteStatus = EWaiting;
				IssueWrite();
			break;

			// Request timed out
			case ETimeout:
			break;
		
			default:;
		}
	}
	else 
	{
		// Error: pass it up to user interface
		if ( iStatus == RSocket::EStopOutput ) {
			iOwner->SocketEvent( ESocketClosed );
		} else {
			iOwner->SocketEvent( EWriteFailed );
		}
	}
}

void CSockWriter::ResetCache() 
{ 
	iCache->Reset();
}

int CSockWriter::Send( const char* buf, int len )
{
	int ilen = iCache->Put( buf, len );
	
	IssueWrite();
	return ilen;
}

int CSockWriter::SendTo( TInetAddr addr, const char* buf, int len )
{
	int ilen = iCache->PutPack( buf, len, addr );
	IssueWrite();
	return ilen;
}

extern "C" void itoa( int val, char* str, int radix );
#ifdef __WINS__
extern "C" void udp_socket_trace( const char* ip, short port, const unsigned char* data, int len );
#endif

void CSockWriter::IssueWrite()
{
	//SYS_TRACE1( 0, "Issue Send" );
	if ( !IsActive() ) {
		if ( iOwner->GetProtocol() == KProtocolInetTcp ) {
			TInt len = iCache->Get( iBuffer, iBuffer.MaxSize() );
			if ( len > 0 && !iOwner->HasSocketClosed() ) {
				iSocket->Write( iBuffer, iStatus );
				iWriteStatus = EWriting;
				SetActive();
			}
		} else 
		{
			TInt len = iCache->GetPack( iBuffer, iBuffer.MaxSize(), iDest );
			if ( len > 0 && !iOwner->HasSocketClosed() ) 
			{
				TBuf< 20 >	ip;
				char		str[ 60 ];
				char		num[ 10 ];
				TPtr8		to( (TUint8*)&str[ 0 ], 0, 60 );
				iDest.Output( ip );
				to.Copy( ip );
				str[ to.Length() ] = 0;
				strcat( str, ":" );
				itoa( iDest.Port(), num, 10 );
				strcat( str, num );
				strcat( str, " " );
				TInt		len = iBuffer.Length();
			#ifndef __WINS__
				iSocket->SendTo( iBuffer, iDest, 0, iStatus, iLen );
				iWriteStatus = EWriting;
				SetActive();
			#else
				//udp_socket_trace( STR_AUDIO_SERVER, C_ADUIO_PORT, iBuffer.Ptr(), iBuffer.Length() );
			#endif
				//SYS_TRACE2( 0, str, len );
			}
		}
	}
}


⌨️ 快捷键说明

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