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

📄 connectsocket.cpp

📁 用套接字实现的ftp文件传输源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			break;
		}
		
		// 改变到被动模式
		case TOK_PASV:
		{
			// 删除当前的数据连接
			DestroyDataConnection();

			// 创建新的数据套接字连接
			m_pDataSocket = new CDataSocket(this, -1);

			if (!m_pDataSocket->Create())
			{
				DestroyDataConnection();	
				SendResponse("421 Failed to create socket.");
				break;
			}
			//开始侦听
			m_pDataSocket->Listen();
			m_pDataSocket->AsyncSelect();
			
			CString strIP, strTmp;
			UINT nPort;
			
			// 获得我们的IP地址
			GetSockName(strIP, nPort);
			//获得端口号
			m_pDataSocket->GetSockName(strTmp, nPort);
			// 替换"."
			strIP.Replace(".",",");
			// 通知客户端要连接的IP地址和端口
			SendResponse("227 Entering Passive Mode (%s,%d,%d).", strIP, nPort/256, nPort%256);
			m_bPassiveMode = TRUE;
			break;
		} 

		// 列出当前路径
		case TOK_LIST:
		case TOK_DIR:
		{
			// 如果不是被动模式,我们先需要PORT命令指定端口
			if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
			{
				SendResponse("503 Bad sequence of commands.");
			}
			else
			{
				// 如果用户没有指定路径,用当前路径
				if (strArguments == "")
				{
					strArguments = m_strCurrentDir;
				}
				else
				{
					// 检查参数是文件名还是路径
					CString strResult;
					int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_LIST, strResult);
					if (nResult == 0)
					{
						strArguments = strResult;
					}
				}
				CString strListing;
				int nResult = theServer.m_UserManager.GetDirectoryList(m_strUserName, strArguments, strListing);
				switch(nResult)
				{
					case 1:
						SendResponse("550 Permission denied.");
						break;
					case 2:
						SendResponse("550 Directory not found.");
						break;
					default:
						//创建套接字连接获得路径列表
						if (!CreateDataConnection(0, strListing))
						{
							DestroyDataConnection();
						}
						break;
				}
			} 
			break;
		} 
		
		// 获得文件
		case TOK_RETR:
		{
			// 如果不是被动模式,我们先需要PORT命令指定端口
			if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
			{
				SendResponse("503 Bad sequence of commands.");
				break;
			}
			
			CString strResult;
			int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DOWNLOAD, strResult);
			switch(nResult)
			{
				case 1:
					SendResponse("550 Permission denied.");
					break;
				case 2:
					SendResponse("550 File not found.");
					break;
				default:
					//为文件传输创建一个套接字
					if (!CreateDataConnection(1, strResult))
					{
						DestroyDataConnection();
					}
					break;
			}
			break;	
		}

		//客户端上传文件
		case TOK_STOR:
		{
			// 如果不是被动模式,我们先需要PORT命令指定端口
			if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
			{
				SendResponse("503 Bad sequence of commands.");
				break;
			}
			
			CString strResult;
			int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_UPLOAD, strResult);
			switch(nResult)
			{
				case 1:
					SendResponse("550 Permission denied.");
					break;
				case 2:
					SendResponse("550 Filename invalid.");
					break;
				default:
					//为文件传输创建一个套接字
					if (!CreateDataConnection(2, strResult))
					{
						DestroyDataConnection();
					}
					break;
			}
		}
		break;
		
		//获得文件大小
		case TOK_SIZE:
		{
			CString strResult;
			int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DOWNLOAD, strResult);
			switch(nResult)
			{
				case 1:
					SendResponse("550 Permission denied.");
					break;
				case 2:
					SendResponse("550 File not found.");
					break;
				default:
				{
					CFileStatus status;
					CFile::GetStatus(strResult, status);
					SendResponse("213 %d", status.m_size);
					break;
				}
			}
		}
		break;
		
		// 删除文件
		case TOK_DELE:
		{
			CString strResult;
			int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DELETE, strResult);
			switch(nResult)
			{
				case 1:
					SendResponse("550 Permission denied.");
					break;
				case 2:
					SendResponse("550 File not found.");
					break;
				default:
					//删除文件
					if (!DeleteFile(strResult))
					{
						SendResponse("450 Internal error deleting the file: \"%s\".",  strArguments);
					}
					else
					{
						SendResponse("250 File \"%s\" was deleted successfully.", strArguments);
					}
					break;
			}
		}
		break;
		
		// 删除目录
		case TOK_RMD: 
		{
			CString strResult;
			int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_DELETE, strResult);
			switch(nResult)
			{
				case 1:
					SendResponse("550 Permission denied.");
					break;
				case 2:
					SendResponse("550 Directory not found.");
					break;
				default:
					// 删除目录
					if (!RemoveDirectory(strResult))
					{
						if (GetLastError() == ERROR_DIR_NOT_EMPTY)
						{
							SendResponse("550 Directory not empty.");
						}
						else
						{
							SendResponse("450 Internal error deleting the directory.");
						}
					}
					else
					{
						SendResponse("250 Directory deleted successfully.");
					}
					break;
			}
		}
		break;	
		
		// 创建目录
		case TOK_MKD: 
		{
			CString strResult;
			int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_CREATE_DIR, strResult);
			switch(nResult)
			{
				case 0:
					SendResponse("550 Directory already exists.");
					break;
				case 1:
					SendResponse("550 Can't create directory. Permission denied.");
					break;
				default:
					//创建目录
					if (!MakeSureDirectoryPathExists(strResult))
					{
						SendResponse("450 Internal error creating the directory.");
					}
					else
					{
						SendResponse("250 Directory created successfully.");
					}
					break;
			}
		}
		break;
		
		//重命名文件名或者路径
		case TOK_RNFR:
		{
			CString strResult;
			int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
			if (nResult == 0)
			{
				m_strRenameFile = strResult;
				m_bRenameFile = TRUE;
				SendResponse("350 File exists, ready for destination name.");
				break;
			}
			else
			{
				// 用户端重命名目录
				nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
				switch(nResult)
				{
					case 0:
						m_strRenameFile = strResult;
						m_bRenameFile = FALSE;
						SendResponse("350 Directory exists, ready for destination name.");
						break;
					case 1:
						SendResponse("550 Permission denied.");
						break;
					default: 
						SendResponse("550 File/directory not found.");
						break;
				}
			}	
		}
		break;

		// 重命名文件名或目录
		case TOK_RNTO:
		{
			if (m_strRenameFile.IsEmpty())
			{
				SendResponse("503 Bad sequence of commands.");
				break;
			}
			if (m_bRenameFile)
			{
				CString strResult;
				// 检查目标文件名
				int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
				switch(nResult)
				{
					case 0:
						SendResponse("550 File already exists.");
						break;
					case 1:
						SendResponse("550 Permission denied.");
						break;
					default:
						// 重命名文件
						if (!MoveFile(m_strRenameFile, strResult))
						{
							SendResponse("450 Internal error renaming the file: \"%s\".", m_strRenameFile);
						}
						else
						{
							SendResponse("250 File \"%s\" renamed successfully.", m_strRenameFile);
						}
						break;
				}
			}
			else
			{
				CString strResult;
				// 检查目标路径名
				int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
				switch(nResult)
				{
					case 0:
						SendResponse("550 Directory already exists.");
						break;
					case 1:
						SendResponse("550 Permission denied.");
						break;
					case 3:
						SendResponse("550 Directory invalid.");
						break;
					default:
						// 重命名路径
						if (!MoveFile(m_strRenameFile, strResult))
						{
							SendResponse("450 Internal error renaming the directory: \"%s\".", m_strRenameFile);
						}
						else
						{
							SendResponse("250 Directory \"%s\" renamed successfully.", m_strRenameFile);
						}
						break;
				}
			}		
		}
		break;

		// 取消传输
		case TOK_ABOR:
		{
			if (m_pDataSocket)
			{
				if (m_pDataSocket->GetStatus() != XFERMODE_IDLE)
				{
					SendResponse("426 Data connection closed.");
				}
				//销毁数据连接
				m_pThread->PostThreadMessage(WM_THREADMSG, 0, 0);
			}
			SendResponse("226 ABOR command successful.");
			break;
		} 

		// 获得系统信息
		case TOK_SYST:
			SendResponse("215 UNIX emulated by Li's FTP Server.");
			break;
		
		// 关闭连接
		case TOK_QUIT:
		case TOK_BYE:
		{
			// 发送再见消息给客户机
			CConnectThread *pThread = (CConnectThread *)m_pThread;
			SendResponse("220 %s", ((CFTPServer *)pThread->m_pWndServer)->GetGoodbyeMessage());

			Close();
			//通知线程已经结束关闭连接
			m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
			break;
		}

		//重新启动传输
		case TOK_REST:
		{
			if (!IsNumeric(strArguments.GetBuffer(strArguments.GetLength())))
			{
				strArguments.ReleaseBuffer();
				SendResponse("501 Invalid parameter.");
			}
			else
			{
				strArguments.ReleaseBuffer();
				m_dwRestartOffset = atol(strArguments);
				SendResponse("350 Restarting at %d.", m_dwRestartOffset);
			}
		}
		break;

		//显示帮助信息
		case TOK_HELP:
			//如果客户端不指定命令名显示所有可有命令
			if (strArguments == "")
			{
				CString strResponse = "214-The following commands are recognized:\r\n";
				// 在命令列表中查找命令
				for (int i = TOK_ABOR; i < TOK_ERROR; i++)
				{
					strResponse += commandList[i].m_pszName;
					strResponse += "\r\n";
				}
				strResponse += "214 HELP command successful.";
				SendResponse(strResponse);
			}
			else
			{
				int nHelpCmd;
				// 在命令列表中查找命令
				for (nHelpCmd = TOK_ABOR; nHelpCmd < TOK_ERROR; nHelpCmd++)
				{
					//判断是否找到命令
					if (strArguments.CompareNoCase(commandList[nHelpCmd].m_pszName) == 0)
					{
						break;			
					}
				}
				if (nHelpCmd != TOK_ERROR)
				{
					//显示命令帮助信息
					SendResponse("214 %s", commandList[nHelpCmd].m_pszDescription);
				}
				else
				{
					SendResponse("501 Unknown command %s", strArguments);
				}
			}
			break;

		// 空命令
		case TOK_NOOP:
			SendResponse("200 OK");
			break;

		default:
			SendResponse("502 Command not implemented - Try HELP.");
			break;
	}
}


/********************************************************************/
/*																	*/
/* Function name: FireStatusMessage									*/		
/* Description  : Fire status message.								*/
/*																	*/
/********************************************************************/
void CConnectSocket::FireStatusMessage(LPCTSTR lpszStatus, int nType)
{
	CConnectThread *pThread = (CConnectThread *)m_pThread;
	((CFTPServer *)pThread->m_pWndServer)->AddTraceLine(nType, "[%d] %s", m_pThread->m_nThreadID, lpszStatus);
}


/********************************************************************/
/*																	*/
/* Function name: CreateDataConnection								*/		
/* Description  : Create data transfer connection.					*/
/*																	*/
/********************************************************************/
BOOL CConnectSocket::CreateDataConnection(int nTransferType, LPCTSTR lpszData)
{
	if (!m_bPassiveMode)
	{
		m_pDataSocket = new CDataSocket(this, nTransferType);
		if (m_pDataSocket->Create())
		{
			m_pDataSocket->AsyncSelect();
			m_pDataSocket->SetRestartOffset(m_dwRestartOffset);
			m_pDataSocket->SetData(lpszData);

			// connect to remote site
			if (m_pDataSocket->Connect(m_strRemoteHost, m_nRemotePort) == 0)
			{
				if (GetLastError() != WSAEWOULDBLOCK)
				{
					SendResponse("425 Can't open data connection.");
					return FALSE;
				}
			}
			
			switch(nTransferType)
			{
				case 0:
					SendResponse("150 Opening ASCII mode data connection for directory list."); 
					break;
				case 1:
				case 2:
					SendResponse("150 Opening BINARY mode data connection for file transfer.");
					break;
			}
		}
		else
		{
			SendResponse("421 Failed to create data connection socket.");
			return FALSE;
		}
	}
	else
	{
		m_pDataSocket->SetRestartOffset(m_dwRestartOffset);
		m_pDataSocket->SetData(lpszData);
		m_pDataSocket->SetTransferType(nTransferType, TRUE);
	}
	return TRUE;
}


/********************************************************************/
/*																	*/
/* Function name: DestroyDataConnection								*/		
/* Description  : Close data transfer connection.					*/
/*																	*/
/********************************************************************/
void CConnectSocket::DestroyDataConnection()
{
	if (!m_pDataSocket)
		return;

	delete m_pDataSocket;

	// reset transfer status
	m_pDataSocket = NULL;
	m_strRemoteHost = "";
	m_nRemotePort = -1;
	m_dwRestartOffset = 0;
	m_bPassiveMode = FALSE;
}

⌨️ 快捷键说明

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