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

📄 connectsocket.cpp

📁 It can also accept a number of ftp connection (multithreaded), and with most of the commercial ftp s
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/********************************************************************/
/*																	*/
/*  CONNECTSOCKET.CPP												*/
/*																	*/
/*  Implementation of the Connect Socket.							*/
/*	This class is a part of the ConnectThread which handles			*/
/*  socket connections. Incomming data is processed in OnReceive	*/
/*																	*/
/*  Programmed by Pablo van der Meer								*/
/*	http://www.pablovandermeer.nl									*/
/*																	*/
/*  Last updated: 10 july 2002										*/
/*																	*/
/********************************************************************/

#include "stdafx.h"
#include "FTPServerApp.h"
#include "FTPServer.h"
#include "ConnectSocket.h"
#include "ConnectThread.h"
#include "ApplicationDlg.h"
#include "DataSocket.h"

extern CFTPServer theServer;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/********************************************************************/
/*																	*/
/* Function name : CConnectSocket::CConnectSocket					*/
/* Description   : Constructor										*/
/*																	*/
/********************************************************************/
CConnectSocket::CConnectSocket()
{
	m_bLoggedon = FALSE;
	m_bRenameFile = FALSE;

	// reset transfer status
	m_TransferStatus.m_pDataSocket = NULL;
	m_TransferStatus.m_strRemoteHost = "";
	m_TransferStatus.m_nRemotePort = -1;
	m_TransferStatus.m_bPassiveMode = FALSE;
	m_TransferStatus.m_nRest = -1;
}


/********************************************************************/
/*																	*/
/* Function name : CConnectSocket::~CConnectSocket					*/
/* Description   : Destructor										*/
/*																	*/
/********************************************************************/
CConnectSocket::~CConnectSocket()
{
	DestroyDataSocket();

	// tell our thread we have been closed
	AfxGetThread()->PostThreadMessage(WM_QUIT,0,0);

	TRACE0("CConnectSocket destroyed.\n");
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CConnectSocket, CSocket)
	//{{AFX_MSG_MAP(CConnectSocket)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0


/********************************************************************/
/*																	*/
/* Function name : OnClose											*/		
/* Description   : Send WM_QUIT message to the thread containing	*/
/*				   the socket to shutdown once the connection is	*/
/*                 closed.											*/
/*																	*/
/********************************************************************/
void CConnectSocket::OnClose(int nErrorCode) 
{
	Close();
	// destroy connection
	m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
	TRACE("CConnectSocket() OnClose()\n");

	CSocket::OnClose(nErrorCode);
}


#define BUFFERSIZE 4096

/********************************************************************/
/*																	*/
/* Function name : OnReceive										*/		
/* Description   : Called by the framework to notify this socket	*/
/*                 that there is data in the buffer.				*/
/*																	*/
/********************************************************************/
void CConnectSocket::OnReceive(int nErrorCode) 
{
	TCHAR buff[BUFFERSIZE];

	int nRead = Receive(buff, BUFFERSIZE);
	switch (nRead)
	{
		case 0:
			Close();
			break;

		case SOCKET_ERROR:
			if (GetLastError() != WSAEWOULDBLOCK) 
			{
				TCHAR szError[256];
				wsprintf(szError, "OnReceive error: %d", GetLastError());
				
				AfxMessageBox (szError);
			}
			break;

		default:
			if (nRead != SOCKET_ERROR && nRead != 0)
			{
				((CConnectThread *)AfxGetThread())->IncReceivedBytes(nRead);

				// terminate the string
				buff[nRead] = 0; 
				m_RxBuffer += CString(buff);
				
				GetRxLine();
			}	
			break;
	}
	CSocket::OnReceive(nErrorCode);
}


/********************************************************************/
/*																	*/
/* Function name: GetRxCommand										*/		
/* Description  : Get command from receiver buffer.					*/
/*																	*/
/********************************************************************/
BOOL CConnectSocket::GetRxCommand(CString &strCommand, CString &strArguments)
{
	if (!m_strCommands.IsEmpty())
	{
		CString strBuff = m_strCommands.RemoveHead();
		int nIndex = strBuff.Find(" ");
		if (nIndex != -1)
		{
			CString strPassword = strBuff;
			strPassword.MakeUpper();
			// make password invisible
			if (strPassword.Left(5) == "PASS ")
			{
				strPassword = strBuff.Left(5);
				for (int i=0; i<strBuff.GetLength()-5; i++)
					strPassword += "*";
				FireStatusMessage(strPassword, 1);
			}
			else
			{
				FireStatusMessage(strBuff, 1);
			}
			strCommand = strBuff.Left(nIndex);
			strArguments = strBuff.Mid(nIndex+1);
		}
		else
		{
			FireStatusMessage(strBuff, 1);
			strCommand = strBuff;
		}

		if (strCommand != "")
		{
			strCommand.MakeUpper();

			// who screwed up ???
			if (strCommand.Right(4) == "ABOR")
			{
				strCommand = "ABOR";
			}
			
			TRACE2("COMMAND: %s, ARGS: %s\n", strCommand, strArguments);
			return TRUE;
		}
	}
	return FALSE;
}


/********************************************************************/
/*																	*/
/* Function name: GetRxLine											*/		
/* Description  : Parse complete command line						*/
/*																	*/
/********************************************************************/
void CConnectSocket::GetRxLine()
{
	CString strTemp;
	int nIndex;

	while(!m_RxBuffer.IsEmpty())
	{
		nIndex = m_RxBuffer.Find("\r\n");
		if (nIndex != -1)
		{
			strTemp = m_RxBuffer.Left(nIndex);
			m_RxBuffer = m_RxBuffer.Mid(nIndex + 2);
			if (!strTemp.IsEmpty())
			{
				m_strCommands.AddTail(strTemp);
				// parse and execute command
				ParseCommand();
			}
		}
		else
			break;
	}
}


/********************************************************************/
/*																	*/
/* Function name: OnConnect											*/		
/* Description  : Called by the framework to notify this connecting	*/
/*				  socket that its connection attempt is completed.  */
/*																	*/
/********************************************************************/
void CConnectSocket::OnConnect(int nErrorCode) 
{
	CSocket::OnConnect(nErrorCode);
}


/********************************************************************/
/*																	*/
/* Function name: HasConnectionDropped								*/		
/* Description  : Check if connection has been dropped.				*/
/*				  Used to detect if client has crashed.				*/
/*																	*/
/********************************************************************/
BOOL CConnectSocket::HasConnectionDropped(void)
{
	BOOL bConnDropped = FALSE;
	INT iRet = 0;
	BOOL bOK = TRUE;
	
	if (m_hSocket == INVALID_SOCKET)
		return TRUE;

	struct timeval timeout = { 0, 0 };
	fd_set readSocketSet;
	
	FD_ZERO(&readSocketSet);
	FD_SET(m_hSocket, &readSocketSet);
	
	iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
	bOK = (iRet > 0);
	
	if(bOK)
	{
		bOK = FD_ISSET(m_hSocket, &readSocketSet);
	}
	
	if(bOK)
	{
		CHAR szBuffer[1] = "";
		iRet = ::recv(m_hSocket, szBuffer, 1, MSG_PEEK);
		bOK = (iRet > 0);
		if(!bOK)
		{
			INT iError = ::WSAGetLastError();
			bConnDropped = (( iError == WSAENETRESET) ||
				(iError == WSAECONNABORTED) ||
				(iError == WSAECONNRESET) ||
				(iError == WSAEINVAL) ||
				(iRet == 0));
		}
	}
    return(bConnDropped);
}


/********************************************************************/
/*																	*/
/* Function name: SendResponse										*/		
/* Description  : Send response to client.							*/
/*																	*/
/********************************************************************/
BOOL CConnectSocket::SendResponse(CString strData)
{
	// is connection still active ?
	if (HasConnectionDropped())
	{
		FireStatusMessage("could not send reply, disconnected.", 2);	

		Close();
		// tell our thread we have been closed
		
		// destroy connection
		m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
		return FALSE;
	}

	int nBytes = CSocket::Send(strData + "\r\n", strData.GetLength()+2);
	if (nBytes == SOCKET_ERROR)
	{
		Close();
		FireStatusMessage("could not send reply, disconnected.", 2);	

		// tell our thread we have been closed
		m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);

		return FALSE;
	}

	FireStatusMessage(strData, 2);

	((CConnectThread *)AfxGetThread())->IncSentBytes(nBytes);
	return TRUE;
}


/********************************************************************/
/*																	*/
/* Function name: ParseCommand										*/		
/* Description  : Parse and execute command from client.			*/
/*																	*/
/********************************************************************/
void CConnectSocket::ParseCommand()
{
	static CFTPCommand commandList[] = 
	{
		{TOK_USER,	"USER", TRUE},
		{TOK_PASS,	"PASS", TRUE},
		{TOK_CWD,	"CWD",	TRUE},
		{TOK_PWD,	"PWD",	FALSE},
		{TOK_PORT,	"PORT", TRUE},
		{TOK_PASV,	"PASV", FALSE},
		{TOK_TYPE,	"TYPE", TRUE},
		{TOK_LIST,	"LIST", FALSE},
		{TOK_REST,	"REST", TRUE},
		{TOK_CDUP,	"CDUP", FALSE},
		{TOK_RETR,	"RETR", TRUE},
		{TOK_STOR,	"STOR", TRUE},
		{TOK_SIZE,	"SIZE", TRUE},
		{TOK_DELE,	"DELE", TRUE},
		{TOK_RMD,	"RMD",	TRUE},
		{TOK_MKD,	"MKD",	TRUE},
		{TOK_RNFR,	"RNFR", TRUE},
		{TOK_RNTO,	"RNTO", TRUE},
		{TOK_ABOR,	"ABOR", FALSE}, 
		{TOK_SYST,	"SYST", FALSE},
		{TOK_NOOP,	"NOOP", FALSE},
		{TOK_BYE,	"BYE",  FALSE},
		{TOK_QUIT,	"QUIT",  FALSE},
		{TOK_ERROR,	"",		FALSE},
	};
	
	// parse command
	CString strCommand, strArguments;
	if (!GetRxCommand(strCommand, strArguments))
	{
		return;
	}

	int nCommand;

	// find command in command list
	for (nCommand = TOK_USER; nCommand < TOK_ERROR; nCommand++)
	{

⌨️ 快捷键说明

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