📄 symsock.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 "symsock.h"
#include "sockstream.h"
#include "osutil.h"
const TInt KTimeOut = 20000000; // 30 seconds time-out
//-------------------------------------------------------------------------------------------
// CSymSocket class for connection and shutdown
//-------------------------------------------------------------------------------------------
CSymSocket::CSymSocket() : CActive( EPriorityStandard )
{
}
CSymSocket::~CSymSocket()
{
DoCancel();
delete iReader;
delete iWriter;
delete iTimer;
iSocket.Close();
iSocketServ.Close();
}
CSymSocket* CSymSocket::NewL( MUINotify* aConsole, TUint aRCacheSize, TUint aWCachSize )
{
CSymSocket* self = NewLC( aConsole, aRCacheSize, aWCachSize );
CleanupStack::Pop();
return self;
}
CSymSocket* CSymSocket::NewLC( MUINotify* aConsole, TUint aRCacheSize, TUint aWCachSize )
{
CSymSocket* self = new (ELeave) CSymSocket;
CleanupStack::PushL(self);
self->ConstructL( aConsole, aRCacheSize, aWCachSize );
return self;
}
/**
* Construct object, and open a socket
*/
void CSymSocket::ConstructL( MUINotify* aConsole, TUint aRCacheSize, TUint aWCacheSize )
{
iProtocol = KProtocolInetTcp;
iUi = aConsole;
iSocketStatus = ESocketUnknown;
iTimeOut = KTimeOut;
iTimer = CTimeOutTimer::NewL(EPriorityHigh, *this);
CActiveScheduler::Add(this);
// Open channel to Socket Server
User::LeaveIfError( iSocketServ.Connect() );
iReader = CSockReader::NewL( &iSocket, this, aRCacheSize );
iWriter = CSockWriter::NewL( &iSocket, this, aWCacheSize );
iSocketStatus = ESocketUnknown;
}
/**
* Cancel asychronous requests
*/
void CSymSocket::DoCancel()
{
if ( iTimer )
iTimer->Cancel();
// Cancel appropriate request to socket
switch ( iSocketStatus )
{
case EConnecting:
iSocket.CancelConnect();
break;
case ELookingUp:
// Cancel look up attempt
iResolver.Cancel();
iResolver.Close();
break;
default:;
}
}
void CSymSocket::SetServer( const TDesC& aServerName, TUint16 aPort, TUint aProtocol )
{
iProtocol = aProtocol;
User::LeaveIfError( iResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp ) );
// DNS request for name resolution
if ( KErrNone != iResolver.GetByName( aServerName, iNameEntry ) ) {
iSocketStatus = ELookUpFailed;
} else {
iNameRecord = iNameEntry();
iAddress.SetAddress( TInetAddr::Cast(iNameRecord.iAddr).Address() );
}
iResolver.Close();
iAddress.SetPort( aPort );
}
void CSymSocket::SetServerName( const TDesC& aServerName )
{
User::LeaveIfError( iResolver.Open( iSocketServ, KAfInet, KProtocolInetUdp ) );
// DNS request for name resolution
if ( KErrNone != iResolver.GetByName( aServerName, iNameEntry ) ) {
iSocketStatus = ELookUpFailed;
} else {
iNameRecord = iNameEntry();
iAddress.SetAddress( TInetAddr::Cast(iNameRecord.iAddr).Address() );
}
iResolver.Close();
}
void CSymSocket::SetServerPort( TUint16 port )
{
iAddress.SetPort( port );
}
void CSymSocket::ConnectL()
{
// Open a TCP/UDP socket
if ( iProtocol == KProtocolInetUdp ) {
User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp ) );
iAddress.SetAddress( KInetAddrAny );
//iAddress.SetAddress( INET_ADDR( 218,106,172,228 ) );
//iAddress.SetAddress( INET_ADDR( 192,168,0,91 ) );
iAddress.SetPort( 2468 );
iSocket.Bind( iAddress );
iSocketStatus = EConnected;
//SYS_TRACE1( 0, "udp socket created" );
} else {
User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );
iSocket.Connect( iAddress, iStatus );
iSocketStatus = EConnecting;
iTimer->After(iTimeOut);
SetActive();
}
}
/**
* Shutdown connection request
*/
void CSymSocket::Stop()
{
switch ( iSocketStatus )
{
case EConnected:
// Stop live connection
iReader->Cancel();
iWriter->Cancel();
break;
case EConnecting:
case ELookingUp:
// if request to CEchoEngine, then stop it
Cancel();
break;
default:;
}
}
void CSymSocket::Close()
{
iReader->Cancel();
iWriter->Cancel();
iSocket.Close();
iSocketStatus = ESocketUnknown;
}
int CSymSocket::Send( const char* buf, int len, int flags )
{
if ( iSocketStatus == EWriteFailed || iSocketStatus == EReadFailed )
return -1;
return iWriter->Send( buf, len );
}
int CSymSocket::Recv( char* buf, int len, int flags )
{
if ( iSocketStatus == EReadFailed || iSocketStatus == EWriteFailed )
return -1;
return iReader->Recv( buf, len );
}
int CSymSocket::SendTo( const char* buf, int len, TInetAddr dest )
{
return iWriter->SendTo( dest, buf, len );
}
int CSymSocket::RecvFrom( char* buf, int len, TInetAddr& from )
{
return iReader->RecvFrom( from, buf, len );
}
/*
int CSymSocket::SendTo( const char* ip, short port, const char* buf, int len, int flags )
{
return 0;
}
int CSymSocket::RecvFrom( char* ip, short& port, char* buf, int len, int flags )
{
return 0;
}
*/
/**
* Active object request complete handler.
* iEngineStatus flags what request was made, so its
* completion can be handled appropriately
*/
void CSymSocket::RunL()
{
iTimer->Cancel(); // Cancel TimeOut timer before completion
TBuf<15> ipAddr;
switch( iSocketStatus )
{
case EConnecting: // IP connection request
if (iStatus == KErrNone) // Connection completed sucessfully
{
iSocketStatus = EConnected;
iUi->Notify( iSocketStatus );
}
else
{
iSocketStatus = EConnectFailed;
iUi->ConnectFailed();
}
break;
case ETimeout:
iSocketStatus = ETimeout;
iUi->ConnectTimeout();
break;
case ELookingUp:
iResolver.Close();
if (iStatus == KErrNone) // DNS look up successful
{
iNameRecord = iNameEntry();
TInetAddr::Cast(iNameRecord.iAddr).Output(ipAddr);
}
else
{
iSocketStatus = ELookUpFailed;
}
break;
default:;
}
//( ( CUUClientAppUi* )iUi )->Notify( iSocketStatus );
}
TSymSocketState CSymSocket::GetCurStatus()
{
return iSocketStatus;
}
/**
* Implements MTimeOutNotify: called when timeout expired
*/
void CSymSocket::TimerExpired()
{
Cancel();
iSocketStatus = ETimeout;
TRequestStatus* p = &iStatus;
// Signal CSymSocket::RunL() imediately
SetActive();
User::RequestComplete( p, ETimeout );
}
void CSymSocket::SocketEvent( TSymSocketState aState )
{
switch ( aState )
{
case EReadFailed:
iSocketStatus = EReadFailed;
break;
case EWriteFailed:
iSocketStatus = EWriteFailed;
break;
}
}
TInt CSymSocket::HasSocketClosed()
{
return iSocketStatus == ESocketUnknown;
}
TUint CSymSocket::GetProtocol()
{
return iProtocol;
}
//-------------------------------------------------------------------------------------------
// sock util functions
//-------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -