分享
 
 
 

用VC++5.0编写Ftp客户程序

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

用VC++5.0编写Ftp客户程序

随着Internet的迅猛发展,网络软件的开发与设计显得越来越重要。最初的网络软件主要是以UNIX操作系统为软件开发环境的,随着Windows个人操作系统的流行,传统的编程界面向这一新的软硬件平台转换变得极为迫切。VC++5.0版的MFC封装了的CSocket类提供了高级的SOCKET支持,为编写因特网环境下基于Windows平台的C/S程序提供了极大的方便。本文通过利用CSocket类编写一个FTP客户程序为例介绍了其使用方法,向你揭开网络编程的秘密。

WINSOCK以动态链接库的形式向程序员提供了一个功能强大的函数集,通过对这个函数集的调用,应用程序可以完成其特定的任务。然而缺点是程序较为繁琐。为了解决这一问题,Microsoft对其推出的Visual C++系列的基本类库(MFC)做了逐步的完善。尤其是新近发行的VC++5.0版,封装了许多与网络程序设计相关的类。CSocket就是其中之一。

CSocket类(父类为CAsyncSocket)提供了一个高级的SOCKET支持,完成对低层函数的操作,大大降低了编程难度。这里,以Windows 95为开发环境,采用Visual C++5.0编写一个Ftp客户程序,来说明如何深入有效地利用CSocket类进行网络软件的开发。考虑到C/S模式下应建立一个Ftp服务器的问题,所以选择Windows 95的4.00.950B版,因为这个版本含有个人Web服务器,提供了HTTP及FTP服务。

首先,建立一个SDI(单文档界面)应用程序的基本框架。这一步比较简单,在VC++5.0中,MFC AppWizard通过创建一个新的项目(Project)而被激活,选择File菜单中的New选项,选取Project,输入文件名为SuperFTP,选择OK。随后的步骤为VC++自动创建过程,可以参见相关资料,不再详述。最后生成以下几个主要类:

CMainFrame,

CSuperFTPApp,

CSuperFTPDoc,

CSuperFTPView,

CAboutDlg。

其次,建立几个新类,如下表:

有关Ftp协议请参考相关资料,这是正确开发Ftp客户程序的重要前提。

第三步,具体程序的编制。由于整个程序比较长,下面给出主要部分的核心代码并附注释。

1.MainFrm.cpp:

……

CMainFrame::CMainFrame()

//初始化指针

m_ctrlconn=NULL;

m_dataconn=NULL;

m_recvconn=NULL;

//选择菜单项“快速连接”

void CMainFrame::OnQuickconnect()

if(!Makeconn())

MessageBox(“FTP控制链路建立失败!”,“提示”,MB_ICONWARNING);

if(!MakeRemoteDir())

MessageBox(“FTP数据链路建立失败!”,“提示”,MB_ICONWARNING);

//建立控制链路

BOOL CMainFrame::Makeconn()

……

Quickconn dlg;

//输入服务器名,用户名,口令

if (dlg.DoModal()==IDOK)

fservername=dlg.m_servername;

fusername=dlg.m_username;

fpassword=dlg.m_password;

m_ctrlconn=new ctrlsocket();

//建立一个SOCKET

If(!m_ctrlconn->Create(0,SOCK_STREAM,NULL)

delete m_ctrlconn;

m_ctrlconn=NULL;

MessageBox(“Socket()建立失败!”,“提示”,MB_ICONWARNING);

return FALSE;

//申请网络事件通知

If(!m_ctrlconn->AsyncSelect(FD_READ|FD_WRITE|FD_ACCEPT|FD_CONNECT|FD_CLOSE))

MessageBox(“AsyncSelect()错误!”,“提示”,MB_ICNWARNING);

return FALSE;

BeginWaitCursor();

//向由fservername指定的主机发出连接请求

if(!m_ctrlconn->Connect(fservername,IPPORT_FTP))

delete m_ctrlconn;

m_ctrlconn=NULL;

MessageBox(远端服务器连接失败!”,“提示”,MB_ICONWARNING);

return FALSE;

EndWaitCursor();

……

return TRUE;

这里,选择了菜单的“快速连接”项后,执行结果如下图:

如果选择了“匿名”登录,应用程序则自动将用户姓名和口令字填充为:anonymous,guest@unknown

BOOL CMainFrame::MakeRemoteDir()

if(m_ctrlconn==NULL)

(“请连接到服务器!”,“提示”,MB_iconwarwing);

retrurn FALSE;

if(!MakeDataListen())

MessageBox(“数据链路建立失败!”,“提示”,MB_ICONWARNING);

return FALSE;

……

return TRUE;

//处理来自远端服务器的响应

BOOL CMainFrame::Processftp()

………

//建立数据连接“监听”函数

BOOL CMainFrame::MakeDataListen()

……

m_dataconn=new Listensocket();

/* 建立一个SOCKET,并与本地主机地址捆绑。作为一个例子,直接插入了本机的IP地址“90.0.0.8”,而在实际应用中应首先通过相应的函数调用取得本地主机地址。

注意:如果不采用VC++的CSocket类而用其它的方法,需在建立SOCKET之后,调用bind()函数来进行与本地主机地址的捆绑。*/

if(!m_dataconn->Create(0,SOCK_STREAM,“90.0.0.8”))

delete m_dataconn;

m_dataconn=NULL;MessageBox(“Socket()建立失败!”,“提示”,MB_ICONWARNING);

return FALSE;

//申请网络事件通知

if(!m_dataconn->AsyncSelect(FD_ACCEPT))

delete m_dataconn;

m_dataconn=NULL;

MessageBox(“AsyncSelect()错误!”,“提示”,MB_ICONWARNING);

return FALSE;

……

if(!m_dataconn->Listen(5))

MessageBox(“listen()错误!”,“提示”,MB_ICONWARNING);

return FALSE;

……

//接受数据连接请求的函数

BOOL CMainFrame::AcceptDataConn()

int num,nRet;

SOCKADDR_IN RemoteDataAddr;

num=sizeof(SOCKADDR_IN);

if(m_recvconn==NULL)

m_recvconn=new Datasocket();

if(!m_dataconn->Accept(*m_recvconn,(LPSOCKADDR)&RemoteDataAddr,(int FAR*)&num))

MessageBox(“accept()错误!”,“提示”,MB_ICONWARWING);

return FALSE;

……

m_dataconn->Close();

//申请网络事件通知

if(!m_recvconn->AsyncSelect(FD_READ|FD_WRITE|FD_CLOSE)

MessageBox(“Asyncselect()错误!”,“提示”,MB_ICONWARNING);

return FALSE;

return TRUE;

//数据接受函数,接受来自远端服务器的数据

int CMainFrame::RecvData()

……

int nRet=m_recvconn->Receive(…);

if (nRet>0)

else

……

2.ctrlsocket.cpp

……

void ctrlsocket::OnReceive(int nErrorCode)

//处理网络事件FD_READ

CSocket::OnReceive(nErrorCode);

((CmainFrame *)(AfxGetApp()->m_pMainWnd))->Processftp();

3.Listensocket.cpp

……

void Listensocket::OnAccept(int nErrorCode)

//处理网络事件FD_ACCEPT

CSocket::OnAccept(nErrorCode);

((CmainFrame*)AfxGetApp()->m_pMainWnd))->AcceptDataConn();

4.Datasocket.cpp

……

Datasocket::OnReceive(int nErrorCode)

//处理网络事件FD_READ

CAsyncSocket::OnReceive(nErrorCode);

((CMainFrame*)(AfxGetApp()->m_pMainWnd))->RecvData();

void Datasocket::OnSend(int nErrorCode)

//处理网络事件FD_WRITE

CAsyncSocket::OnSend(nErrorCode);

((CMainFrame*)(AfxGetApp()->m_pMainWnd))->SendData();

程序执行时左下窗口为本地系统,右下窗口为远端系统。通过激活相关的菜单项,就可以对远端主机的文件系统进行下载操作。当然,如果Ftp服务器允许上载,你也可以将自己的文件传送到远端主机。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有