📄 sockstream.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 + -