FTP服务器与客户端设计与开发
详细设计
程序包括5个主要功能
1.服务器的运行:启动和停止FTP服务
2.用户管理添加用户,删除用户和设置用户权限
3.服务器配置设置服务器开放端口,最大连接数等
4.运行统计:统计当前服务器运行时期上传下载的流量等等
5.安全设置允许连接服务器的IP列表以及禁止访问的IP
服务器的运行模块
功能负责F服务器的运行。
使用类 类,CAplic i Dg类 CListnSocket类 Cnecthread类 ConnctS ockt类
各种类的功能
1.C类是CWnd的子类作为程序的顶层类负责实现或者调用各个成员函数
2.Aplica ionDg类:CDialog类的子类,实现程序主窗口。
3.CLi tenSoket类负责监听T客户端连接,并实现有效连接
4.ConnectThred类:负责实现并保证多个连接的有效性。
5.CnnectScket类实现FTP命令的解析,数据的发送和接收
类
作为服务器的顶层类实现服务器开始运行时的所有成员函数
申明如下:
lass :pulic Cd
{fr ed CCnnec ockt;/CConnectocke 作为其友元类,可以访问内部私有数据成员publi:
void StGoodbyeMessage CTSTR pszTxt ;/发送退出信息
vod SetWl eMessae(LPCTSTR lpszTet ;/发送欢迎信息
oid Setmeout(i al );设置暂停时间
oid SetPo t(it nValue) //设置端口vod xUse s int nVa ue ;//设置最大连接数
void StSta isticsInterval(int ale);//统计时间间隔
O O IsActie();/是否有效
void S o()
BOOL S art );
() vir ualC();
CU rManaer //用户管理对象
CSecurityanager;/安全策略
类
最主要的成员函数是start(和stop ) 分别负责ftp服务器的开始运行和结束运行函数声明如下:
/* ******* ** **** ******** ***** ********
********/
/* /
*Funtin ame :Start *
De cr ptio :Strt li inin on rt 1 an accpt new //* onnec ions */
/ *
** ****************** ****************************
**/
BOOLC()
{if (munnng)
n FALSE;/如果运行,返回错误标志
/crea dm wndow for me sag u i
f(!Cd::Cr Ex(0 AxRgis erWndC as s(0), N ifica in ink",S_PPUP, 0,0,0 NL, )
dTacine , Fild to create notifia on w dow.");return FALSE;
/开始创建socketif misteSockt.Cr te m_ort))
{
// tr i teningi (mL s enocket.Listn( )
{
_ListeSocet._pWdSe ve = h
m_bR ning= T RU;
S e Timer( ,m_nStt ticsInterval,NUL ;
d;
}
AdTrceLin(0, " faild to tn o port%. ,mPort);
/de troy no ficatio indow
f(IsWnow(m_hWd )
Destr no();
mhWnd N ULL;
rturn FALE;
}
* *****************************************
*********
/* */
/*Fuction ame Stp /
*D e cription S top . */
/* /
/********************************* ********** *************voi C()
if !m_bunning
rturn;
// stop sttist cs timer
Killim e r 1
_Running FALS E m_i te ocket.lo ( ;
CnnetThre ad*pThr d=ULL;
// e ll rnning thred
d
{
m_C ti lec in.Lock();
POSITION os _Th ad s .GetedPositin();
(po !=NULL)
{
pThead (CConec Thred*)mTreadist.etAt(os)
_C t ca ec in Un ok( ;
/ save trea membrsin nT hr e aID= pTr ->_nT he aI
HN D L hThr ea = T ed-m_hr e a;
AddTracLine(0, " %d]Sht ing wn t ed.. . hreadD //tll hread to stop
pThed- threadPr or tyTHEAD_PRITYHIHT ; Thread>PostTh adMssge(_QUI,0,0);
/ wa t for hrad o end,while keepin te m ges umping(x 5 scods)
i (i WithM aeo op(hTrad,50)== FALS)
//
AdTrceLne(0, "[]Problmhil killig thread. , nTreadID);
//dn't t y agai, so remov
m_r ticlS ectin.c();
POSION rmPo m_Tr dList.Fn phread);
if(rmP o s =NULL)
_TheadLis RmveA (rmPos);
mritica ection.Un oc );
}
el
{
AddTraceLine(0 "[%]Thread scce sfully stpe." nThredID); }
}
else
{m_Criticaletion.Un o ()
pThea =NUL;
}
hi e (pT he a != N ULL)
AdracLne 0, " topped "
if(I do(hWn))
Ds r oWino(
m_n =NUL;
}
Ci t Scket类
用于监听每个客户的连接,CLi teSockt类是CAsyncSockt的子类其成员函数 isten
监听来自客户端的连接,当监听到可以接收的socket的时候通过OAccept函数准备创建有效连接的进程。
函数如下vid CL tnSoket: :OnAcept nt nErrrCoe)
/New nec on is eing estali he
CSoket scki
Acept th connct on sing a te CSckt obj t.
Accept(socki );
/ Create a tred t hndl te connection. Th t ad i reaed suspended so hat we can
/ st ariab e in onnctTh ead before t sta s execut n. CConectTrea pThread=(onetThrea*)AfxegnThrad(RUNTI_CAS S(ConnctThread), THEAD_IRIY_ORMA 0, CRASUSENED);
f (!pTh ad)
{socki lo e()
RAE "Could not ra theadn");
tun;
}
C*Wn =(C*m_pWnder r;
ine eve ytig s suces fl, dd the thr d t ou li t Wn->mriticalS e ion ock ;pWnd->mThreadList.AddTail(pThead)
Wnd->m_ri i lSetion.Un ock( ;
// ae pointer
pTrad-WnSr r= Wde ve ;
//Pass the socke to the the passig he so t hndle You nnot pa
/ a Cocketojectacross eads.
Trea->mS oce =sockit.et h();
// w ta t th read.
pThread>Re umeThread(
}
CConnecthead类
CCnnectThead类负责为每个有效进程创建一个线程,每个进程完成数据传输的所有任务,穿件县城后通过 itInstance完成线程的初始化
OOL C nectThread :Ii ns ance()
{
try
{
//Attac the socke handle to a Sce objct.
/ Th make re tat te ocke noti ications are sent to th thread.
mConnctSockt.ttch(m_hSo e )
_ConectS ocktm_pThred= his
Strig strIPdd s ;
IT Por ;
m_o ec ocket GtPeerNam( trIPAddrss, P t ;
/otif se e that there
m_pWnd rvr->ene sg(_HRASTAR, (WPARA th s,);
i (( C*m_W Se ver ->ChecMaUsrs )
connectd
P ThredMssage(_UIT,0 0);
}
e se
if( (C*)mWdServer -I IPddre sA lowd(strIPAddress))
{
y te server.");
tTredMessage(WM_UIT,,);
}e se
/ send wlom messge o client
C rin strText =((C* _nd rvr)->Get cmeessge( ;
;
m_ime I = :SetTmer(UL,0, 000,TmerProc ;
}
}
ath(Exception *e)
{
e->Dle e( ;
}
urn TRUE;
}
线程结束以后通过Ei Instnce函数实现资源的释放代码如下:
n CCnnectThread: xitIstance(
C *pWnd (C )m_pWndS e ver;try
{
pWnd->m_Cr ti lSc .Lo ();
/ d t th read rom the line li
POSIION ps= Wnd-m_TheaL s .Find(t s);
(pos ! NUL)
{
pnd>m_radLi .Rmovt ps);
}
pWnd-m_Cri ialS ec ion.Unlock();
// notify service main lop
pWn->SendMe sge(_HEDCLOS, (WPARAM)this,
}
catch(Eception
{pWd->_ i iclS ect on.Unlock()
e-Del e()
}retur CWinThread: :Eit stance( ;
}
为了了解传输过程中接收和发送的字节数使用ncRecei tes和IncSentytes来计算。这两个函数在Connec ce 类中调用,代码如下:
oid CConctTr d: :IncSntte in nByte
m_L Dtrans erTie = Cie: :Ge urrentTm();
// n i serer class
mnd rer-Ps e s sag WM_THREAMS, (WPARA 0, (LPAAM)nB y e ;
}
vid CConnectThead InRce vedByte (int nytes)
{
m_a tD ataTras e Tme =Cme: e CrrentTime();
_nRceived e +=nBytes;
/noti y erver ass
m_pndS erver->Po tes age(WM_THREADS G, (WPAA)1 (LPARAnBytes)
CConnectocke 类
每个线程都是通过一个CConetocke 对象m_onectScket来完成数据的接受和发送。当线程创建成功以后m_ConnectS et对象通过nReceiv函数获得数据,然后利用ParseCommand函数来解析其中FT命令vid Connect cket: :OnRce e(i nErrorCode)
THR bff[BUFFRS ZE ;it nReadReeive(buf, FFERS Z);
wi ch (Read)
case 0:
Close()
bek;
case SCKET_EROR
if (e LstError( =WSEWO ULB LO)
{
TCA szError[256 ;wpritf srror());
fxss eBox( rror
}
bea;
efault:
f(Read = O C KET_ROR& Read != 0)
{
((ConnetThead*)AfGe Thr d())>InReceivdBy sRed); /te minate he str g
buf[nead]=
m_RxB u ff += S trin(bff)
e tRLin )
}
rek;
}
Cokt: :Onec e(nErr Cod)
}
ParseComnd函数
是当前程序最重要的一个部分它根据客户端提交的各种命令进行相应的操作代码如下vid ConnctSck : PrsCmad()
{
sta i C ommanList ]=
{
{O KUR "U S E",RU ,
{T O_PAS "PAS S , RUE ,
_CW "", TRUE}
TOKPWD, "WD", FASE}
{_OR, POT", TR ,
{T O K_ASV PAS , FLS E},
{OK_YP, "TYPE",TRU},
{TK_LIT, "I", ALE},
{T_RST, REST",RUE},
{TO_CDUP "CDUP" FALSE ,
{T O K_ET R "ETR",T RE},
{TOK_STOR, "STO T},
TOK_IZ "IZ" TRU},
{O KD ELE, "DL",TRU}
TOK_MD "MD", TRE},
{K_KD, M KD", RU E},
{T O K_NR, "RNF",T RU E},
{TK_RTO, RTO",TRU ,
TOK_ABOR "ABO ALSE ,
{T O K_SYST, "SYST", FALE ,
TOK_NOOP, "OOP , FALS}
TO_BY, , FALS ,
{TOKQT, "UT", FASE},
{TOK_ROR "", FLS},
;
/ parse comman
C ring strCommnd st Aget if(!etRxomad(st Cmmand rArguments))
{
如今我们还有在做个人网站吗?随着自媒体和短视频的发展和兴起,包括我们很多WEB2.0产品的延续,当然也包括个人建站市场的低迷和用户关注的不同,有些个人已经不在做网站。但是,由于我们有些朋友出于网站的爱好或者说是有些项目还是基于PC端网站的,还是有网友抱有信心的,比如我们看到有一些老牌个人网站依旧在运行,且还有新网站的出现。今天在这篇文章中谈谈有网友问关于个人网站备案的问题。这个也是前几天有他在选择...
Virtono是一家成立于2014年的国外VPS主机商,提供VPS和服务器租用等产品,商家支持PayPal、信用卡、支付宝等国内外付款方式,可选数据中心共7个:罗马尼亚2个,美国3个(圣何塞、达拉斯、迈阿密),英国和德国各1个。目前,商家针对美国圣何塞机房VPS提供75折优惠码,同时,下单后在LET回复订单号还能获得双倍内存的升级。下面以圣何塞为例,分享几款VPS主机配置信息。Cloud VPSC...
恒创科技也有暑期的活动,其中香港服务器也有一定折扣,当然是针对新用户的,如果我们还没有注册过或者可以有办法注册到新用户的,可以买他们家的香港服务器活动价格,2M带宽香港云服务器317元。对于一般用途还是够用的。 活动链接:恒创暑期活动爆款活动均是针对新用户的。1、云服务器仅限首次购买恒创科技产品的新用户。1 核 1G 实例规格,单个账户限购 1台;其他活动机型,单个账户限购 3 台(必须在一个订单...