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))
{
前些天赵容分享过DogYun(狗云)香港BGP线路AMD 5950X经典低价云服务器的信息(点击查看),刚好账户还有点余额够开个最低配,所以手贱尝试下,这些贴上简单测试信息,方便大家参考。官方网站:www.dogyun.com主机配置我搞的是最低款优惠后14.4元/月的,配置单核,512MB内存,10GB硬盘,300GB/50Mbps月流量。基本信息DogYun的VPS主机管理集成在会员中心,包括...
易探云产品限时秒杀&QQ音乐典藏活动正在进行中!购买易探云香港/美国云服务器送QQ音乐绿钻豪华版1年,价值180元,性价比超级高。目前,有四大核心福利产品推荐:福利一、香港云服务器1核1G2M,仅218元/年起(香港CN2线路,全球50ms以内);福利二、美国20G高防云服务器1核1G5M,仅336元/年起(美国BGP线路,自带20G防御);福利三、2G虚拟主机低至58.8元/年(更有免费...
virmach怎么样?virmach家这几年非常火,从商家的黑五闪购开始,以超低的价格吸引了大批的国人客户,而且商家的机器还是非常稳定的,站长手里的4.75刀年付已经用了两年了,非常稳定,不过商家到国内的线路一般,目前商家新上了夏季优惠促销,价格低到发指,年付7.2美元起,商家反馈将在9月开始更换AMD+NVMe平台,这个消息从年初就有了,不过一直没有更换,目前这个时间也不确定是否准确。点击进入:...