版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
/FTP服务器和客户端设计和开发具体设计程序包括5个主要功能:服务器的运行:启动和停止FTP服务用户管理:添加用户,删除用户和设置用户权限服务器配置:设置服务器开放端口,最大连接数等运行统计:统计当前服务器运行时期上传下载的流量等等平安设置:允许连接服务器的IP列表,以及禁止访问的IP服务器的运行模块功能:负责FTP服务器的运行。运用类:CFTPServer类,CApplicationDlg类,CListenSocket类,CConnectThread类,CConnectSocket类各种类的功能:CFTPServer类:是CWnd的子类,作为程序的顶层类,负责实现或者调用各个成员函数CApplicationDlg类:CDialog类的子类,实现程序主窗口。CListenSocket类:负责监听FTP客户端连接,并实现有效连接CConnectThread类:负责实现并保证多个连接的有效性。CConnectSocket类:实现FTP吩咐的解析,数据的发送和接收CFTPServer类作为服务器的顶层类,实现服务器起先运行时的全部成员函数申明如下:classCFTPServer:publicCWnd{ friendCConnectSocket;//CConnectSocket作为其友元类,可以访问内部私有数据成员public: voidSetGoodbyeMessage(LPCTSTRlpszText);//发送退出信息 voidSetWelcomeMessage(LPCTSTRlpszText);//发送欢迎信息 voidSetTimeout(intnValue);//设置暂停时间 voidSetPort(intnValue);//设置端口 voidSetMaxUsers(intnValue);//设置最大连接数 voidSetStatisticsInterval(intnValue);//统计时间间隔 BOOLIsActive();//是否有效 voidStop(); BOOLStart(); CFTPServer(); virtual~CFTPServer(); CUserManagerm_UserManager;//用户管理对象 CSecurityManagerm_SecurityManager;//平安策略CFTPServer类最主要的成员函数是start()和stop(),分别负责ftp服务器的起先运行和结束运行函数声明如下:/********************************************************************//* *//*Functionname:Start *//*Description:Startlistiningonport21andacceptnew *//* connections. *//* *//********************************************************************/BOOLCFTPServer::Start(){ if(m_bRunning) returnFALSE;//假如运行,返回错误标记 //createdummywindowformessageroutingif(!CWnd::CreateEx(0,AfxRegisterWndClass(0),"FTPServerNotificationSink",WS_POPUP,0,0,0,0,NULL,0)) { AddTraceLine(0,"Failedtocreatenotificationwindow."); returnFALSE; } //起先创建socket if(m_ListenSocket.Create(m_nPort)) { //startlistening if(m_ListenSocket.Listen()) { m_ListenSocket.m_pWndServer=this; m_bRunning=TRUE; SetTimer(1,m_nStatisticsInterval,NULL); AddTraceLine(0,"FTPServerstartedonport%d.",m_nPort); returnTRUE; } } AddTraceLine(0,"FTPServerfailedtolistenonport%d.",m_nPort); //destroynotificationwindow if(IsWindow(m_hWnd)) DestroyWindow(); m_hWnd=NULL; returnFALSE;}/********************************************************************//* *//*Functionname:Stop *//*Description:StopFTPserver. *//* *//********************************************************************/voidCFTPServer::Stop(){ if(!m_bRunning) return; //stopstatisticstimer KillTimer(1); m_bRunning=FALSE; m_ListenSocket.Close(); CConnectThread*pThread=NULL; //closeallrunningthreads do { m_CriticalSection.Lock(); POSITIONpos=m_ThreadList.GetHeadPosition(); if(pos!=NULL) { pThread=(CConnectThread*)m_ThreadList.GetAt(pos); m_CriticalSection.Unlock(); //savethreadmembers intnThreadID=pThread->m_nThreadID; HANDLEhThread=pThread->m_hThread; AddTraceLine(0,"[%d]Shuttingdownthread...",nThreadID); //tellthreadtostop pThread->SetThreadPriority(THREAD_PRIORITY_HIGHEST); pThread->PostThreadMessage(WM_QUIT,0,0); //waitforthreadtoend,whilekeepingthemessagespumping(max5seconds) if(WaitWithMessageLoop(hThread,5000)==FALSE) { //threaddoesn'twanttostopped AddTraceLine(0,"[%d]Problemwhilekillingthread.",nThreadID); //don'ttryagain,soremove m_CriticalSection.Lock(); POSITIONrmPos=m_ThreadList.Find(pThread); if(rmPos!=NULL) m_ThreadList.RemoveAt(rmPos); m_CriticalSection.Unlock(); } else { AddTraceLine(0,"[%d]Threadsuccessfullystopped.",nThreadID); } } else { m_CriticalSection.Unlock(); pThread=NULL; } } while(pThread!=NULL); AddTraceLine(0,"FTPServerstopped."); if(IsWindow(m_hWnd)) DestroyWindow(); m_hWnd=NULL;}CListenSocket类用于监听每个客户的连接,CListenSocket类是CAsyncSocket的子类,其成员函数listen监听来自客户端的连接,当监听到可以接收的socket的时候通过OnAccept函数打算创建有效连接的进程。函数如下:voidCListenSocket::OnAccept(intnErrorCode){ //Newconnectionisbeingestablished CSocketsockit; //AccepttheconnectionusingatempCSocketobject. Accept(sockit); //Createathreadtohandletheconnection.Thethreadiscreatedsuspendedsothatwecan //setvariablesinCConnectThreadbeforeitstartsexecuting. CConnectThread*pThread=(CConnectThread*)AfxBeginThread(RUNTIME_CLASS(CConnectThread),THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); if(!pThread) { sockit.Close(); TRACE("Couldnotcreatethread\n"); return; } CFTPServer*pWnd=(CFTPServer*)m_pWndServer;//sinceeverythingissuccessful,addthethreadtoourlist pWnd->m_CriticalSection.Lock();pWnd->m_ThreadList.AddTail(pThread); pWnd->m_CriticalSection.Unlock(); //savepointer pThread->m_pWndServer=m_pWndServer; //Passthesockettothethreadbypassingthesockethandle.Youcannotpass //aCSocketobjectacrossthreads. pThread->m_hSocket=sockit.Detach(); //Nowstartthethread. pThread->ResumeThread();}CConnectThread类CConnectThread类负责为每个有效进程创建一个线程,每个进程完成数据传输的全部任务,穿件县城后通过InitInstance完成线程的初始化BOOLCConnectThread::InitInstance(){ try { //AttachthesockethandletoaCSocketobject. //Thismakessurethatthesocketnotificationsaresenttothisthread. m_ConnectSocket.Attach(m_hSocket); m_ConnectSocket.m_pThread=this; CStringstrIPAddress; UINTnPort; m_ConnectSocket.GetPeerName(strIPAddress,nPort); //notifyserverthatthere'sanewconnection m_pWndServer->SendMessage(WM_THREADSTART,(WPARAM)this,0); if(((CFTPServer*)m_pWndServer)->CheckMaxUsers()) { m_ConnectSocket.SendResponse("421Toomanyusersareconnected,pleasetryagainlater."); PostThreadMessage(WM_QUIT,0,0); } else if(!((CFTPServer*)m_pWndServer)->IsIPAddressAllowed(strIPAddress)) { m_ConnectSocket.SendResponse("421Accessdenied,IPaddresswasrejectedbytheserver."); PostThreadMessage(WM_QUIT,0,0); } else { //sendwelcomemessagetoclient CStringstrText=((CFTPServer*)m_pWndServer)->GetWelcomeMessage(); m_ConnectSocket.SendResponse("220"+strText); m_nTimerID=::SetTimer(NULL,0,1000,TimerProc); } } catch(CException*e) { e->Delete(); } returnTRUE;}线程结束以后,通过ExitInstance函数实现资源的释放代码如下:intCConnectThread::ExitInstance(){ CFTPServer*pWnd=(CFTPServer*)m_pWndServer; try { pWnd->m_CriticalSection.Lock(); //deletethisthreadfromthelinkedlist POSITIONpos=pWnd->m_ThreadList.Find(this); if(pos!=NULL) { pWnd->m_ThreadList.RemoveAt(pos); } pWnd->m_CriticalSection.Unlock(); //notifyservicemainloop pWnd->SendMessage(WM_THREADCLOSE,(WPARAM)this,0); } catch(CException*e) { pWnd->m_CriticalSection.Unlock(); e->Delete(); } returnCWinThread::ExitInstance();}为了了解传输过程中接收和发送的字节数,运用IncReceivedBytes和IncSentBytes来计算。这两个函数在CConnectSocket类中调用,代码如下:voidCConnectThread::IncSentBytes(intnBytes){ m_LastDataTransferTime=CTime::GetCurrentTime(); m_nSentBytes+=nBytes; //notifyserverclass m_pWndServer->PostMessage(WM_THREADMSG,(WPARAM)0,(LPARAM)nBytes);}voidCConnectThread::IncReceivedBytes(intnBytes){ m_LastDataTransferTime=CTime::GetCurrentTime(); m_nReceivedBytes+=nBytes; //notifyserverclass m_pWndServer->PostMessage(WM_THREADMSG,(WPARAM)1,(LPARAM)nBytes);}CConnectSocket类每个线程都是通过一个CConnectSocket对象m_ConnectSocket来完成数据的接受和发送。当线程创建胜利以后,m_ConnectSocket对象通过OnReceive函数获得数据,然后利用ParseCommand函数来解析其中FTP吩咐voidCConnectSocket::OnReceive(intnErrorCode){ TCHARbuff[BUFFERSIZE]; intnRead=Receive(buff,BUFFERSIZE); switch(nRead) { case0: Close(); break; caseSOCKET_ERROR: if(GetLastError()!=WSAEWOULDBLOCK) { TCHARszError[256]; wsprintf(szError,"OnReceiveerror:%d",GetLastError()); AfxMessageBox(szError); } break; default: if(nRead!=SOCKET_ERROR&&nRead!=0) { ((CConnectThread*)AfxGetThread())->IncReceivedBytes(nRead); //terminatethestring buff[nRead]=0; m_RxBuffer+=CString(buff); GetRxLine(); } break; } CSocket::OnReceive(nErrorCode);}ParseCommand函数是当前程序最重要的一个部分,它依据客户端提交的各种吩咐进行相应的操作代码如下voidCConnectSocket::ParseCommand(){ staticCFTPCommandcommandList[]= { {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}, }; //parsecommand CStringstrCommand,strArguments; if(!GetRxCommand(strCommand,strArguments)) { return; } intnCommand; //查找吩咐 for(nCommand=TOK_USER;nCommand<TOK_ERROR;nCommand++) { //foundcommand? if(strCommand==commandList[nCommand].m_pszName) { //didweexpectanargument? if(commandList[nCommand].m_bHasArguments&&(strArguments=="")) { SendResponse("501Syntaxerror"); return; } break; } } if(nCommand==TOK_ERROR) { //commandisnotinourlist SendResponse("500Syntaxerror,commandunrecognized."); return; } //nocommandsareexceptedbeforesuccessfullloggedon if(nCommand>TOK_PASS&&!m_bLoggedon) { SendResponse("530PleaseloginwithUSERandPASSfirst."); return; } //procescommand switch(nCommand) { //specifyusername caseTOK_USER: { strArguments.MakeLower(); m_bLoggedon=FALSE; m_strUserName=strArguments; CStringstrPeerAddress; UINTnPeerPort; GetPeerName(strPeerAddress,nPeerPort); //tellFTPserveranewuserhasconnected CConnectThread*pThread=(CConnectThread*)m_pThread; ((CFTPServer*)pThread->m_pWndServer)->m_pEventSink->OnFTPUserConnected(m_pThread->m_nThreadID,m_strUserName,strPeerAddress); SendResponse("331Passwordrequiredfor"+strArguments); } break; //specifypassword caseTOK_PASS: { //alreadyloggedon? if(m_bLoggedon) { SendResponse("503Badsequenceofcommands."); } else { //checkuserandpassword CUseruser; if(theServer.m_UserManager.CheckUser(m_strUserName,strArguments,user)) { //设置用户主书目 m_strCurrentDir="/"; //胜利登录提示 m_bLoggedon=TRUE; SendResponse("230Loggedon"); } else SendResponse("530Loginorpasswordincorrect!"); } } break; //changecurrentdirectory caseTOK_CWD: { intnResult=theServer.m_UserManager.ChangeDirectory(m_strUserName,m_strCurrentDir,strArguments); CStringstr; switch(nResult) { case0: str.Format("250CWDsuccessful.\"%s\"iscurrentdirectory.",m_strCurrentDir); SendResponse(str); break; case1: str.Format("550CWDfailed.\"%s\":Permissiondenied.",strArguments); SendResponse(str); break; default: str.Format("550CWDfailed.\"%s\":directorynotfound.",strArguments); SendResponse(str); break; } } break; //printcurrentdirectory caseTOK_PWD: { CStringstr; str.Format("257\"%s\"iscurrentdirectory.",m_strCurrentDir); SendResponse(str); } break; //specifyIPandport(PORTa1,a2,a3,a4,p1,p2)->IPaddressa1.a2.a3.a4,portp1*256+p2. caseTOK_PORT: { CStringstrSub; intnCount=0; while(AfxExtractSubString(strSub,strArguments,nCount++,',')) { switch(nCount) { case1: //a1 m_TransferStatus.m_strRemoteHost=strSub; m_TransferStatus.m_strRemoteHost+="."; break; case2: //a2 m_TransferStatus.m_strRemoteHost+=strSub; m_TransferStatus.m_strRemoteHost+="."; break; case3: //a3 m_TransferStatus.m_strRemoteHost+=strSub; m_TransferStatus.m_strRemoteHost+="."; break; case4: //a4 m_TransferStatus.m_strRemoteHost+=strSub; break; case5: //p1 m_TransferStatus.m_nRemotePort=256*atoi(strSub); break; case6: //p2 m_TransferStatus.m_nRemotePort+=atoi(strSub); break; } } m_TransferStatus.m_bPassiveMode=FALSE; SendResponse("200Portcommandsuccessful"); break; } //switchtopassivemode caseTOK_PASV: { //deleteexistingdatasocket DestroyDataSocket(); //createnewdatasocket m_TransferStatus.m_pDataSocket=newCDataSocket(this,-1); if(!m_TransferStatus.m_pDataSocket->Create()) { DestroyDataSocket(); SendResponse("421Can'tcreatesocket"); break; } //startlistening m_TransferStatus.m_pDataSocket->Listen(); m_TransferStatus.m_pDataSocket->AsyncSelect(); CStringstrIP,strTmp; UINTnPort; //getouripaddress GetSockName(strIP,nPort); //Nowretrievetheport m_TransferStatus.m_pDataSocket->GetSockName(strTmp,nPort); //Reformattheip strIP.Replace(".",","); //telltheclientwhichaddress/porttoconnectto CStringstr; str.Format("227EnteringPassiveMode(%s,%d,%d)",strIP,nPort/256,nPort%256); SendResponse(str); m_TransferStatus.m_bPassiveMode=TRUE; break; } caseTOK_TYPE: { SendResponse("200Typesetto"+strArguments); } break; //listcurrentdirectory caseTOK_LIST: { if(!m_TransferStatus.m_bPassiveMode&&(m_TransferStatus.m_strRemoteHost==""||m_TransferStatus.m_nRemotePort==-1)) { SendResponse("503Badsequenceofcommands."); } else { //ifclientdidnotspecifyadirectoryusecurrentdir if(strArguments=="") { strArguments=m_strCurrentDir; } else { //checkifargumentisfileordirectory CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_LIST,strResult); if(nResult==0) { strArguments=strResult; } } CStringstrListing; intnResult=theServer.m_UserManager.GetDirectoryList(m_strUserName,strArguments,strListing); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Directorynotfound"); break; default: if(!m_TransferStatus.m_bPassiveMode) { CDataSocket*pDataSocket=newCDataSocket(this,0); pDataSocket->Create(); pDataSocket->SetData(strListing); pDataSocket->AsyncSelect(); m_TransferStatus.m_pDataSocket=pDataSocket; if(!pDataSocket->Connect(m_TransferStatus.m_strRemoteHost,m_TransferStatus.m_nRemotePort)) { if(GetLastError()!=WSAEWOULDBLOCK) { SendResponse("425Can'topendataconnection"); break; } } SendResponse("150Openingdatachannelfordirectorylist."); } else { m_TransferStatus.m_pDataSocket->SetData(strListing); m_TransferStatus.m_pDataSocket->SetTransferType(0); } break; } } break; } //changetoparentdirectory caseTOK_CDUP: { CStringstrDirectory=".."; CStringstr; intnResult=theServer.m_UserManager.ChangeDirectory(m_strUserName,m_strCurrentDir,strDirectory); switch(nResult) { case0: str.Format("250CWDsuccessful.\"%s\"iscurrentdirectory.",m_strCurrentDir); SendResponse(str); break; case1: str.Format("550CWDfailed.\"%s\":Permissiondenied.",strDirectory); SendResponse(str); break; case2: str.Format("550CWDfailed.\"%s\":directorynotfound.",strDirectory); SendResponse(str); break; } } break; //retrievefile caseTOK_RETR: { if(!m_TransferStatus.m_bPassiveMode&&(m_TransferStatus.m_strRemoteHost==""||m_TransferStatus.m_nRemotePort==-1)) { SendResponse("503Badsequenceofcommands."); break; } CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_DOWNLOAD,strResult); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Filenotfound"); break; default: if(!m_TransferStatus.m_bPassiveMode) { CDataSocket*pDataSocket=newCDataSocket(this,1); m_TransferStatus.m_pDataSocket=pDataSocket; pDataSocket->Create(); pDataSocket->AsyncSelect(); pDataSocket->SetData(strResult); if(pDataSocket->Connect(m_TransferStatus.m_strRemoteHost,m_TransferStatus.m_nRemotePort)==0) { if(GetLastError()!=WSAEWOULDBLOCK) { SendResponse("425Can'topendataconnection"); break; } } SendResponse("150Openingdatachannelforfiletransfer."); } else { m_TransferStatus.m_pDataSocket->SetData(strResult); m_TransferStatus.m_pDataSocket->SetTransferType(1); } break; } break; } //clientwantstouploadfile caseTOK_STOR: { if(m_TransferStatus.m_bPassiveMode==-1) { SendResponse("503Badsequenceofcommands."); break; } if(!m_TransferStatus.m_bPassiveMode&&(m_TransferStatus.m_strRemoteHost==""||m_TransferStatus.m_nRemotePort==-1)) { SendResponse("503Badsequenceofcommands."); break; } CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_UPLOAD,strResult); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Filenameinvalid"); break; default: if(!m_TransferStatus.m_bPassiveMode) { CDataSocket*pDataSocket=newCDataSocket(this,2); m_TransferStatus.m_pDataSocket=pDataSocket; pDataSocket->Create(); pDataSocket->AsyncSelect(); pDataSocket->SetData(strResult); if(pDataSocket->Connect(m_TransferStatus.m_strRemoteHost,m_TransferStatus.m_nRemotePort)==0) { if(GetLastError()!=WSAEWOULDBLOCK) { SendResponse("425Can'topendataconnection"); break; } } SendResponse("150Openingdatachannelforfiletransfer."); } else { m_TransferStatus.m_pDataSocket->SetData(strResult); m_TransferStatus.m_pDataSocket->SetTransferType(2); } break; } } break; //getfilesize caseTOK_SIZE: { CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_DOWNLOAD,strResult); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Filenotfound"); break; default: { CFileStatusstatus; CFile::GetStatus(strResult,status); CStringstrResponse; strResponse.Format("213%d",status.m_size); SendResponse(strResponse); break; } } } break; //deletefile caseTOK_DELE: { CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_DELETE,strResult); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Filenotfound"); break; default: try { CFile::Remove(strResult); } catch(CFileException*e) { e->Delete(); SendResponse("450Internalerrordeletingthefile."); break; } SendResponse("250Filedeletedsuccessfully"); break; } } break; //removedirectory caseTOK_RMD: { CStringstrResult; intnResult=theServer.m_UserManager.GetDirectory(m_strUserName,strArguments,m_strCurrentDir,FTP_DELETE,strResult); switch(nResult) { case1: SendResponse("550Permissiondenied"); break; case2: SendResponse("550Directorynotfound"); break; default: if(!RemoveDirectory(strResult)) { if(GetLastError()==ERROR_DIR_NOT_EMPTY) SendResponse("550Directorynotempty."); else SendResponse("450Internalerrordeletingthedirectory."); } else { SendResponse("250Directorydeletedsuccessfully"); } break; } } break; //createdirectory caseTOK_MKD: { CStringstrResult; intnResult=theServer.m_UserManager.GetDirectory(m_strUserName,strArguments,m_strCurrentDir,FTP_CREATE_DIR,strResult); switch(nResult) { case0: SendResponse("550Directoryalreadyexists"); break; case1: SendResponse("550Can'tcreatedirectory.Permissiondenied"); break; case3: SendResponse("550Directorynamenotvalid"); break; default: strResult+="\\"; CStringstrDir; BOOLbResult; //createdirectorystructureonepartatatime while(strResult!="") { strDir+=strResult.Left(strResult.Find("\\")+1); strResult=strResult.Mid(strResult.Find("\\")+1); bResult=CreateDirectory(strDir,0); } if(!bResult) { SendResponse("450Internalerrorcreatingthedirectory."); } else SendResponse("250Directorycreatedsuccessfully"); break; } } break; //renamefileordirectory(part1) caseTOK_RNFR: { CStringstrResult; intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_RENAME,strResult); if(nResult==0) { m_strRenameFile=strResult; m_bRenameFile=TRUE; SendResponse("350Fileexists,readyfordestinationname."); break; } else { //clientwantstorenamedirectory nResult=theServer.m_UserManager.GetDirectory(m_strUserName,strArguments,m_strCurrentDir,FTP_RENAME,strResult); switch(nResult) { case0: m_strRenameFile=strResult; m_bRenameFile=FALSE; SendResponse("350Directoryexists,readyfordestinationname."); break; case1: SendResponse("550Permissiondenied"); break; default: SendResponse("550file/directorynotfound"); break; } } } break; //renamefileordirectory(part2) caseTOK_RNTO: { if(m_strRenameFile.IsEmpty()) { SendResponse("503Badsequenceofcommands!"); break; } if(m_bRenameFile) { CStringstrResult; //checkdestinationfilename intnResult=theServer.m_UserManager.GetFileName(m_strUserName,strArguments,m_strCurrentDir,FTP_RENAME,strResult); switch(nResult) { case0: SendResponse("550fileexists"); break; case1: SendResponse("550Permissiondenied"); break; default: if(!MoveFile(m_strRenameFile,strResult)) SendResponse("450Internalerrorrenamingthefile"); else SendResponse("250filerenamedsuccessfully"); break; } } else { CStringstrResult; //checkdestinationdirectoryname intnResult=theServer.m_UserManager.GetDirectory(m_strUserName,strArguments,m_strCurrentDir,FTP_RENAME,strResult); switch(nResult) { case0: SendResponse("550directoryexists"); break; case1: SendResponse("550Permissiondenied"); break; case3: SendResponse("550Filenameinvalid"); break; default: if(!MoveFile(m_strRenameFile,strResult)) SendResponse("450Internalerrorrenamingthefile"); else SendResponse("250filerenamedsuccessfully"); break; } } } break; //aborttransfer caseTOK_ABOR: { if(m_TransferStatus.m_pDataSocket) { if(m_TransferStatus.m_pDataSocket->GetStatus()!=XFERMODE_IDLE) SendResponse("426Connectionclosed;transferaborted."); //destroydatasocket m_pThread->PostThreadMessage(WM_THREADMSG,0,0);// DestroyDataSocket(); } SendResponse("226ABORcommandsuccessful"); break; } //getsysteminfo caseTOK_SYST: SendResponse("215UNIXemulatedbyPablo'sFTPServer"); break; //closeconnection caseTOK_BYE: caseTOK_QUIT: { //sendgoodbyemessagetoclient CConnectThread*pThread=(CConnectThread*)m_pThread; CStringstrText=((CFTPServer*)pThread->m_pWndServer)->GetGoodbyeMessage(); SendResponse("220"+strText); Close(); //tellourthreadwehavebeenclosed //destroyconnection m_pThread->PostThreadMessage(WM_THREADMSG,1,0); break; } //dummyinstruction caseTOK_NOOP: SendResponse("200OK"); break; default: SendResponse("502Commandnotimplemented."); break; }}用户管理模块用户管理模块须要为指定的用户设置相应的权限,通过CUser类,CuserManager类和CDirectory类和CUserAccountsDlg完成CUser类:保存用户名称,密码,书目列表和用户是否被禁止CuserManager类:实现用户管理全部功能CDirectory类:保存书目是否允许下载,上传,重命名,删除创建书目及是否为主书目,CUserAccountsDlg类:实现用户设置的对话框下面介绍CuserManager类的常用的成员函数classCUser:publicCObject{ DECLARE_SERIAL(CUser) CUser(); virtual~CUser();public: virtualvoidSerialize(CArchive&); CUser(constCUser&user); //copy-constructor CUser&operator=(constCUser&user); //=-operator CStringm_strName; CStringm_strPassword; CArray<CDirectory,CDirectory&>m_DirectoryArray; BOOLm_bAccountDisabled;};平安设置模块负责设置须要屏蔽的,允许连接的ip列表。该模块通过CSecurityManager类实现平安设置功能,CSecurityPage类实现设置界面,CSecurityManager类的成员函数如下classCSecurityManager{public: BOOLIsIPAddressBlocked(LPCTSTRlpszIPAddress); BOOLIsIPAddressNonBlocked(LPCTSTRlpszIPAddress); voidUpdateBlockedList(CStringArray&strArray); voidUpdateNonBlockedList(CStringArray&strArray); voidGetNonBlockedList(CStringArray&strArray); voidGetBlockedList(CStringArray&strArray); CSecurityManager(); virtual~CSecurityManager(); BOOLSerialize(BOOLbStoring);protected: CStringArraym_NonBlockedList; CStringArraym_BlockedList; CStringm_strFilename; CCriticalSectionm_CriticalSection;客户端和服务器连接FTP是建立在TCP之上的连接,端口号运用21。若客户端和服务器之间胜利连接,获得服务器根书目的全部文件并在列表框中显示。//连接ftp服务器voidCMyFtpDlg::OnConnect(){ UpdateData(TRUE); //新建对话 m_pInetSession=newCInternetSession(AfxGetAppName(),1,PRE_CONFIG_INTERNET_ACCESS); try { //新建连接对象 m_pFtpConnection=m_pInetSession->GetFtpConnection(m_strServer,m_strUserName, m_strPassword); } catch(CInternetException*pEx) { //获得错误 TCHARszError[1024]; if(pEx->GetErrorMessage(szError,1024)) AfxMessageBox(szError); else AfxMessageBox("Therewasanexception"); pEx->Delete(); m_pFtpConnection=NULL; return; } m_pRemoteFinder=newCFtpFileFind(m_pFtpConnection); //获得服务器根书目的全部文件并在列表框中显示 BrowseDir("",&m_ctrlRemoteFiles,m_pRemoteFinder,&m_arrRemoteFiles);}获得书目和显示在建立的列表框中,显示出远程计算机书目和本地计算机书目。如书目下仍旧有子文件,则在点击“下一层”按钮后,列表框显示该文件的子文件,如该文件已经是文件,那么则不变。//初始化两个列表框控件 SetListCtrlStyle(&m_ctrlLocalFiles); SetListCtrlStyle(&m_ctrlRemoteFiles); AddHeaders(&m_ctrlLocalFiles); AddHeaders(&m_ctrlRemoteFiles); //本地文件书目以c盘为根书目 BrowseDir("c:",&m_ctrlLocalFiles,&m_LocalFinder,&m_arrLocalFiles); returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}voidCMyFtpDlg::OnSysCommand(UINTnID,LPARAMlParam){ if((nID&0xFFF0)==IDM_ABOUTBOX) { CAboutDlgdlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID,lParam); }}//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,//thisisautomaticallydoneforyoubytheframework.voidCMyFtpDlg::OnPaint(){ if(IsIconic())
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年茶叶电商茶园承包经营合同模板4篇
- 2024游艇租赁及水上活动一体化服务合同范本3篇
- 二零二四年度2024年木工雕刻艺术品定制合同3篇
- 二零二五年影视项目投资与导演编剧合作协议3篇
- 二零二五年度海洋资源开发合作变更合同补充协议2篇
- 二零二五年度医疗器械临床试验合同主体责任与权益保障4篇
- 二零二五厂房购置及安装工程合同范本4篇
- 2我向国旗敬个礼 第1课时 说课稿-2024-2025学年道德与法治一年级上册统编版
- 二零二五年度节能合同变更及减排措施协议3篇
- 买卖住宅合同(2024年版)
- 2024年贵州省中考数学真题含解析
- 参考新医大-中央财政支持地方高校发展专项资金建设规
- 《中医内科学关格》课件
- 2024年中国PCB板清洗剂市场调查研究报告
- 《纸管》规范要求
- 【数学】2021-2024年新高考数学真题考点分布汇
- 2024年育婴师合同协议书
- 大班健康教案及教学反思《蜈蚣走路》
- 生活妆课件教学课件
- 2023-2024学年广东省广州市番禺区八年级(上)期末英语试卷
- 山东省房屋市政工程安全监督机构人员业务能力考试题库-上(单选题)
评论
0/150
提交评论