FTP服務(wù)器與客戶端設(shè)計與開發(fā)_第1頁
FTP服務(wù)器與客戶端設(shè)計與開發(fā)_第2頁
FTP服務(wù)器與客戶端設(shè)計與開發(fā)_第3頁
FTP服務(wù)器與客戶端設(shè)計與開發(fā)_第4頁
FTP服務(wù)器與客戶端設(shè)計與開發(fā)_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、ftp服務(wù)器與客戶端設(shè)計與開發(fā)ftp服務(wù)器與客戶端設(shè)計與開發(fā)詳細(xì)設(shè)計程序包括5個主要功能:1 .服務(wù)器的運(yùn)行:啟動和停止ftp服務(wù)2 .用戶管理:添加用戶,刪除用戶和設(shè)置用戶權(quán)限3 .服務(wù)器配置:設(shè)置服務(wù)器開放端口,最大連接數(shù)等4 .運(yùn)行統(tǒng)計:統(tǒng)計當(dāng)前服務(wù)器運(yùn)行時期上傳下載的流量等等5 .安全設(shè)置:允許連接服務(wù)器的ip列表,以及禁止訪問的ip服務(wù)器的運(yùn)行模塊功能:負(fù)責(zé)ftp服務(wù)器的運(yùn)行。使用類:c 類,capplicationdlg 類,clistensocket 類,cconnectthread 類,cconnectsocket 類各種類的功能:1 .c類:是cwnd的子類,作為程序的頂層類

2、,負(fù)責(zé)實現(xiàn)或者調(diào)用各個成員函數(shù)2 . capplicationdlg類:cdialog類的子類,實現(xiàn)程序主窗口。3 .clistensocket類:負(fù)責(zé)監(jiān)聽ftp客戶端連接,并實現(xiàn)有效連接4 . cconnectthread類:負(fù)責(zé)實現(xiàn)并保證多個連接的有效性。5 .cconnectsocket類:實現(xiàn)ftp命令的解析,數(shù)據(jù)的發(fā)送和接收c類作為服務(wù)器的頂層類,實現(xiàn)服務(wù)器開始運(yùn)行時的所有成員函數(shù) 申明如下:class c : public cwnd (friend cconnectsocket;/cconnectsocket作為其友元類,可以訪問內(nèi)部私有數(shù)據(jù)成 員public:void setgo

3、odbyemessage(lpctstr ipsztext);發(fā)送退出信息void setwelcomemessage (lpctstr ipsztext);發(fā)送歡迎信息void settimeout (int nvalue);設(shè)置暫停時間void setport(int nvalue);設(shè)置端口void setmaxusers (int nvalue);設(shè)置最大連接數(shù)void setstatisticsinterval (int nvalue);統(tǒng)計時間間隔bool isactive();是否有效void stop ();bool start 0;c();virtual co;cuserma

4、nager m_us er manager; /用戶管理對象csecuritymanager m_securityxanager; 安全策略c類最主要的成員函數(shù)是start。和stop o,分別負(fù)貴ftp服務(wù)器的開始運(yùn)行和結(jié)束運(yùn)行 函數(shù)聲明如下:/*/*/*/*/*/*/*/* function name : start/* description : start listining on port 21 and accept new/*connections./*/*/ bool coif (m_brunning)return false;/如果運(yùn)行,返回錯誤標(biāo)志/ create dummy

5、 window for message routingif (!cwnd: :createex(o, afxregisterwndclass (0), notification sinkv, ws_popup, 0,0,0,0, null, 0)/ ifaddtraceline(o, failed to create notification window.); return false;開始創(chuàng)建socket(m_listensocket. create(m_nport)/ start listening if (m_listensocket. listeno)m_listensocket.

6、m_pwndserver = this; m_brunning = true;settimer(1, m_nstatisticsinterval, null);addtraceline(0, started on port %d,, m_nport); return true;)addtraceline(0, failed to listen on port %d, m_nport);/ destroy notification window if (iswindow(m_hwnd)destroywindow();m.hwnd = null;1 / 32ftp服務(wù)器與客戶端設(shè)計與開發(fā)retur

7、n false; )/*, jt*/*/*/*/* function name : stop/* description : stop ./*/*,void c()if (!m_brunning)return;/ stop statistics timer killtimer(l);m_brunning = false;m_listensocket. close 0;cconnectthread* pthread = null;/ close all running threads do(m_criticalsection. locko ;position pos = m_threadlist

8、. getheadpositiono; if (pos != null) (pthread = (cconnectthread *)m_threadlist. getat(pos);m_criticalsection. unlock 0;/ save thread membersint nthreadid = pthread-m_nthreadid;handle hthread = pthread-m_hthread;addtraceline(o, %d shutting down thread.nthreadid);/ tell thread to stoppthread-setthread

9、priority(thread_priority_highest);pthread-postthreadmessage(wm_quit, 0, 0);/ wait for thread to end, while keeping the messages pumping (max 5 seconds)if (waitwithmessageloop(hthread, 5000) = false) (/ thread doesn,t want to stoppedaddtraceline(o, ad problem while killing thread.nthreadid);/ dont tr

10、y again, so removem_criticalsection. locko ;position rmpos = m_threadlist. find(pthread); if (rmpos != null)m_threadlist. removeat(rmpos);m_criticalsection. unlock 0 ;) else ( addtraceline(o, rd thread successfully stopped. ”, nthreadid);) else ( m_criticalsection. unlock 0; pthread = null;)while (p

11、thread != null);addtraceline(o, stopped. ,,);if (iswindow(m_hwnd) destroywindowo ;m.hwnd = null; )clistensocket 類用于監(jiān)聽每個客戶的連接,clistensocket類是casyncsocket的子類,其成員函數(shù)listen 監(jiān)聽來自客戶端的連接,當(dāng)監(jiān)聽到可以接收的socket的時候通過onaccept函數(shù)準(zhǔn)備創(chuàng)建 有效連接的進(jìn)程。函數(shù)如下:void clistensocket:onaccept(int nerrorcode) (/ new connection is being es

12、tablishedcsocket sockit;/ accept the connection using a temp csocket object.accept (sockit);/ create a thread to handle the connection. the thread is created suspended so that we can/ set variables in cconnectthread before it starts executing.cconnectthread* pthread =(cconnectthread*)afxbeginthread(

13、runtime_class(cconnectthread),thread priority normal, 0, create suspended);if (!pthread)(sockit. close 0;traceccould not create thread、); return;)c *pwnd = (c *)m_pwndserver;/ since everything is successful, add the thread to our listpwnd-m_criticalsection. locko ;pwnd-m_threadlist. addtail(pthread)

14、;pwnd-m_criticalsection. unlock0 ;/ save pointerpthread-m_pwndserver = m_pwndserver;/ pass the socket to the thread by passing the socket handle. you cannot pass/ a csocket object across threads.pthread-m_hsocket = sockit. detacho ;/ now start the thread.pthread-resumethread 0;cconnectthread 類cconne

15、ctthread類負(fù)責(zé)為每個有效進(jìn)程創(chuàng)建一個線程,每個進(jìn)程完成數(shù)據(jù)傳輸?shù)乃腥蝿?wù), 穿件縣城后通過initlnstance完成線程的初始化bool cconnectthread::initlnstance0try/ attach the socket handle to a csocket object./ this makes sure that the socket notifications are sent to this thread. m_connectsocket. attach(m_hsocket);m_connectsocket. m_pthread = this;cstri

16、ng strlpaddress;uint nport;m_connectsocket. getpeername(strlpaddress, nport);/ notify server that theres a new connectionm3wndserver-sendmessage(wm_threadstart, (wparam) this, 0);if (c *)m_pwndserver)-checkmaxusers 0)(m_connectsocket. sendresponse c*421 too many users are connected, please try again

17、 later.);postthreadmessage(wm_quit, 0, 0);)elseif (! (c *)m_pwndserver)-isipaddressallowed(stripaddress) (m_connectsocket. sendresponse(421 access denied, ip address was rejected by the server. /z);postthreadmessage (lquit, 0, 0);else(/ send welcome message to clientcstring strtext = (c *)m_pwndserv

18、er)-getwelcomemessage 0;m_connectsocket. sendresponse(220 + strtext); m_ntimerid = :settimer(null, 0, 1000, timerproc);)catch (cexception *e)e-delete();)return true;)線程結(jié)束以后,通過exitinstance函數(shù)實現(xiàn)資源的釋放代碼如下:int cconnectthread::exitinstance0c *pwnd = (c *)m_pwndserver;try (pwnd-m_criticalsection. lock 0;/

19、delete this thread from the linked list position pos = pwnd-m_threadlist. find(this); if(pos != null) (pwnd-m_threadli st. removeat(pos);)pwnd-m_criticalsection. unlock 0;/ notify service main loop pwnd-sendmessage(w.threadclose, (wparam) this, 0);)catch(cexception *e) (pwnd-m_criticalsection. unloc

20、k 0;e-delete();)return cwinthread::exitinstance 0;)為了了解傳輸過程中接收和發(fā)送的字節(jié)數(shù),使用increceivedbytes和incsentbytes來計 算。這兩個函數(shù)在cconnectsocket類中調(diào)用,代碼如下:void cconnectthread::incsentbytes(int nbytes) (m_lastdatatransfertime = ctime::getcurrenttime0;m_nsentbytes += nbytes;/ notify server classm_pwndserver-postmessage(

21、lthwmsg, (wparam) 0, (lparam) nbytes);)void cconnectthread::increceivedbytes(int nbytes) (m_lastdatatransfertime = ctime::getcurrenttime0;m_nreceivedbytes += nbytes;/ notify server classm_pwndserver-postmessage(lthre!sg, (wparam) 1, (lparam) nbytes);)cconnectsocket 類 7 / 32ftp服務(wù)器與客戶端設(shè)計與開發(fā)每個線程都是通過一個c

22、connectsocket對象m_connectsocket來完成數(shù)據(jù)的接受和發(fā)送。 當(dāng)線程創(chuàng)建成功以后,m_connectsocket對象通過onreceive函數(shù)獲得數(shù)據(jù),然后利用 parsecommand函數(shù)來解析其中ftp命令void cconnectsocket::onreceive(int nerrorcode) (tchar buffbuffersize;int nread = receive(buff, buffersize);switch (nread)case 0:close 0 ;break;case socket.error:if (getlasterroro != w

23、saewouldblock) (tchar szerror256;wsprintf (szerror, /?0nreceive error:與d”, getlasterroro);afxmessagebox (szerror); ) break;default:if (nread != socket_error & nread != 0) (cconnectthread *)afxgetthread0)-increceivedbytes(nread);/ terminate the stringbuffnread = 0;m_rxbuffer += cstring(buff);getrxlin

24、e0;) break;)csocket:0nreceive(nerrorcode);)parsecommand 函數(shù)是當(dāng)前程序最重要的一個部分,它根據(jù)客戶端提交的各種命令進(jìn)行相應(yīng)的操作代碼如下void cconnectsocket::parsecommandostatic c 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.l

25、ist,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”,

26、 false,tok.quit,quit”, falsetok_error,false),);/ parse commandcstring strcommand, strarguments;if (igetrxcommand(strcommand, strarguments) (return;)int ncommand;查找命令for (ncommand = tok_user; ncommand tok_pass & !m_bloggedon) (sendresponse(,/530 please log in with user and pass first. /z); return;)/

27、proces command switch(ncommand) / specify usernamecase tok.user: (strarguments. makelower 0 ;m_bloggedon = false;m_strusername = strarguments;cstring strpeeraddress;uint npeerport;getpeername(strpeeraddress, npeerport);/ tell a new user has connected cconnectthread *pthread = (cconnectthread *)m_pth

28、read; (c*) pthread-m_pwndserver)-m_peventsink-on(m_pthread-m_nthreadid, m_strusername, strpeeraddress);9 / 32ftp服務(wù)器與客戶端設(shè)計與開發(fā)sendresponse (/?331 password required for + strarguments);)break;/ specify password case tok.pass: (/ already logged on ?if (m_bloggedon) (sendresponse(,/503 bad sequence of co

29、mmands.);) else (/ check user and password cuser user;if (theserver. m-usermanager. checkuser (m_strusernanie, strarguments, user)(設(shè)置用戶主目錄 m_strcurrentdir = 7”;/成功登錄提示m_bloggedon = true;sendresponse(230 logged on);)else sendresponse(z,530 login or password incorrect!);) break;/ change current direct

30、orycase t0kj2wd:(int nresult = theserver. m_usermanager. changedirectory (m_strusername, m_strcurrentdir, strarguments);cstring str;switch(nresult) (case 0:str. format (?,250 cwd successful.is current directory.,z,m_strcurrentdir);sendresponse(str);break;case 1:str. format (/z550 cwd failed. 與s”: pe

31、rmission denied.,z, strarguments);sendresponse(str);break;default:str. format (/z550 cwd failed.directory not found.”,strarguments);sendresponse(str);break;) break;/ print current directorycase t0k_pwd:(cstring str;str. format (?,257 s is current directory, /z, m_strcurrentdir); sendresponse(str);)

32、break;/ specify ip and port (port al, a2, a3, a4, pl, p2) - ip address al. a2. a3. a4, port pl*256+p2.case tok.port:(cstring strsub;int ncount=0;while (afxextractsubstring(strsub, strarguments, ncount+, (switch(ncount)(case 1: / alm transferstatus. m strremotehost = strsub;m transferstatus. m strrem

33、otehost +=.;break;case 2: / a2m transferstatus. m strremotehost += strsub;m transferstatus. m strremotehost +=,;break;case 3: / a3m transferstatus. m strremotehost += strsub;m transferstatus. m strremotehost +=,;break;case 4: / a4m transferstatus. m strremotehost += strsub;break;case 5: / plm_transf

34、erstatus. m_nremoteport = 256*atoi(strsub); break;case 6: / p2m_transferstatus. m_nremoteport += atoi(strsub); break;)m transferstatus. m bpassivemode = false;sendresponse(z,200 port command successful); break;)/ switch to passive modecase tok.pasv:(/ delete existing datasocket destroydatasocket 0;/

35、 create new data socketm_transferstatus. m_pdatasocket = new cdatasocket (this, -1);if (!m_transferstatus. m_pdatasocket-create 0)(destroydatasocket 0;sendresponse(,/421 cant create socket);break;)/ start listeningm_transferstatus. m_pdatasocket-listen();m_transferstatus. m_pdatasocket-asyncselect 0

36、;cstring strip, strtmp;uint nport;/ get our ip addressgetsockname(strip, nport);/ now retrieve the portm_transferstatus. m_pdatasocket-getsockname(strtmp, nport);/ reformat the ipstrlp. replaced );/ tell the client which address/port to connect tocstring str;str. format c227 entering passive mode (%

37、s, %d, %d)/z, strlp, nport/256, nport%256);sendresponse(str);m transferstatus. m bpassivemode = true;break;case tok.type:(sendresponse (/z200 type set to + strarguments);)break;/ list current directorycase tok.list:(if(!m_transferstatus. m_bpassivemode &(m_transferstatus. m_strremotehost = m_transfe

38、rstatus. 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 directorycstring strresult;int nresult = theserver. m_usermanager. get(m_strusernam

39、e, strarguments, m_strcurrentdir, , strresult);if (nresult = 0)(strarguments = strresult;13 / 32ftp服務(wù)器與客戶端設(shè)計與開發(fā))cstring strlisting; int nresult =theserver. m_usermanager. getdirectorylist(m_strusername, strarguments, strlisting);switch(nresult)(case 1:sendresponse(,/550 permission denied);break;case

40、 2:sendresponsec?550 directory not found);break;default:if (!m_transferstatus. m_bpassivemode)(cdatasocket *pdatasocket = new cdatasocket(this, 0);pdatasocket-create 0;pdatasocket-setdata(strlisting);pdatasocket-asyncselect 0;m_transferstatus. m_pdatasocket = pdatasocket; if(!pdatasocket-connect(m_t

41、ransferstatus. m_strremotehost, m_transferstatus. m_nremoteport)if (getlasterror 0 != wsaewouldblock)(sendresponse(425 can t open data connection/z);break;)sendresponse (/z150 opening data channel for directory list. *);) else (m_transferstatus. m_pdatasocket-setdata (strlisting);m_transferstatus. m

42、_pdatasocket-settransfert5rpe (0);) break; )break;)/ change to parent directorycase tok.cdup: (cstring strdirectory = cstring str;int nresult = theserver. m_usermanager. changedirectory (m_strusername, m_strcurrentdir, strdirectory);switch(nresult) ( case 0:str. format (250 cwd successful.is current

43、 directory.m_strcurrentdir);sendresponse (str);break;case 1:str. format (/z550 cwd failed.permission denied.strdirectory);sendresponse(str);break;case 2:str. format (/z550 cwd failed.directory not found.”,strdirectory);sendresponse(str); break;) break;/ retrieve file case tok.retr: (if(!m_transferst

44、atus. m_bpassivemode &(m_transferstatus. m_strremotehost = m_transferstatus. m_nremoteport = -1) (sendresponse(,z503 bad sequence of commands.); break;)cstring strresult;int nresult = theserver. m_usermanager. get(m_strusername, strarguments, m_strcurrentdir, , strresult);switch(nresult)case 1:sendr

45、esponse(z,550 permission denied);break;case 2:sendresponse(550 found);break;default:if (!m_transferstatus. m-bpassivemode) (cdatasocket *pdatasocket = new cdatasocket(this, 1); m_transferstatus. m_pdatasocket = pdatasocket;pdatasocket-create 0;pdatasocket-asyncselect 0; pdatasocket-setdata(strresult

46、); if(pdatasocket-connect(m_transferstatus. m_strremotehost , m_transferstatus. m_nrem oteport) = 0)(if (getlasterroro != wsaewouldblock)(sendresponse (,z425 cant open data connection); break;)sendresponse (z/150 opening data channel for .“); ) else m_transferstatus. m_pdatasocket-setdata(strresult)

47、; m_transferstatus. m_pdatasocket-settransfertype(l);) break;) break;)/ client wants to upload filecase tok.stor:(if(m_transferstatus. m_bpassivemode = -1)(sendresponse (,z503 bad sequence of commands.;break;)if(!m_transferstatus. m_bpassivemode &(m_transferstatus. m_strremotehost = m_transferstatus

48、. m_nremoteport = -1) (sendresponse c503 bad sequence of commands.; break;)cstring strresult;int nresult = theserver. m_usermanager. get(m_strusername, starguments, m_strcurrentdir, , strresult);switch(nresult)(case 1:sendresponse(z,550 permission denied);break;case 2:sendresponse(550 invalid);break

49、;default:if (!m_transferstatus. m_bpassivemode) (cdatasocket *pdatasocket = new cdatasocket(this, 2); m_transferstatus. m_pdatasocket = pdatasocket; pdatasocket-create 0;pdatasocket-asyncselect 0; pdatasocket-setdata(strresult);if (pdatasocket-connect(m_transferstatus. m_strremotehost, m_transfersta

50、tus. m_nremoteport) = 0) (if (getlasterroro != wsaewouldblock) (sendresponse(425 cant open data connection); break;)sendresponse (,/150 opening data channel for .“);) else ( m_transferstatus. m_pdatasocket-setdata(strresult); m_transferstatus. m_pdatasocket-settransfertype(2);17 / 32ftp服務(wù)器與客戶端設(shè)計與開發(fā))

51、 break; ) ) break;/ getcase tok.size: (cstring strresult;int nresult = theserver. m_usermanager. get(m_strusername, strarguments, m_strcurrentdir, , strresult);switch(nresult) ( case 1:sendresponse(z,550 permission denied); break;case 2: sendresponse(550 found); break;default: (c status;c(strresult,

52、 status);cstring strresponse;strresponse. format(213 *d, status. m_size); sendresponse(strresponse); break;) break;/ delete filecase t0k_dele: (cstring strresult;int nresult = theserver. m_usermanager. get(m_strusername, strarguments, m_strcurrentdir, , strresult);switch(nresult) ( case 1:sendresponse(z,550 permission denied); break;case 2: sendresponse(550 found); break;default: try ( c(strresult); ) catch(c *e) (e-delete();sendresponse(450 internal err

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論