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

📄 connection.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		else
		{
			m_mInput.nPosition = ( m_mInput.nPosition + 1 ) % METER_LENGTH;
			m_mInput.pTimes[ m_mInput.nPosition ]		= tNow;
			m_mInput.pHistory[ m_mInput.nPosition ]	= nTotal;
			m_mInput.tLastSlot = tNow;
		}
	}
	
	m_mInput.nTotal += nTotal;
	Statistics.Current.Bandwidth.Incoming += nTotal;

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CConnection write event handler

BOOL CConnection::OnWrite()
{
	if ( m_hSocket == INVALID_SOCKET ) return FALSE;
	if ( m_pOutput->m_nLength == 0 ) return TRUE;
	
	DWORD tNow		= GetTickCount();
	DWORD nLimit	= 0xFFFFFFFF;
	
	if ( m_mOutput.pLimit && *m_mOutput.pLimit && ( Settings.Live.BandwidthScale <= 100 || m_mOutput.bUnscaled ) )
	{
		DWORD tCutoff	= tNow - METER_SECOND;
		DWORD* pHistory	= m_mOutput.pHistory;
		DWORD* pTime	= m_mOutput.pTimes;
		DWORD nUsed		= 0;
		
		for ( int nSeek = METER_LENGTH ; nSeek ; nSeek--, pHistory++, pTime++ )
		{
			if ( *pTime >= tCutoff ) nUsed += *pHistory;
		}
		
		nLimit = *m_mOutput.pLimit;
		
		if ( Settings.Live.BandwidthScale < 100 && ! m_mOutput.bUnscaled )
		{
			nLimit = nLimit * Settings.Live.BandwidthScale / 100;
		}
		
		if ( Settings.Uploads.ThrottleMode )
		{
			nLimit = ( nUsed >= nLimit ) ? 0 : ( nLimit - nUsed );
		}
		else
		{
			tCutoff = nLimit * ( tNow - m_mOutput.tLastAdd ) / 1000;
			nLimit = ( nUsed >= nLimit ) ? 0 : ( nLimit - nUsed );
			nLimit = min( nLimit, tCutoff );
			m_mOutput.tLastAdd = tNow;
		}
	}
	
	BYTE* pBuffer = m_pOutput->m_pBuffer;
	DWORD nBuffer = m_pOutput->m_nLength;
	
	while ( nLimit && nBuffer )
	{
		int nLength = (int)min( nLimit, nBuffer );
		
		nLength = send( m_hSocket, (char*)pBuffer, nLength, 0 );
		if ( nLength <= 0 ) break;
		
		pBuffer += nLength;
		nBuffer -= nLength;
		
		if ( nLimit != 0xFFFFFFFF ) nLimit -= nLength;
	}
	
	DWORD nTotal = ( m_pOutput->m_nLength - nBuffer );
	
	if ( nTotal )
	{
		m_pOutput->Remove( nTotal );
		m_mOutput.tLast = tNow;
		
		if ( tNow - m_mOutput.tLastSlot < METER_MINIMUM )
		{
			m_mOutput.pHistory[ m_mOutput.nPosition ]	+= nTotal;
		}
		else
		{
			m_mOutput.nPosition = ( m_mOutput.nPosition + 1 ) % METER_LENGTH;
			m_mOutput.pTimes[ m_mOutput.nPosition ]		= tNow;
			m_mOutput.pHistory[ m_mOutput.nPosition ]	= nTotal;
			m_mOutput.tLastSlot = tNow;
		}
		
		m_mOutput.nTotal += nTotal;
		Statistics.Current.Bandwidth.Outgoing += nTotal;
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CConnection measure

void CConnection::Measure()
{
	DWORD tCutoff		= GetTickCount() - METER_PERIOD;
	DWORD* pInHistory	= m_mInput.pHistory;
	DWORD* pInTime		= m_mInput.pTimes;
	DWORD* pOutHistory	= m_mOutput.pHistory;
	DWORD* pOutTime		= m_mOutput.pTimes;
	DWORD nInput		= 0;
	DWORD nOutput		= 0;
	
	for ( int tNow = METER_LENGTH ; tNow ; tNow-- )
	{
		if ( *pInTime >= tCutoff ) nInput += *pInHistory;
		if ( *pOutTime >= tCutoff ) nOutput += *pOutHistory;
		pInHistory++, pInTime++;
		pOutHistory++, pOutTime++;
	}
	
	m_mInput.nMeasure	= nInput * 1000 / METER_PERIOD;
	m_mOutput.nMeasure	= nOutput * 1000 / METER_PERIOD;
}

//////////////////////////////////////////////////////////////////////
// CConnection HTML header reading

BOOL CConnection::ReadHeaders()
{
	CString strLine;
	
	while ( m_pInput->ReadLine( strLine ) )
	{
		if ( strLine.GetLength() > 20480 ) strLine = _T("#LINE_TOO_LONG#");
		
		int nPos = strLine.Find( _T(":") );
		
		if ( strLine.IsEmpty() )
		{
			m_sLastHeader.Empty();
			return OnHeadersComplete();
		}
		else if ( _istspace( strLine.GetAt( 0 ) ) )
		{
			if ( m_sLastHeader.GetLength() )
			{
				strLine.TrimLeft();
				strLine.TrimRight();
				
				if ( strLine.GetLength() > 0 )
				{
					if ( ! OnHeaderLine( m_sLastHeader, strLine ) ) return FALSE;
				}
			}
		}
		else if ( nPos > 1 && nPos < 64 )
		{
			m_sLastHeader		= strLine.Left( nPos );
			CString strValue	= strLine.Mid( nPos + 1 );
			
			strValue.TrimLeft();
			strValue.TrimRight();
			
			if ( strValue.GetLength() > 0 )
			{
				if ( ! OnHeaderLine( m_sLastHeader, strValue ) ) return FALSE;
			}
		}
	}
	
	OnWrite();
	
	return TRUE;
}

BOOL CConnection::OnHeaderLine(CString& strHeader, CString& strValue)
{
	if ( strHeader.CompareNoCase( _T("User-Agent") ) == 0 )
	{
		m_sUserAgent = strValue;
		return TRUE;
	}
	else if ( strHeader.CompareNoCase( _T("Remote-IP") ) == 0 )
	{
		Network.AcquireLocalAddress( strValue );
	}
	else if (	strHeader.CompareNoCase( _T("X-My-Address") ) == 0 ||
				strHeader.CompareNoCase( _T("Listen-IP") ) == 0 ||
				strHeader.CompareNoCase( _T("Node") ) == 0 )
	{
		int nColon = strValue.Find( ':' );
		
		if ( ! m_bInitiated && nColon > 0 )
		{
			int nPort = GNUTELLA_DEFAULT_PORT;
			
			if ( _stscanf( strValue.Mid( nColon + 1 ), _T("%lu"), &nPort ) == 1 && nPort != 0 )
			{
				m_pHost.sin_port = htons( nPort );
			}
		}
	}
	
	return TRUE;
}

BOOL CConnection::OnHeadersComplete()
{
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CConnection header output helpers

BOOL CConnection::SendMyAddress()
{
	if ( Network.IsListening() )
	{
		CString strHeader;
		strHeader.Format( _T("Listen-IP: %s:%lu\r\n"),
			(LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ),
			htons( Network.m_pHost.sin_port ) );
		m_pOutput->Print( strHeader );
		return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CConnection blocked agent filter

BOOL CConnection::IsAgentBlocked()
{
	if ( m_sUserAgent.IsEmpty() ) return FALSE;
	if ( m_sUserAgent == _T("Fake Shareaza") ) return TRUE;
	if ( Settings.Uploads.BlockAgents.IsEmpty() ) return FALSE;
	
	CString strBlocked = Settings.Uploads.BlockAgents;
	strBlocked.MakeLower();
	
	CString strAgent = m_sUserAgent;
	strAgent.MakeLower();
	
	for ( strBlocked += '|' ; strBlocked.GetLength() ; )
	{
		CString strBrowser	= strBlocked.SpanExcluding( _T("|;,") );
		strBlocked			= strBlocked.Mid( strBrowser.GetLength() + 1 );
		
		if ( strBrowser.GetLength() > 0 &&
			 strAgent.Find( strBrowser ) >= 0 ) return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CConnection URL encodings

CString CConnection::URLEncode(LPCTSTR pszInputT)
{
	static LPCTSTR pszHex	= _T("0123456789ABCDEF");
	static LPCSTR pszUnsafe	= "<>\"#%{}|\\^~[]+?&@=:,";
	
	CString strOutput;
	if ( pszInputT == NULL || *pszInputT == 0 ) return strOutput;
	
#ifdef _UNICODE
	int nUTF8 = WideCharToMultiByte( CP_UTF8, 0, pszInputT, -1, NULL, 0, NULL, NULL );
	if ( nUTF8 < 2 ) return strOutput;
	LPSTR pszUTF8 = new CHAR[ nUTF8 ];
	WideCharToMultiByte( CP_UTF8, 0, pszInputT, -1, pszUTF8, nUTF8, NULL, NULL );
	pszUTF8[ nUTF8 - 1 ] = 0;
	LPCSTR pszInput = pszUTF8;
#else
	LPCSTR pszInput = pszInputT;
#endif
	
	LPTSTR pszOutput = strOutput.GetBuffer( strlen( pszInput ) * 3 + 1 );
	
	for ( ; *pszInput ; pszInput++ )
	{
		if ( *pszInput <= 32 || *pszInput > 127 ||
			 strchr( pszUnsafe, *pszInput ) != NULL )
		{
			*pszOutput++ = _T('%');
			*pszOutput++ = pszHex[ ( *pszInput >> 4 ) & 0x0F ];
			*pszOutput++ = pszHex[ *pszInput & 0x0F ];
		}
		else
		{
			*pszOutput++ = (TCHAR)*pszInput;
		}
	}
	
	*pszOutput = 0;
	strOutput.ReleaseBuffer();
	
#ifdef _UNICODE
	delete [] pszUTF8;
#endif
	
	return strOutput;
}

CString CConnection::URLDecode(LPCTSTR pszInput)
{
	TCHAR szHex[3] = { 0, 0, 0 };
	CString strOutput;
	int nHex;
	
#ifdef _UNICODE
	LPSTR pszBytes = new CHAR[ _tcslen( pszInput ) + 1 ];
	LPSTR pszOutput = pszBytes;
#else
	LPSTR pszOutput = strOutput.GetBuffer( strlen( pszInput ) );
#endif
	
	for ( ; *pszInput ; pszInput++ )
	{
		if ( *pszInput == '%' )
		{
			if ( ! ( szHex[0] = pszInput[1] ) ) break;
			if ( ! ( szHex[1] = pszInput[2] ) ) break;
			if ( _stscanf( szHex, _T("%x"), &nHex ) != 1 ) break;
			if ( nHex < 1 ) break;
			*pszOutput++ = nHex;
			pszInput += 2;
		}
		else if ( *pszInput == '+' )
		{
			*pszOutput++ = ' ';
		}
		else
		{
			*pszOutput++ = (CHAR)*pszInput;
		}
	}
	
	*pszOutput = 0;
	
#ifdef _UNICODE
	int nLength = MultiByteToWideChar( CP_UTF8, 0, pszBytes, -1, NULL, 0 );
	MultiByteToWideChar( CP_UTF8, 0, pszBytes, -1, strOutput.GetBuffer( nLength ), nLength );
	strOutput.ReleaseBuffer();
	delete [] pszBytes;
#else
	strOutput.ReleaseBuffer();
#endif
	
	return strOutput;
}

BOOL CConnection::StartsWith(LPCTSTR pszInput, LPCTSTR pszText)
{
	return _tcsnicmp( pszInput, pszText, _tcslen( pszText ) ) == 0;
}

⌨️ 快捷键说明

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