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

📄 transfersocket.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		m_pOwner->ShowStatus(str, 1);
		Close();
		if (!m_bSentClose)
		{
			m_nMode|=CSMODE_TRANSFERERROR;
			m_bSentClose=TRUE;
			m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
		}	
	}
	else
	{
		/* Set internal socket send buffer to twice the programs buffer size
		 * this should fix the speed problems some users have reported
		 */
		DWORD value;
		int len = sizeof(value);
		GetSockOpt(SO_SNDBUF, &value, &len);
		if (value < (BUFSIZE*2))
		{
			value = BUFSIZE * 2;
			SetSockOpt(SO_SNDBUF, &value, sizeof(value));
		}
	}
	if (m_nTransferState == STATE_STARTING)
	{
		m_nTransferState = STATE_STARTED;
		
		m_TransferedFirst = m_StartTime = CTime::GetCurrentTime();
		m_LastActiveTime=CTime::GetCurrentTime();
		
		if (m_pSslLayer)
		{
			AddLayer(m_pSslLayer);
			int res = m_pSslLayer->InitSSLConnection(true);
			if (res == SSL_FAILURE_LOADDLLS)
				m_pOwner->ShowStatus(IDS_ERRORMSG_CANTLOADSSLDLLS, 1);
			else if (res == SSL_FAILURE_INITSSL)
				m_pOwner->ShowStatus(IDS_ERRORMSG_CANTINITSSL, 1);
					
			if (res)
			{
				Close();
				if (!m_bSentClose)
				{
					m_nMode |= CSMODE_TRANSFERERROR;
					m_bSentClose = TRUE;
					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
				}
				return;
			}
		}
		
		if (m_pGssLayer)
		{
			AddLayer(m_pGssLayer);
		}
	}
}	


void CTransferSocket::OnClose(int nErrorCode) 
{
	LogMessage(__FILE__, __LINE__, this, FZ_LOG_DEBUG, _T("OnClose(%d)"), nErrorCode);

	if (m_nTransferState == STATE_WAITING)
	{
		m_nNotifyWaiting |= FD_CLOSE;
		return;
	}

	OnReceive(0);
	Close();
	if (!m_bSentClose)
	{
		m_bSentClose=TRUE;
		m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
	}
}

int CTransferSocket::CheckForTimeout(int delay)
{
	UpdateStatusBar(false);
	if (!m_bCheckTimeout)
		return 1;
	CTimeSpan span = CTime::GetCurrentTime()-m_LastActiveTime;
	if (span.GetTotalSeconds()>=delay)
	{
		m_pOwner->ShowStatus(IDS_ERRORMSG_TIMEOUT, 1);
		Close();
		if (!m_bSentClose)
		{
			m_nMode |= CSMODE_TRANSFERTIMEOUT;
			m_bSentClose = TRUE;
			VERIFY(m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode));
		}
		return 2;
	}
	return 1;
}

void CTransferSocket::SetActive()
{
	LogMessage(__FILE__, __LINE__, this, FZ_LOG_DEBUG, _T("SetActive()"));

	if (m_nTransferState == STATE_WAITING)
		m_nTransferState = STATE_STARTING;
	m_bCheckTimeout = TRUE;
	m_LastActiveTime = CTime::GetCurrentTime();

	if (m_nNotifyWaiting & FD_READ)
		OnReceive(0);
	if (m_nNotifyWaiting & FD_WRITE)
		OnSend(0);
	if (m_nNotifyWaiting & FD_CLOSE)
		OnClose(0);
}

void CTransferSocket::OnSend(int nErrorCode) 
{
	if (m_nTransferState == STATE_WAITING)
	{
		m_nNotifyWaiting |= FD_WRITE;
		return;
	}

	if (m_bSentClose)
		return;
	if (m_bListening)
		return;
	
	if (!(m_nMode&CSMODE_UPLOAD))
		return;

	if (m_nTransferState == STATE_STARTING)
		OnConnect(0);

	if (m_useZlib)
	{
		if (!m_pBuffer)
		{
			m_pBuffer = new char[BUFSIZE];
			m_bufferpos = 0;

			m_zlibStream.next_out = (Bytef *)m_pBuffer;
			m_zlibStream.avail_out = BUFSIZE;
		}
		if (!m_pBuffer2)
		{
			m_pBuffer2 = new char[BUFSIZE];

			m_zlibStream.next_in = (Bytef *)m_pBuffer2;
		}

		bool beenWaiting = false;
		while (true)
		{
			int numsend;
			if (!m_zlibStream.avail_in)
			{
				if (m_pFile)
				{
					DWORD numread;
					numread = ReadDataFromFile(m_pBuffer2, BUFSIZE);
					if (numread < 0)
						return;

					m_transferdata.transferleft -= numread;					
					m_zlibStream.next_in = (Bytef *)m_pBuffer2;
					m_zlibStream.avail_in = numread;

					if (numread < BUFSIZE)
						m_pFile = 0;
				}
			}
			if (!m_zlibStream.avail_out)
			{
				if (m_bufferpos >= BUFSIZE)
				{
					m_bufferpos = 0;
					m_zlibStream.next_out = (Bytef *)m_pBuffer;
					m_zlibStream.avail_out = BUFSIZE;
				}
			}

			int res = Z_OK;
			if (m_zlibStream.avail_out)
			{
				res = deflate(&m_zlibStream, m_pFile ? 0 : Z_FINISH);
				if (res != Z_OK && (!m_pFile && res != Z_STREAM_END))
				{
					m_pOwner->ShowStatus("ZLib error", 1);
					Close();
					if (!m_bSentClose)
					{
						m_nMode |= CSMODE_TRANSFERERROR;
						m_bSentClose = TRUE;
						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
					}
					return;
				}
			}

			numsend = BUFSIZE;
			int len = BUFSIZE - m_bufferpos - m_zlibStream.avail_out;
			if (!len && !m_pFile)
				break;

			if (len < BUFSIZE)
				numsend = len;

			int nLimit = (int)m_pOwner->GetAbleToUploadSize(beenWaiting);
			if (nLimit != -1 && GetState() != closed && numsend > nLimit)
				numsend = nLimit;

			if (!numsend)
			{
				TriggerEvent(FD_WRITE);
				return;
			}

			int numsent = Send(m_pBuffer + m_bufferpos, numsend);
			if (numsent == SOCKET_ERROR)
			{
				/* Give control back to the system. Else FileZilla would 
				 * consume most CPU power until the data was sent.
				 * This behaviour is very strange, and I can't explain it,
				 * maybe it's just another bug in Windows
				 */
				Sleep(0);
							
				int nError = GetLastError();
				if (nError == WSAENOTCONN)
				{
					//Not yet connected
					return;
				}
				else if (m_pSslLayer && nError == WSAESHUTDOWN)
				{
					// Do nothing, wait for shutdown complete notification.
					return;
				}
				else if (nError != WSAEWOULDBLOCK)
				{
					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
					{
						Close();
						if (!m_bSentClose)
						{
							m_nMode |= CSMODE_TRANSFERERROR;
							m_bSentClose = TRUE;
							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
						}
					}
				}
				UpdateStatusBar(false);
				return;
			}

			Transfered( numsent, CTime::GetCurrentTime());
			m_pOwner->SpeedLimitAddUploadedBytes(numsent);
			m_LastActiveTime = CTime::GetCurrentTime();
			UpdateSendLed();

			m_bufferpos += numsent;

			UpdateStatusBar(false);
			
			if (!m_zlibStream.avail_in && !m_pFile && m_zlibStream.avail_out &&
				m_zlibStream.avail_out + m_bufferpos == BUFSIZE && res == Z_STREAM_END)
			{
				if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
				{
					Close();
					if (!m_bSentClose)
					{
						m_bSentClose = TRUE;
						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
					}
				}
				return;
			}

			//Check if there are other commands in the command queue.
			MSG msg;
			if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
			{
				TriggerEvent(FD_WRITE);
				return;
			}
		}
	}
	else
	{
		if (!m_pFile)
			return;
		if (!m_pBuffer)
			m_pBuffer = new char[BUFSIZE];
		
		int numread;
		
		bool beenWaiting = false;
		_int64 currentBufferSize;
		if (GetState() != closed)
			currentBufferSize = m_pOwner->GetAbleToUploadSize(beenWaiting);
		else
			currentBufferSize = BUFSIZE;

		if (!currentBufferSize && !m_bufferpos)
		{
			// Not allowed to send yet, try later
			TriggerEvent(FD_WRITE);
			return;
		}
		else if (m_bufferpos < currentBufferSize)
		{
			numread = ReadDataFromFile(m_pBuffer + m_bufferpos, static_cast<int>(currentBufferSize - m_bufferpos));
			if (numread < 0 )
				return;
			else if (!numread && !m_bufferpos)
			{
				if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
				{
					Close();
					if (!m_bSentClose)
					{
						m_bSentClose = TRUE;
						m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
					}
				}
				return;
			}
		}
		else
			numread = 0;
			
		ASSERT((numread+m_bufferpos) <= BUFSIZE);
		ASSERT(numread>=0);
		ASSERT(m_bufferpos>=0);

		if (numread+m_bufferpos <= 0)
		{
			if (ShutDown() || GetLastError()!=WSAEWOULDBLOCK)
			{
				Close();
				if (!m_bSentClose)
				{
					m_bSentClose=TRUE;
					m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
				}
			}
			return;
		}
			
		int numsent = Send(m_pBuffer, numread + m_bufferpos);
			
		while (TRUE)
		{
			if (numsent != SOCKET_ERROR)
			{
				Transfered(numsent, CTime::GetCurrentTime());
				m_pOwner->SpeedLimitAddUploadedBytes(numsent);
				m_LastActiveTime = CTime::GetCurrentTime();
				UpdateSendLed();
				m_transferdata.transferleft -= numsent;
			}
			
			if (numsent==SOCKET_ERROR || !numsent)
			{
				/* Give control back to the system. Else FileZilla would 
				 * consume most CPU power until the data was sent.
				 * This behaviour is very strange, and I can't explain it,
				 * maybe it's just another bug in Windows
				 */
				Sleep(0);
							
				int nError = GetLastError();
				if (nError == WSAENOTCONN)
				{
					//Not yet connected
					m_bufferpos += numread;
					return;
				}
				else if (nError == WSAEWOULDBLOCK)
					m_bufferpos += numread;
				else if (m_pSslLayer && nError == WSAESHUTDOWN)
				{
					m_bufferpos += numread;
					// Do nothing, wait for shutdown complete notification.
					return;
				}
				else
				{
					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
					{
						Close();
						if (!m_bSentClose)
						{
							m_nMode |= CSMODE_TRANSFERERROR;
							m_bSentClose = TRUE;
							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
						}
					}
				}
				UpdateStatusBar(false);
				return;
			}
			else
			{
				int pos = numread + m_bufferpos - numsent;

				if (pos < 0 || (numsent + pos) > BUFSIZE)
				{
					LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Index out of range"));
					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
					{
						Close();
						if (!m_bSentClose)
						{
							m_nMode |= CSMODE_TRANSFERERROR;
							m_bSentClose = TRUE;
							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
						}
					}
					return;
				}
				else if (!pos && numread < (currentBufferSize-m_bufferpos) && m_bufferpos != currentBufferSize)
				{
					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
					{
						Close();
						if (!m_bSentClose)
						{
							m_bSentClose = TRUE;
							m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode);
						}
					}
					return;
				}
				else if (!pos)
					m_bufferpos = 0;
				else
				{
					memmove(m_pBuffer, m_pBuffer+numsent, pos);
					m_bufferpos=pos;
				}
			}
			//Check if there are other commands in the command queue.
			MSG msg;
			if (PeekMessage(&msg, 0, m_nInternalMessageID, m_nInternalMessageID, PM_NOREMOVE))
			{
				//Send resume message
				LogMessage(__FILE__, __LINE__, this, FZ_LOG_DEBUG, _T("Message waiting in queue, resuming later"));
				TriggerEvent(FD_WRITE);
				UpdateStatusBar(false);
				return;
			}
			UpdateStatusBar(false);
				
			if (GetState() != closed)
				currentBufferSize = m_pOwner->GetAbleToUploadSize( beenWaiting);
			else
				currentBufferSize = BUFSIZE;

			if (m_bufferpos < currentBufferSize)
			{
				numread = ReadDataFromFile(m_pBuffer + m_bufferpos, static_cast<int>(currentBufferSize - m_bufferpos));
				if (numread < 0 )
					return;
				else if (!numread && !m_bufferpos)
				{
					if (ShutDown() || GetLastError() != WSAEWOULDBLOCK)
					{
						Close();
						if (!m_bSentClose)

⌨️ 快捷键说明

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