4.4.2 定义CFtp类
CFtp类是用户自定义实现FTP功能和原理非常重要的类。在本节中,用户将学习到怎样在VC环境中定义和封装CFtp类。首先定义头文件Ftp.h,代码如下:
- class CFtp //定义CFtp类
- {
- public:
- CString ipaddr,name,password; //IP地址、用户名、密码
- int port; //端口号码
- BOOL FTPConnect(CString severhost,int port); //连接FTP服务器
- CSocket *m_clientsocke; //套接字对象
- CArchive *archive; //串行化对象
- CSocketFile *socketfile; //套接字文件对象
- private:
- CString Recv(); //接收命令消息
- Void Send(CString st);//发送命令消息
- Void UpdataFile(CString str); //上传文件
- Void DownLoadFile(CString str1); //下载文件
- Void GetFileStatu(char ch);//获取文件属性
- }
从上面的CFtp类声明中,用户可以看到FTP编程(www.cppentry.com)相关的数据和实现方法。下面将根据FTP基本功能介绍每个函数。首先,客户端应该连接服务器,登录方式为匿名。其函数实现如下:
- BOOL CFtp::FTPConnect(CString severhost,int port)
- {
- CSocket *m_clientsocket=new CSocket(); //构造连接套接字对象
- m_clientsocket->Create(21,SOCK_STREAM,FD_READ|FD_WRITE,NULL);
- //创建流式套接字
- if(!m_clientsocket) //判断套接字对象创建是否成功
- { MessageBox("套接字创建失败!");
- return false; } //创建m_clientsocket失败
- if(!(m_clientsocket->Connect((atoi)severhost,port)))
- return false; //连接FTP服务器
- else
- { return true;} //连接成功将返回true
- }
客户端连接FTP服务器,成功则返回true,否则返回false。如果连接成功,则需要向服务器发送命令以初始化服务器和获取服务器文件列表。函数Send()定义如下:
- Void CFtp::Send(CString charstring) // Send()函数发送信息到服务器
- { CSocketFile * socketfile; //定义对象指针
- socketfile =new CSocketFile(m_clientsocket);
- //关联对象m_clientsocket是创建的套接字
- archive=new CArchive(&m_sockfile,CArchive::load| CArchive::store);
- //创建对象m_archive的实例并指定属性
- charstring=""USER"+lymlrl+"PASS"+123456"; //构造字符串charstring
- archive.WriteString(" "+"\r\n"); //向服务器发送空字符串进行初始化
- try{
- archive ->WriteString(charstring +"\r\n");
- //调用CArchive类的WriteString发送命令
- archive ->Flush(); //强制写入命令到服务器
- }
- Catch(CException e)//处理被抛出的异常
- {
- MessageBox("发送关闭命令失败!");
- }
- }
当命令发送后,服务器会返回客户端请求的数据。函数Recv()的实现如下:
- // Recv()函数接收服务器返回的数据
- CString CFtp::Recv()
- {
- CString recvstr=" "; //初始化字符串recvstr为空
- if(archive->ReadString(recvstr)) //接收返回信息并放到recvstr变量
- {
- if(recvstr==" ") MessageBox("接收数据为空"); //如果接收的数据为空则提示
- { MessageBox("接收数据成功");
- return recvstr; //返回数据
- }}//返回接收到的数据
- else
- {
- MessageBox("接收数据失败");
- }//提示接收数据失败
- }
函数Recv()利用"archive->ReadString(recvstr)"读取服务器返回的数据或者其他信息。其中,包括文件的属性等信息。用户可以从服务器返回的数据中读取文件的属性。函数实现如下:
- Void CFtp::GetFileStatu(char car) //参数car表示接收到的数据
- {
- char buf[100]={0}; //用于保存临时数据
- char ch="a"; //初始化字符变量
- CString str=""; //定义字符串
- int i=0,j=0; //定义循环变量
- for(int i=0;i<1024;i++) //循环解析消息数据以获得一条完整的信息
- {
- if(car[i]!="\")buf[i]==car[i]; //取得的
信息不是"\",则保存到临时变量 - else
- {
- if(car[i+1]=="r")MessageBox("成功解析一条消息!");
- //如果取得的是结束符号,则提示成功提取
- }
- }
- while(ch!=""&&i<1024)
- {
- if(buf[i]!=""&&buf[i+1]==EOF)str+=(CString)buf[i];
- //如果不是空格,则保存在字符串变量中
- else
- {
- ch=buf[i+1]; //如果是空格,则移动到下一个字符
- i+=1;
- j+=1;
- str=""; //将字符串变量重新设置
- }
- switch(j)//根据变量j进行选择信息字符段
- {
- case 1:
- MessageBox("文件最后一次保存的日期是:%c",str);
- //打印文件各属性
- case 2:
- MessageBox("文件最后一次保存的时间是:%c",str);
- case 3:
- MessageBox("文件的大小是:%c",atoi(str));
- case 4:
- MessageBox("文件的名称是:%c",str);
- }
- }
- }
函数GetFileStatu()根据参数car所指向的接收内容数组,通过循环方式获取一条完整的信息,然后再从这条信息中取得各属性。
CFtp类中很重要的作用是上传和下载文件,这两个功能的实现方法如下:
- Void CFtp::UpdataFile(CString str) //参数
str表示上传文件的路径 - {
- archive->WriteString("STOR "+"\r\n");
- //调用CArchive类的WriteString()函数发送STOR命令
- char buff[1024]={0}; //设置缓冲区
- SOCKET sock; //与服务器建立连接成功后返回的套接字句柄
- CFile file(str,CFile::modeReadWrite); //关联文
件对象并指定文件属性为可读可写 - file.Read(buff,1024); //读取文件内容到缓冲区中
- file.close(); //读取完毕,关闭文件
- ::Send(sock,buff,1024,NULL); //调
用Send()函数发送文件内容到FTP文件 - }
函数UpdataFile()根据参数str所指定的本地文件路径上传文件。首先读取本地文件内容到缓冲区中,利用函数Send()将缓冲区的内容发送到服务器。下载文件函数DownLoadFile()的实现方法与函数UpdataFile()一样,其具体实现如下:
- Void CFtp::DownLoadFile(CString filename)
- //参数filename表示从列表中获取的文件名
- {
- int lenth; //已经获取的文件大小
- int i=0;
- archive->WriteString("RETR "+"\r\n");
- //调用CArchive类的WriteString()函数发送RETR命令
- archive->WriteString(filename +"\r\n"); //向
服务器发送将要下载的文件名称 - char buff[1024]={0}; //设置缓冲区
- SOCKET sock; //与服务器建立连接成功后返回的套接字句柄
- CFile file(filename,CFile::modeReadWrite); //
建立文件并指定文件属性为可读可写 - while(lenth!=0)
- {
- ::Recv(sock,buff,1024,NULL); //在套接字上接收数据到缓冲区中
- file.Write(buff,1024); //将缓冲区内容写到文件中
- lenthlenth=lenth-1024;//从文件总大小中减去已经接收并写入文件中的大小
- }
本节封装了CFtp类发送命令、接收数据、获取文件属性和上传下载文件等FTP主要操作。用户在程序中使用该类时,应将其头文件"Ftp.h"和"Ftp.cpp"加入到工程中,然后创建CFtp类对象对各函数进行调用即可。