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

📄 connectsocket.cpp

📁 vc++6.0开发网络典型应用实例导航 1. 本光盘提供了本书中所有的实例源程序文件。 2. 附录文件夹下是Winsock 函数参考以及错误码列表
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			// delete existing datasocket
			DestroyDataConnection();

			// create new data socket
			m_pDataSocket = new CDataSocket(this, -1);

			if (!m_pDataSocket->Create())
			{
				DestroyDataConnection();	
				SendResponse("421 Failed to create socket.");
				break;
			}
			// start listening
			m_pDataSocket->Listen();
			m_pDataSocket->AsyncSelect();
			
			CString strIP, strTmp;
			UINT nPort;
			
			// get our ip address
			GetSockName(strIP, nPort);
			// retrieve port
			m_pDataSocket->GetSockName(strTmp, nPort);
			// replace dots 
			strIP.Replace(".",",");
			// tell the client which address/port to connect to
			SendResponse("227 Entering Passive Mode (%s,%d,%d).", strIP, nPort/256, nPort%256);
			m_bPassiveMode = TRUE;
			break;
		} 

		// list current directory (or a specified file/directory)
		case TOK_LIST:
		case TOK_DIR:
		{
			// if not PASV mode, we need a PORT comand first
			if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
			{
				SendResponse("503 Bad sequence of commands.");
			}
			else
			{
				// if client did not specify a directory use current dir
				if (strArguments == "")
				{
					strArguments = m_strCurrentDir;
				}
				else
				{
					// check if argument is file or directory
					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:
						// create socket connection to transfer directory listing
						if (!CreateDataConnection(0, strListing))
						{
							DestroyDataConnection();
						}
						break;
				}
			} 
			break;
		} 
		
		// retrieve file
		case TOK_RETR:
		{
			// if not PASV mode, we need a PORT comand first
			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:
					// create socket connection for file transfer
					if (!CreateDataConnection(1, strResult))
					{
						DestroyDataConnection();
					}
					break;
			}
			break;	
		}

		// client wants to upload file
		case TOK_STOR:
		{
			// if not PASV mode, we need a PORT comand first
			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:
					// create socket connection for file transfer
					if (!CreateDataConnection(2, strResult))
					{
						DestroyDataConnection();
					}
					break;
			}
		}
		break;
		
		// get file size
		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;
		
		// delete file
		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:
					// delete the file
					if (!DeleteFile(strResult))
					{
						SendResponse("450 Internal error deleting the file: \"%s\".",  strArguments);
					}
					else
					{
						SendResponse("250 File \"%s\" was deleted successfully.", strArguments);
					}
					break;
			}
		}
		break;
		
		// remove directory
		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:
					// remove the directory
					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;	
		
		// create directory
		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:
					// create directory structure
					if (!MakeSureDirectoryPathExists(strResult))
					{
						SendResponse("450 Internal error creating the directory.");
					}
					else
					{
						SendResponse("250 Directory created successfully.");
					}
					break;
			}
		}
		break;
		
		// rename file or directory (part 1)
		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
			{
				// client wants to rename directory
				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;

		// rename file or directory (part 2)
		case TOK_RNTO:
		{
			if (m_strRenameFile.IsEmpty())
			{
				SendResponse("503 Bad sequence of commands.");
				break;
			}
			if (m_bRenameFile)
			{
				CString strResult;
				// check destination filename
				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:
						// rename file
						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;
				// check destination directory name
				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:
						// rename directory
						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;

		// abort transfer
		case TOK_ABOR:
		{
			if (m_pDataSocket)
			{
				if (m_pDataSocket->GetStatus() != XFERMODE_IDLE)
				{
					SendResponse("426 Data connection closed.");
				}
				// destroy data connection
				m_pThread->PostThreadMessage(WM_THREADMSG, 0, 0);
			}
			SendResponse("226 ABOR command successful.");
			break;
		} 

		// get system info
		case TOK_SYST:
			SendResponse("215 UNIX emulated by Pablo's FTP Server.");
			break;
		
		// close connection
		case TOK_QUIT:
		case TOK_BYE:
		{
			// send goodbye message to client
			CConnectThread *pThread = (CConnectThread *)m_pThread;
			SendResponse("220 %s", ((CFTPServer *)pThread->m_pWndServer)->GetGoodbyeMessage());

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

		// restart transfer
		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;

		// display help
		case TOK_HELP:
			// if client did not specify a command, display all available commands
			if (strArguments == "")
			{
				CString strResponse = "214-The following commands are recognized:\r\n";
				// find command in command list
				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;
				// find command in command list
				for (nHelpCmd = TOK_ABOR; nHelpCmd < TOK_ERROR; nHelpCmd++)
				{
					// found command ?
					if (strArguments.CompareNoCase(commandList[nHelpCmd].m_pszName) == 0)
					{
						break;			
					}
				}
				if (nHelpCmd != TOK_ERROR)
				{
					// show help about command
					SendResponse("214 %s", commandList[nHelpCmd].m_pszDescription);
				}
				else
				{
					SendResponse("501 Unknown command %s", strArguments);
				}
			}
			break;

		// dummy instruction
		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 + -