controlsocket.cpp

来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 551 行 · 第 1/2 页

CPP
551
字号

_int64 CControlSocket::GetAbleToUDSize( bool &beenWaiting, CTime &curTime, _int64 &curLimit, std::list<CControlSocket::t_ActiveList>::iterator &iter, bool download, int nBufSize)
{
	beenWaiting = false;

	CTime nowTime = CTime::GetCurrentTime();
	_int64 ableToRead = BUFSIZE;

	if ( nowTime == curTime)
	{
		ableToRead = iter->nBytesAvailable;

		if ( ableToRead <= 0)
		{
			//	we should wait till next second
			nowTime = CTime::GetCurrentTime();

			while (nowTime == curTime && !iter->nBytesAvailable)
			{
				if (beenWaiting)
				{
					//Check if there are other commands in the command queue.
					MSG msg;
					if (PeekMessage(&msg, 0, m_pOwner->m_nInternalMessageID, m_pOwner->m_nInternalMessageID, PM_NOREMOVE))
					{
						LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("Message waiting in queue, resuming later"));
						return 0;
					}
				}
				m_SpeedLimitSync.Unlock();
				Sleep(100);
				m_SpeedLimitSync.Lock();
				nowTime = CTime::GetCurrentTime();
				beenWaiting = true;
			}
			
		}
		ableToRead = iter->nBytesAvailable;
	}

	if (nowTime != curTime)
	{
		if ( ableToRead > 0)
			ableToRead = 0;

		if (download)
		{
			curLimit = GetDownloadSpeedLimit( curTime);
			__int64 nMax = curLimit / CControlSocket::m_DownloadInstanceList.size();
			_int64 nLeft=0;
			int nCount=0;
			std::list<CControlSocket::t_ActiveList>::iterator iter2;
			for (iter2=CControlSocket::m_DownloadInstanceList.begin(); iter2!=CControlSocket::m_DownloadInstanceList.end(); iter2++)
			{
				if (iter2->nBytesAvailable>0)
				{
					nLeft+=iter2->nBytesAvailable;
					iter2->nBytesTransferred=1;
					nCount++;
				}
				else
				{
					iter2->nBytesTransferred=0;
				}
				iter2->nBytesAvailable=nMax;
			}
			if (nCount)
			{
				nMax=nLeft/nCount;
				for (iter2=CControlSocket::m_DownloadInstanceList.begin(); iter2!=CControlSocket::m_DownloadInstanceList.end(); iter2++)
				{
					if (!iter2->nBytesTransferred)
					{
						iter2->nBytesAvailable+=nMax;
						iter2->nBytesTransferred=0;
					}
					iter2->nBytesTransferred=0;
				}
			}
			for (iter2=CControlSocket::m_DownloadInstanceList.begin(); iter2!=CControlSocket::m_DownloadInstanceList.end(); iter2++)
				iter2->nBytesTransferred=0;
		}
		else
		{
			curLimit = GetUploadSpeedLimit(curTime);
			__int64 nMax = curLimit / CControlSocket::m_UploadInstanceList.size();
			_int64 nLeft=0;
			int nCount=0;
			std::list<CControlSocket::t_ActiveList>::iterator iter2;
			for (iter2=CControlSocket::m_UploadInstanceList.begin(); iter2!=CControlSocket::m_UploadInstanceList.end(); iter2++)
			{
				if (iter2->nBytesAvailable>0)
				{
					nLeft+=iter2->nBytesAvailable;
					iter2->nBytesTransferred=1;
					nCount++;
				}
				else
				{
					iter2->nBytesTransferred=0;
				}
				iter2->nBytesAvailable=nMax;
			}
			if (nCount)
			{
				nMax=nLeft/nCount;
				for (iter2=CControlSocket::m_UploadInstanceList.begin(); iter2!=CControlSocket::m_UploadInstanceList.end(); iter2++)
				{
					if (!iter2->nBytesTransferred)
					{
						iter2->nBytesAvailable+=nMax;
						iter2->nBytesTransferred=0;
					}
					iter2->nBytesTransferred=0;
				}
			}
			for (iter2=CControlSocket::m_UploadInstanceList.begin(); iter2!=CControlSocket::m_UploadInstanceList.end(); iter2++)
				iter2->nBytesTransferred=0;
		}
		ableToRead=iter->nBytesAvailable;
	}

	curTime = nowTime;

	if (!nBufSize)
		nBufSize = BUFSIZE;
	if (ableToRead > nBufSize)
		ableToRead = nBufSize;
	
	return ableToRead;
}

_int64 CControlSocket::GetAbleToDownloadSize( bool &beenWaiting, int nBufSize /*=0*/)
{
	CSingleLock lock(&m_SpeedLimitSync, TRUE);
	std::list<CControlSocket::t_ActiveList>::iterator iter;
	for (iter=CControlSocket::m_DownloadInstanceList.begin(); iter!=CControlSocket::m_DownloadInstanceList.end(); iter++)
		if (iter->pOwner == this)
			break;
	if (iter==CControlSocket::m_DownloadInstanceList.end())
	{
		CControlSocket::t_ActiveList item;
		item.nBytesAvailable = GetDownloadSpeedLimit(CTime::GetCurrentTime())/(CControlSocket::m_DownloadInstanceList.size()+1);
		item.nBytesTransferred = 0;
		item.pOwner = this;
		CControlSocket::m_DownloadInstanceList.push_back(item);
		iter=CControlSocket::m_DownloadInstanceList.end();
		iter--;
	}
	return GetAbleToUDSize( beenWaiting, m_CurrentDownloadTime, m_CurrentDownloadLimit, iter, true, nBufSize);
}

_int64 CControlSocket::GetAbleToUploadSize( bool &beenWaiting, int nBufSize)
{
	CSingleLock lock(&m_SpeedLimitSync, TRUE);
	std::list<CControlSocket::t_ActiveList>::iterator iter;
	for (iter=CControlSocket::m_UploadInstanceList.begin(); iter!=CControlSocket::m_UploadInstanceList.end(); iter++)
		if (iter->pOwner == this)
			break;
	if (iter==CControlSocket::m_UploadInstanceList.end())
	{
		CControlSocket::t_ActiveList item;
		item.nBytesAvailable = GetUploadSpeedLimit(CTime::GetCurrentTime())/(CControlSocket::m_UploadInstanceList.size()+1);
		item.nBytesTransferred = 0;
		item.pOwner = this;
		CControlSocket::m_UploadInstanceList.push_back(item);
		iter=CControlSocket::m_UploadInstanceList.end();
		iter--;
	}
	return GetAbleToUDSize( beenWaiting, m_CurrentUploadTime, m_CurrentUploadLimit, iter, false, nBufSize);
}

BOOL CControlSocket::RemoveActiveTransfer()
{
	BOOL bFound = FALSE;
	CSingleLock(&m_SpeedLimitSync, TRUE);
	std::list<CControlSocket::t_ActiveList>::iterator iter;
	for (iter=m_UploadInstanceList.begin(); iter!=m_UploadInstanceList.end(); iter++)
		if (iter->pOwner == this)
		{
			m_UploadInstanceList.erase(iter);
			bFound = TRUE;
			break;
		}
	for (iter=m_DownloadInstanceList.begin(); iter!=m_DownloadInstanceList.end(); iter++)
		if (iter->pOwner == this)
		{
			m_DownloadInstanceList.erase(iter);
			bFound = TRUE;
			break;
		}
	return bFound;
}

BOOL CControlSocket::SpeedLimitAddDownloadedBytes(_int64 nBytesDownloaded)
{
	CSingleLock(&m_SpeedLimitSync, TRUE);
	std::list<t_ActiveList>::iterator iter;
	for (iter=m_DownloadInstanceList.begin(); iter!=m_DownloadInstanceList.end(); iter++)
		if (iter->pOwner == this)
		{
			if (iter->nBytesAvailable > nBytesDownloaded)
				iter->nBytesAvailable -= nBytesDownloaded;
			else
				iter->nBytesAvailable = 0;
			iter->nBytesTransferred += nBytesDownloaded;
			return TRUE;
		}
	return FALSE;
}

BOOL CControlSocket::SpeedLimitAddUploadedBytes(_int64 nBytesUploaded)
{
	CSingleLock(&m_SpeedLimitSync, TRUE);
	std::list<t_ActiveList>::iterator iter;
	for (iter=m_UploadInstanceList.begin(); iter!=m_UploadInstanceList.end(); iter++)
		if (iter->pOwner == this)
		{
			if (iter->nBytesAvailable > nBytesUploaded)
				iter->nBytesAvailable -= nBytesUploaded;
			else
				iter->nBytesAvailable = 0;
			iter->nBytesTransferred += nBytesUploaded;
			return TRUE;
		}
	return FALSE;
}

_int64 CControlSocket::SpeedLimitGetDownloadBytesAvailable()
{
	CSingleLock(&m_SpeedLimitSync, TRUE);
	std::list<t_ActiveList>::const_iterator iter;
	for (iter=m_DownloadInstanceList.begin(); iter!=m_DownloadInstanceList.end(); iter++)
		if (iter->pOwner == this)
			return iter->nBytesAvailable;
	return 0;
}

_int64 CControlSocket::SpeedLimitGetUploadBytesAvailable()
{
	CSingleLock(&m_SpeedLimitSync, TRUE);
	std::list<t_ActiveList>::const_iterator iter;
	for (iter=m_UploadInstanceList.begin(); iter!=m_UploadInstanceList.end(); iter++)
		if (iter->pOwner == this)
			return iter->nBytesAvailable;
	return 0;
}

CString CControlSocket::ConvertDomainName(CString domain)
{
	USES_CONVERSION;

	LPCWSTR buffer = T2CW(domain);
	
	char *utf8 = new char[wcslen(buffer) * 2 + 2];
	if (!WideCharToMultiByte(CP_UTF8, 0, buffer, -1, utf8, wcslen(buffer) * 2 + 2, 0, 0))
	{
		delete [] utf8;
		LogMessage(FZ_LOG_WARNING, _T("Could not convert domain name"));
		return domain;
	}

	char *output;
	if (idna_to_ascii_8z(utf8, &output, IDNA_ALLOW_UNASSIGNED))
	{
		delete [] utf8;
		LogMessage(FZ_LOG_WARNING, _T("Could not convert domain name"));
		return domain;
	}
	delete [] utf8;

	CString result = A2T(output);
	free(output);
	return result;
}

⌨️ 快捷键说明

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