版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ftp服务器与客户端设计与开发ftp服务器与客户端设计与开发详细设计程序包括5个主要功能:1 .服务器的运行:启动和停止ftp服务2 .用户管理:添加用户,删除用户和设置用户权限3 .服务器配置:设置服务器开放端口,最大连接数等4 .运行统计:统计当前服务器运行时期上传下载的流量等等5 .安全设置:允许连接服务器的ip列表,以及禁止访问的ip服务器的运行模块功能:负责ftp服务器的运行。使用类:c 类,capplicationdlg 类,clistensocket 类,cconnectthread 类,cconnectsocket 类各种类的功能:1 .c类:是cwnd的子类,作为程序的顶层类
2、,负责实现或者调用各个成员函数2 . capplicationdlg类:cdialog类的子类,实现程序主窗口。3 .clistensocket类:负责监听ftp客户端连接,并实现有效连接4 . cconnectthread类:负责实现并保证多个连接的有效性。5 .cconnectsocket类:实现ftp命令的解析,数据的发送和接收c类作为服务器的顶层类,实现服务器开始运行时的所有成员函数 申明如下:class c : public cwnd (friend cconnectsocket;/cconnectsocket作为其友元类,可以访问内部私有数据成 员public:void setgo
3、odbyemessage(lpctstr ipsztext);发送退出信息void setwelcomemessage (lpctstr ipsztext);发送欢迎信息void settimeout (int nvalue);设置暂停时间void setport(int nvalue);设置端口void setmaxusers (int nvalue);设置最大连接数void setstatisticsinterval (int nvalue);统计时间间隔bool isactive();是否有效void stop ();bool start 0;c();virtual co;cuserma
4、nager m_us er manager; /用户管理对象csecuritymanager m_securityxanager; 安全策略c类最主要的成员函数是start。和stop o,分别负贵ftp服务器的开始运行和结束运行 函数声明如下:/*/*/*/*/*/*/*/* function name : start/* description : start listining on port 21 and accept new/*connections./*/*/ bool coif (m_brunning)return false;/如果运行,返回错误标志/ 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;开始创建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服务器与客户端设计与开发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 类用于监听每个客户的连接,clistensocket类是casyncsocket的子类,其成员函数listen 监听来自客户端的连接,当监听到可以接收的socket的时候通过onaccept函数准备创建 有效连接的进程。函数如下: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类负责为每个有效进程创建一个线程,每个进程完成数据传输的所有任务, 穿件县城后通过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;)线程结束以后,通过exitinstance函数实现资源的释放代码如下: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;)为了了解传输过程中接收和发送的字节数,使用increceivedbytes和incsentbytes来计 算。这两个函数在cconnectsocket类中调用,代码如下: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服务器与客户端设计与开发每个线程都是通过一个c
22、connectsocket对象m_connectsocket来完成数据的接受和发送。 当线程创建成功以后,m_connectsocket对象通过onreceive函数获得数据,然后利用 parsecommand函数来解析其中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 函数是当前程序最重要的一个部分,它根据客户端提交的各种命令进行相应的操作代码如下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服务器与客户端设计与开发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)(设置用户主目录 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服务器与客户端设计与开发)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服务器与客户端设计与开发)
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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 飞机透明件制造胶接装配工安全生产意识强化考核试卷含答案
- 殡仪服务员成果转化水平考核试卷含答案
- 生活垃圾填埋作业工保密知识考核试卷含答案
- 松香工岗前安全专项考核试卷含答案
- 2025年厦门清大海峡私募基金管理有限公司人员招聘备考题库及答案详解(易错题)
- 钒铁熔化还原工6S执行考核试卷含答案
- 润滑脂装置操作工安全检查考核试卷含答案
- 炭黑生产工复测水平考核试卷含答案
- 液压支架工操作水平强化考核试卷含答案
- 2025年滨海镇实验幼儿园保育员招聘备考题库及答案详解(夺冠系列)
- 住房按揭借款合同
- 四年级四年级下册阅读理解20篇(附带答案解析)经典
- GB/T 17846-2024小艇电动舱底泵
- 2024年江苏信息职业技术学院高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 板材行业销售渠道分析
- 2024地面用晶体硅光伏组件环境适应性测试要求第1部分:一般气候条件
- 洼田饮水试验评定量表
- 《煤气安全作业》培训教材
- 概率论与数理统计期末考试卷附答案
- 穴位注射水针专题宣讲
- 《髋臼骨缺损分型》
评论
0/150
提交评论