文章目录

  • 1、使用到的库文件
  • 2、测试库文件基本功能
  • 3、FTP协议文件传输系统(文件下载)
  • 4、FTP协议文件传输系统(文件上传)

1、使用到的库文件

库文件下载:

https://download.csdn.net/download/weixin_45715405/85228391?spm=1001.2014.3001.5501

2、测试库文件基本功能

#include "_ftp.h"
Cftp ftp;int main(int argc,char* argv[])
{// 连接ftp服务器,ip地址,用户名,密码,失败返回falseif(ftp.login("172.16.244.2","oracle","oracle")==false){printf("ftp.login(172.16.244.2) failed\n");return -1;}printf("ftp.login(172.16.244.2) ok.\n");// 连接成功之后// 获取ftp服务器aa这个文件的时间,会将时间存储在类的成员变量中m_mtimeif(ftp.mtime("/oracle/ftp/aa")==false){printf("ftp.mtime failed.\n");return -1;}printf("ftp.mtime ok mtime=%s.\n",ftp.m_mtime);// 获取文件大小if(ftp.size("/oracle/ftp/aa")==false){printf("ftp size failed.\n");return -1;}printf("ftp.size size:%d.\n",ftp.m_size);// 列出服务器oracle目录的文件,到/root/bb.list 这个文件中if(ftp.nlist("/oracle","/root/bb.lis")==false){printf("ftp.nlist failed.\n");return -1;}printf("ftp.nlist ok.\n");// 将本地aa.bak这个文件上传到服务器上,// 第三个参数默认是true表示下载 本地和服务器上的文件判断时间是否相等,保证文件的完整性。if(ftp.get("/oracle/ftp/aa","/root/aa.bak",true)==false){printf("ftp.get() failed.\n");return -1;}printf("ftp.get() ok.\n");// 上传文件,// 第三个参数true表示:上传最后一个参数检查判断大小是否相等,保证文件的完整性。if(ftp.put("/root/cc","/oracle/ftp/cc.bak",true)==false){printf("ftp.put() failed.\n");return -1;}printf("ftp.put() ok.\n");// 重命名,服务器上的aa文件,修改为aa.abkif(ftp.ftprename("/oracle/ftp/aa","/oracle/ftp/aa.bak")==false){printf("ftprename faile.\n");return -1;}printf("ftprename ok.\n");ftp.logout();return 0;
}

编译程序,根据自己的存放位置,指定头文件和库所在路径


g++ -g -o ftpclient ftpclient.cpp /root/project_2022-4-12/project/public/_ftp.cpp /root/project_2022-4-12/project/public/_public.cpp  -I /root/project_2022-4-12/project/public -L /root/project_2022-4-12/project/public/ -lftp -lm -lc

可能会报错,找不到库文件,需要配置
Linux下 静态库和动态库 制作使用

3、FTP协议文件传输系统(文件下载)

#include "_ftp.h"void EXIT(int sig);CLogFile logfile;Cftp ftp;struct st_arg
{char host[31];      // 远程服务器的ip和端口int mode;           // 传输某事 1-被动某事,2-主动模式,缺省采用被动模式char username[31];  // 远程服务器ftp的用户名char password[31];  // 远程服务器ftp的密码char remotepath[301];   // 远程服务器存放文件的目录char localpath[301];    // 本地文件存放的目录char matchname[301];    // 待下载文件匹配的规则char listfilename[301]; // 下载前列出服务器文件名的文件int  ptype;             // 文件下载成功后,远程服务器文件的处理方式:1-什么都不做,2-删除,3-备份char remotepathbak[301]; //文件下载成功后,服务器文件的备份目录char okfilename[301];    // 已下载成功文件名清单bool checkmtime;        // 是否需要检查服务端文件的时间,true需要,false不需要,缺省是falseint  timeout;           // 进程心跳的超时时间char pname[51];         // 进程名,建议用ftpgetfiles_后缀的方式
}starg;struct st_fileinfo
{char filename[301];                 // 文件名char mtime[21];                     // 文件时间
};// "<host>172.16.244.2</host><mode>1</mode><username>oracle</username><password>oracle</password><localpath>/tmp/bak</localpath><remotepath>/tmp/surfdata</remotepath><matchname>SURF_ZH*.XML,SURF_ZH*.CSV</matchname><listfilename>/log/ftplist/ftpget.list</listfilename><ptype>1</ptype><remotepathbak>/tmp/surbak</remotepathbak><okfilename>/tmp/ftplist/surfdata.xml</okfilename><checkmtime>true</checkmtime><timeout>80</timeout><pname>ftpgetfiles_surfdata</pname>"bool _xmltoarg(char* strxmlbuffer);     // 把xml解析道参数starg结构中
bool _ftpgetfiles();                    // 下载文件函数
bool LoadListFile();                    // 把ftp.nlist()获取文件名加载到容器中// 加载okfilename文件中的内容到容器vlistfile1中
bool LoadOKFile();
// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4
bool CompVector();
// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件
bool WriteToOKFile();bool AppendToOKFile(struct st_fileinfo* strfilename);vector<struct st_fileinfo> vlistfile1;   // 已下载的文件,从okfilename中加载
vector<struct st_fileinfo> vlistfile2;   // 存放下载前列出服务器文件名的窗口
vector<struct st_fileinfo> vlistfile3;   // 本次不需要下载的文件容器
vector<struct st_fileinfo> vlistfile4;   // 本次需要下载的文件容器// 进程心跳
CPActive PActive;int main(int argc,char* argv[])
{if(argc<3) {printf("param not enough.\n");return -1;}signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if(logfile.Open(argv[1],"a+")==false){printf("logfile.open(%s) failed.\n",argv[1]);return -1;}if(_xmltoarg(argv[2]) == false) return -1;PActive.AddPInfo(starg.timeout,starg.pname);        // 把进程的心跳信息写入共享内存// 登录ftp服务器if(ftp.login(starg.host,starg.username,starg.password,starg.mode)==false){logfile.Write("ftp.login(%s,%s,%s) failed.\n",starg.host,starg.username,starg.password);return -1;}logfile.Write("ftp.login(%s,%s,%s) ok.\n",starg.host,starg.username,starg.password);if(_ftpgetfiles()==false){logfile.Write("_ftpgetfiles() failed.\n");return -1;}ftp.logout();return 0;
}// 加载okfilename文件中的内容到容器vlistfile1中
bool LoadOKFile()
{vlistfile1.clear();CFile file;// 注意:如果程序是第一次下载,okfilename是不存在的,并不是错误,所以返回trueif(file.Open(starg.okfilename,"r")==false) return true;struct st_fileinfo stfileinfo;char strbuffer[501];while(true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));memset(strbuffer,0,sizeof(strbuffer));if(file.Fgets(strbuffer,300,true)==false) break;GetXMLBuffer(strbuffer,"filename",stfileinfo.filename);GetXMLBuffer(strbuffer,"mtime",stfileinfo.mtime);vlistfile1.push_back(stfileinfo);}return true;
}// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4
bool CompVector()
{vlistfile3.clear();vlistfile4.clear();// 把容器2中文件每个文件在容器1中找一遍,找到了 放入容器3中,没找到放入容器4中int i,j;for(i=0;i<vlistfile2.size();i++){for(j=0;j<vlistfile1.size();j++){if((strcmp(vlistfile2[i].filename,vlistfile1[j].filename)==0)&&(strcmp(vlistfile2[i].mtime,vlistfile1[j].mtime)==0)){vlistfile3.push_back(vlistfile2[i]);break;}}if(j==vlistfile1.size()) vlistfile4.push_back(vlistfile2[i]);}
}// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件
bool WriteToOKFile()
{CFile file;if(file.Open(starg.okfilename,"w")==false){logfile.Write("file.open(%s) failed.\n",starg.okfilename); return false;}for(int i=0;i<vlistfile3.size();i++) file.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",vlistfile3[i].filename,vlistfile3[i].mtime);
}bool AppendToOKFile(struct st_fileinfo* strfilename)
{CFile file;if(file.Open(starg.okfilename,"a")==false){logfile.Write("file.open(%s) failed.\n",starg.okfilename);return false;}file.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",strfilename->filename,strfilename->mtime);return true;
}bool LoadListFile()
{vlistfile2.clear();CFile File;if(File.Open(starg.listfilename,"r")==false){logfile.Write("File.Open(%s) failed.\n",starg.listfilename);return false;}struct st_fileinfo stfileinfo;while(true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));if(File.Fgets(stfileinfo.filename,300,true)==false) break;//if(MatchStr(stfileinfo.filename,starg.matchname)==false) continue;if((starg.ptype==1)&&(starg.checkmtime==true)){// 获取ftp服务端文件时间if(ftp.mtime(stfileinfo.filename)==false){logfile.Write("ftp.mtime(%s) failed .\n",stfileinfo.filename);return false;}strcpy(stfileinfo.mtime,ftp.m_mtime);}vlistfile2.push_back(stfileinfo);}return true;
}bool _ftpgetfiles()
{if(ftp.chdir(starg.remotepath)==false){logfile.Write("ftp.chdir(%s) failed.\n",starg.remotepath);return false;}// 调用nlist()方法列出服务器目录的文件if(ftp.nlist(".",starg.listfilename)==false){logfile.Write("ftp.nlist(%s) failed.\n",starg.listfilename);return false;}PActive.UptATime();if(LoadListFile()==false){logfile.Write("LoadListFile() failed.\n");return false;}PActive.UptATime();if(starg.ptype == 1){// 加载okfilename文件中的内容到容器vlistfile1中LoadOKFile();// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4CompVector();// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件WriteToOKFile();// 把vlistfile4中的内容复制到vlistfile2中vlistfile2.clear();vlistfile2.swap(vlistfile4);}PActive.UptATime(); // 更新进程心跳信息// 遍历容器vlistfilechar strremotefilename[301],strlocalfilename[301];for(int i=0;i<vlistfile2.size();i++){SNPRINTF(strremotefilename,sizeof(strremotefilename),300,"%s/%s",starg.remotepath,vlistfile2[i].filename);SNPRINTF(strlocalfilename,sizeof(strlocalfilename),300,"%s/%s",starg.localpath,vlistfile2[i].filename);// 调用ftp.get()方法从服务器下载logfile.Write("get %s ...",strremotefilename);if(ftp.get(strremotefilename,strlocalfilename)==false){logfile.WriteEx("failed.\n");return false;}logfile.WriteEx("ok.\n");PActive.UptATime(); // 更新进程心跳信息// 本地已经下载,就不下载,本地没有就下载// 算法,通过四个容器实现,// v1 已下载,v2加载服务器目录表,v3已下载(第一二个容器都有的,放入),v4代下载(1没有2的放入)// 如果2,下载完之后,删除服务器上的文件if(starg.ptype==1){// 把成功下载后的文件追加到okfile文件中AppendToOKFile(&vlistfile2[i]);}if(starg.ptype == 2){if(ftp.ftpdelete(strremotefilename)==false){logfile.Write("ftp.ftpdelete(%s) failed.\n",strremotefilename);return false;}}// 如果是3,下载完之后,需要备份一下if(starg.ptype == 3) {char strremotefilenamebak[301];SNPRINTF(strremotefilenamebak,sizeof(strremotefilenamebak),300,"%s/%s",starg.remotepathbak,vlistfile2[i].filename);//printf("%s--%s\n",strremotefilename,strremotefilenamebak);if(ftp.ftprename(strremotefilename,strremotefilenamebak)==false){logfile.Write("ftp.ftorename(%s,%s) failed.\n",strremotefilename,strremotefilenamebak);return false;}}}return true;
}bool _xmltoarg(char* strxmlbuffer)
{// 解析xml,得到程序运行的参数memset(&starg,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer,"host",starg.host,30);                     // 远程服务器ip和端口if(strlen(starg.host) == 0){logfile.Write("host is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"mode",&starg.mode);                       // 传输模式, 1-被动,2-主动if(starg.mode!=2) starg.mode = 1;GetXMLBuffer(strxmlbuffer,"username",starg.username,30);             // 远程服务器ftp用户名if(strlen(starg.username) == 0){logfile.Write("username is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"password",starg.password,30);             // 远程服务器ftp密码if(strlen(starg.password) == 0){logfile.Write("password is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"remotepath",starg.remotepath,30);         // 远程服务器存放文件的目录if(strlen(starg.remotepath)==0){logfile.Write("remotepath is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"localpath",starg.localpath,30);           // 本地文件存放的目录if(strlen(starg.localpath)==0){logfile.Write("localpath is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"matchname",starg.matchname,100);          // 待下载文件匹配的规则if(strlen(starg.matchname)==0){logfile.Write("matchname is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"listfilename",starg.listfilename,300);   // 本地文件存放的目录if(strlen(starg.listfilename)==0){logfile.Write("listfilename is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"ptype",&starg.ptype);        // 文件下载后服务器文件处理if((starg.ptype!=1) && (starg.ptype!=2) && (starg.ptype!=3)){logfile.Write("ptype si error.\n"); return false;}GetXMLBuffer(strxmlbuffer,"remotepathbak",starg.remotepathbak,300);     // 下载前列列出服务器文件名if((starg.ptype==3) && (strlen(starg.remotepathbak)==0)){logfile.Write("remotepathbak is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"okfilename",starg.okfilename,300);     // 下载前列列出服务器文件名if((starg.ptype==1) && (strlen(starg.okfilename)==0)){logfile.Write("okfilename is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"checkmtime",&starg.checkmtime);GetXMLBuffer(strxmlbuffer,"timeout",&starg.timeout);if(starg.timeout==0){logfile.Write("timeout is null.\n"); return false;}GetXMLBuffer(strxmlbuffer,"pname",starg.pname,50);if(strlen(starg.pname)==0){logfile.Write("pname is null.\n"); return false;}return true;
}void EXIT(int sig)
{printf("程序退出,sig=%d\n",sig);exit(0);
}
程序需要十几个启动参数,所以我们采用xml格式来构建这个参数,不容易出错程序主要流程:
1、解析xml格式的启动参数,并把它存储到struct st_arg结构体中,遇到写入日子系统中2、连接到ftp服务器3、调用自定义函数_ftpgetfiles()这个函数主要功能是:3.1、切换到指定目录(启动参数给的)3.2、使用ftp类中nlist函数,将目录中的文件写入到指定文件中(启动参数给的)3.3、将存放服务器目录的文件内容用结构体st_fileinfo存储,并存放到容器中(由LoadListFile函数完成)3.4、遍历存储内容的容器(st_fileinfo),进行文件下载大体流程就是这么多,但是,下载文件会分为三种情况:
1、下载完文件之后对服务端文件进行备份(备份目录,启动参数会准备)。
2、下载完文件之后删除服务端文件。
3、因为每次启动都会将服务端文件全部下载一遍,但是我们的需求是只下载,新添加和修改过后的文件,没有修改的没必要下载。

第三种情况具体实现:
1、我们需要准备四个容器
容器1:存放已经下载的文件
容器2:存放列举出当前服务器的文件
容器3:存放本次不需要下载的文件
容器4:存放本次需要下载的文件

具体流程:
1、容器1里面的内容,是通过读取,已下载的文件(这个文件是启动参数指定的)
2、比较容器1,和容器2,要是容器2里面的内容容器1也有就放到容器3,如果没有就放到容器4
3、把容器3的内容覆盖到已下载的文件(这个文件是启动参数指定的)
4、下载容器4中的内容

编译运行

编写makefile文件
all:execl checkproc gzipfiles deletefiles ftpgetfilesPUBINCL = -I/root/project_2022-4-12/project/publicPUBCPP = /root/project_2022-4-12/project/public/_public.cppFTPCPP = /root/project_2022-4-12/project/public/_ftp.cppFTPLIB = -L /root/project_2022-4-12/project/public/ -lftpCFLAGS = -gftpgetfiles:ftpgetfiles.cppg++ $(CFLAGS) -o ftpgetfiles ftpgetfiles.cpp $(PUBINCL) $(PUBCPP) $(FTPCPP) $(FTPLIB) -lm -lcclean:rm -rf  ftpgetfiles

4、FTP协议文件传输系统(文件上传)

和文件下载功能一样,只是将下载的函数换成了上传

#include "_public.h"
#include "_ftp.h"// 程序运行参数的结构体。
struct st_arg
{char host[31];           // 远程服务端的IP和端口。int  mode;               // 传输模式,1-被动模式,2-主动模式,缺省采用被动模式。char username[31];       // 远程服务端ftp的用户名。char password[31];       // 远程服务端ftp的密码。char remotepath[301];    // 远程服务端存放文件的目录。char localpath[301];     // 本地文件存放的目录。char matchname[101];     // 待上传文件匹配的规则。int  ptype;              // 上传后客户端文件的处理方式:1-什么也不做;2-删除;3-备份。char localpathbak[301];  // 上传后客户端文件的备份目录。char okfilename[301];    // 已上传成功文件名清单。int  timeout;            // 进程心跳的超时时间。char pname[51];          // 进程名,建议用"ftpputfiles_后缀"的方式。
} starg;// 文件信息的结构体。
struct st_fileinfo
{char filename[301];   // 文件名。char mtime[21];       // 文件时间。
};vector<struct st_fileinfo> vlistfile1;    // 已上传成功文件名的容器,从okfilename中加载。
vector<struct st_fileinfo> vlistfile2;    // 上传前列出客户端文件名的容器,从nlist文件中加载。
vector<struct st_fileinfo> vlistfile3;    // 本次不需要上传的文件的容器。
vector<struct st_fileinfo> vlistfile4;    // 本次需要上传的文件的容器。// 加载okfilename文件中的内容到容器vlistfile1中。
bool LoadOKFile();// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4。
bool CompVector();// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件。
bool WriteToOKFile();// 如果ptype==1,把上传成功的文件记录追加到okfilename文件中。
bool AppendToOKFile(struct st_fileinfo *stfileinfo);// 把localpath目录下的文件加载到vlistfile2容器中。
bool LoadLocalFile();CLogFile logfile;Cftp ftp;// 程序退出和信号2、15的处理函数。
void EXIT(int sig);void _help();// 把xml解析到参数starg结构中。
bool _xmltoarg(char *strxmlbuffer);// 上传文件功能的主函数。
bool _ftpputfiles();CPActive PActive;  // 进程心跳。int main(int argc,char *argv[])
{if (argc!=3) { _help(); return -1; }// 关闭全部的信号和输入输出。// 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。// 但请不要用 "kill -9 +进程号" 强行终止。CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT);// 打开日志文件。if (logfile.Open(argv[1],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[1]); return -1;}// 解析xml,得到程序运行的参数。if (_xmltoarg(argv[2])==false) return -1;PActive.AddPInfo(starg.timeout,starg.pname);  // 把进程的心跳信息写入共享内存。// 登录ftp服务端。if (ftp.login(starg.host,starg.username,starg.password,starg.mode)==false){logfile.Write("ftp.login(%s,%s,%s) failed.\n",starg.host,starg.username,starg.password); return -1;}// logfile.Write("ftp.login ok.\n");  // 正式运行后,可以注释这行代码。_ftpputfiles();ftp.logout();return 0;
}// 上传文件功能的主函数。
bool _ftpputfiles()
{// 把localpath目录下的文件加载到vlistfile2容器中。if (LoadLocalFile()==false){logfile.Write("LoadLocalFile() failed.\n");  return false;}PActive.UptATime();   // 更新进程的心跳。if (starg.ptype==1){// 加载okfilename文件中的内容到容器vlistfile1中。LoadOKFile();// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4。CompVector();// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件。WriteToOKFile();// 把vlistfile4中的内容复制到vlistfile2中。vlistfile2.clear(); vlistfile2.swap(vlistfile4);}PActive.UptATime();   // 更新进程的心跳。char strremotefilename[301],strlocalfilename[301];// 遍历容器vlistfile2。for (int ii=0;ii<vlistfile2.size();ii++){SNPRINTF(strremotefilename,sizeof(strremotefilename),300,"%s/%s",starg.remotepath,vlistfile2[ii].filename);SNPRINTF(strlocalfilename,sizeof(strlocalfilename),300,"%s/%s",starg.localpath,vlistfile2[ii].filename);logfile.Write("put %s ...",strlocalfilename);// 调用ftp.put()方法把文件上传到服务端,第三个参数填true的目的是确保文件上传成功,对方不可抵赖。if (ftp.put(strlocalfilename,strremotefilename,true)==false) {logfile.WriteEx("failed.\n"); return false;}logfile.WriteEx("ok.\n");PActive.UptATime();   // 更新进程的心跳。// 如果ptype==1,把上传成功的文件记录追加到okfilename文件中。if (starg.ptype==1) AppendToOKFile(&vlistfile2[ii]);// 删除文件。if (starg.ptype==2){if (REMOVE(strlocalfilename)==false){logfile.Write("REMOVE(%s) failed.\n",strlocalfilename); return false;}}// 转存到备份目录。if (starg.ptype==3){char strlocalfilenamebak[301];SNPRINTF(strlocalfilenamebak,sizeof(strlocalfilenamebak),300,"%s/%s",starg.localpathbak,vlistfile2[ii].filename);if (RENAME(strlocalfilename,strlocalfilenamebak)==false){logfile.Write("RENAME(%s,%s) failed.\n",strlocalfilename,strlocalfilenamebak); return false;}}}return true;
}void EXIT(int sig)
{printf("程序退出,sig=%d\n\n",sig);exit(0);
}void _help()
{printf("\n");printf("Using:/project/tools1/bin/ftpputfiles logfilename xmlbuffer\n\n");printf("Sample:/project/tools1/bin/procctl 30 /project/tools1/bin/ftpputfiles /log/idc/ftpputfiles_surfdata.log \"<host>127.0.0.1:21</host><mode>1</mode><username>wucz</username><password>wuczpwd</password><localpath>/tmp/idc/surfdata</localpath><remotepath>/tmp/ftpputest</remotepath><matchname>SURF_ZH*.JSON</matchname><ptype>1</ptype><localpathbak>/tmp/idc/surfdatabak</localpathbak><okfilename>/idcdata/ftplist/ftpputfiles_surfdata.xml</okfilename><timeout>80</timeout><pname>ftpputfiles_surfdata</pname>\"\n\n\n");printf("本程序是通用的功能模块,用于把本地目录中的文件上传到远程的ftp服务器。\n");printf("logfilename是本程序运行的日志文件。\n");printf("xmlbuffer为文件上传的参数,如下:\n");printf("<host>127.0.0.1:21</host> 远程服务端的IP和端口。\n");printf("<mode>1</mode> 传输模式,1-被动模式,2-主动模式,缺省采用被动模式。\n");printf("<username>wucz</username> 远程服务端ftp的用户名。\n");printf("<password>wuczpwd</password> 远程服务端ftp的密码。\n");printf("<remotepath>/tmp/ftpputest</remotepath> 远程服务端存放文件的目录。\n");printf("<localpath>/tmp/idc/surfdata</localpath> 本地文件存放的目录。\n");printf("<matchname>SURF_ZH*.JSON</matchname> 待上传文件匹配的规则。"\"不匹配的文件不会被上传,本字段尽可能设置精确,不建议用*匹配全部的文件。\n");printf("<ptype>1</ptype> 文件上传成功后,本地文件的处理方式:1-什么也不做;2-删除;3-备份,如果为3,还要指定备份的目录。\n");printf("<localpathbak>/tmp/idc/surfdatabak</localpathbak> 文件上传成功后,本地文件的备份目录,此参数只有当ptype=3时才有效。\n");printf("<okfilename>/idcdata/ftplist/ftpputfiles_surfdata.xml</okfilename> 已上传成功文件名清单,此参数只有当ptype=1时才有效。\n");printf("<timeout>80</timeout> 上传文件超时时间,单位:秒,视文件大小和网络带宽而定。\n");printf("<pname>ftpputfiles_surfdata</pname> 进程名,尽可能采用易懂的、与其它进程不同的名称,方便故障排查。\n\n\n");
}// 把xml解析到参数starg结构中。
bool _xmltoarg(char *strxmlbuffer)
{memset(&starg,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer,"host",starg.host,30);   // 远程服务端的IP和端口。if (strlen(starg.host)==0){ logfile.Write("host is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"mode",&starg.mode);   // 传输模式,1-被动模式,2-主动模式,缺省采用被动模式。if (starg.mode!=2)  starg.mode=1;GetXMLBuffer(strxmlbuffer,"username",starg.username,30);   // 远程服务端ftp的用户名。if (strlen(starg.username)==0){ logfile.Write("username is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"password",starg.password,30);   // 远程服务端ftp的密码。if (strlen(starg.password)==0){ logfile.Write("password is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"remotepath",starg.remotepath,300);   // 远程服务端存放文件的目录。if (strlen(starg.remotepath)==0){ logfile.Write("remotepath is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"localpath",starg.localpath,300);   // 本地文件存放的目录。if (strlen(starg.localpath)==0){ logfile.Write("localpath is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"matchname",starg.matchname,100);   // 待上传文件匹配的规则。if (strlen(starg.matchname)==0){ logfile.Write("matchname is null.\n");  return false; }// 上传后客户端文件的处理方式:1-什么也不做;2-删除;3-备份。GetXMLBuffer(strxmlbuffer,"ptype",&starg.ptype);   if ( (starg.ptype!=1) && (starg.ptype!=2) && (starg.ptype!=3) ){ logfile.Write("ptype is error.\n"); return false; }GetXMLBuffer(strxmlbuffer,"localpathbak",starg.localpathbak,300); // 上传后客户端文件的备份目录。if ( (starg.ptype==3) && (strlen(starg.localpathbak)==0) ){ logfile.Write("localpathbak is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"okfilename",starg.okfilename,300); // 已上传成功文件名清单。if ( (starg.ptype==1) && (strlen(starg.okfilename)==0) ){ logfile.Write("okfilename is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"timeout",&starg.timeout);   // 进程心跳的超时时间。if (starg.timeout==0) { logfile.Write("timeout is null.\n");  return false; }GetXMLBuffer(strxmlbuffer,"pname",starg.pname,50);     // 进程名。if (strlen(starg.pname)==0) { logfile.Write("pname is null.\n");  return false; }return true;
}// 把localpath目录下的文件加载到vlistfile2容器中。
bool LoadLocalFile()
{vlistfile2.clear();CDir Dir;Dir.SetDateFMT("yyyymmddhh24miss");// 不包括子目录。// 注意,如果本地目录下的总文件数超过10000,增量上传文件功能将有问题。// 建议用deletefiles程序及时清理本地目录中的历史文件。if (Dir.OpenDir(starg.localpath,starg.matchname)==false){logfile.Write("Dir.OpenDir(%s) 失败。\n",starg.localpath); return false;}struct st_fileinfo stfileinfo;while (true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));if (Dir.ReadDir()==false) break;strcpy(stfileinfo.filename,Dir.m_FileName);   // 文件名,不包括目录名。strcpy(stfileinfo.mtime,Dir.m_ModifyTime);    // 文件时间。vlistfile2.push_back(stfileinfo);}return true;
}// 加载okfilename文件中的内容到容器vlistfile1中。
bool LoadOKFile()
{vlistfile1.clear();CFile File;// 注意:如果程序是第一次上传,okfilename是不存在的,并不是错误,所以也返回true。if ( (File.Open(starg.okfilename,"r"))==false )  return true;char strbuffer[501];struct st_fileinfo stfileinfo;while (true){memset(&stfileinfo,0,sizeof(struct st_fileinfo));if (File.Fgets(strbuffer,300,true)==false) break;GetXMLBuffer(strbuffer,"filename",stfileinfo.filename);GetXMLBuffer(strbuffer,"mtime",stfileinfo.mtime);vlistfile1.push_back(stfileinfo);}return true;
}// 比较vlistfile2和vlistfile1,得到vlistfile3和vlistfile4。
bool CompVector()
{vlistfile3.clear(); vlistfile4.clear();int ii,jj;// 遍历vlistfile2。for (ii=0;ii<vlistfile2.size();ii++){// 在vlistfile1中查找vlistfile2[ii]的记录。for (jj=0;jj<vlistfile1.size();jj++){// 如果找到了,把记录放入vlistfile3。if ( (strcmp(vlistfile2[ii].filename,vlistfile1[jj].filename)==0) &&(strcmp(vlistfile2[ii].mtime,vlistfile1[jj].mtime)==0) ){vlistfile3.push_back(vlistfile2[ii]); break;}}// 如果没有找到,把记录放入vlistfile4。if (jj==vlistfile1.size()) vlistfile4.push_back(vlistfile2[ii]);}return true;
}// 把容器vlistfile3中的内容写入okfilename文件,覆盖之前的旧okfilename文件。
bool WriteToOKFile()
{CFile File;    if (File.Open(starg.okfilename,"w")==false){logfile.Write("File.Open(%s) failed.\n",starg.okfilename); return false;}for (int ii=0;ii<vlistfile3.size();ii++)File.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",vlistfile3[ii].filename,vlistfile3[ii].mtime);return true;
}// 如果ptype==1,把上传成功的文件记录追加到okfilename文件中。
bool AppendToOKFile(struct st_fileinfo *stfileinfo)
{CFile File;if (File.Open(starg.okfilename,"a")==false){logfile.Write("File.Open(%s) failed.\n",starg.okfilename); return false;}File.Fprintf("<filename>%s</filename><mtime>%s</mtime>\n",stfileinfo->filename,stfileinfo->mtime);return true;
}

Linux 基于FTP协议文件传输系统相关推荐

  1. [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器...

    引言: 在这个专题将为大家揭开下FTP这个协议的面纱,其实学习知识和生活中的例子都是很相通的,就拿这个专题来说,要了解FTP协议然后根据FTP协议实现一个文件下载器,就和和追MM是差不多的过程的,相信 ...

  2. 基于FTP协议实现文件上传与下载

    目录 一.FTP简介 二.关于FTP服务器 三.文件上传 分步讲解: 完整实现代码: 四.下载文件 分步讲解: 完整实现代码: 小结 一.FTP简介 FTP(File Transfer Protoco ...

  3. 基于FTP协议实现指定终端的日志自动上送方案

    日志是应用程序的镜子,重要性不言而喻.日志是排查问题的一种有效的和快速的途径. 以往现场出了问题,都需要外办的到处跑,去采集设备日志,再提供给研发分析处理. 且采日志的过程是繁琐的,需要带电脑带工具以 ...

  4. linux中如何用ftp命令下载文件,linux中ftp下载文件命令的用法

    linxu下的ftp命令是用来下载文件或者上传文件的,下面由学习啦小编为大家整理了linux的ftp下载文件命令的用法的相关知识,希望对大家有帮助! 一.linux中的ftp下载文件命令的用法 从远程 ...

  5. 基于FTP协议的文件传输与下载

    目录 一.FTP协议: 二.文件上传: 1.连接服务器 2.登录操作 3.上传操作 三.文件下载 1.连接服务器 2.登录操作 3.下载操作 四. 总结: 一.FTP协议: ftp是(File Tra ...

  6. 基于FTP协议的Excel文件上传与下载

    1.关于FTP协议 FTP(文件传输协议)是TCP/IP协议组中的协议之一,作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用.FTP协议的全称为File Transfer Protocol, ...

  7. linux主机ftp传输文件效率,FTP和TCP的文件传输效率对比测试分析

    前言 最近因项目需要,需要把一定数量的中等文件从开发板上传到电脑上,分别选择了FTP和TCP自定义协议两种方式进行传输,进行了简单的对比测试,故做如下记录. 测试环境 开发板:Linux,ARMv7 ...

  8. loadrunner ftp linux,loadrunner ftp协议使用详细步骤

    loadrunner ftp协议使用详细步骤 大家好,我会给大家讲解两种编写方式,手动和录制.^_^ 1.首先要了解loadrunner中几个FTP函数 在loadrunner联机帮助文档的索引中,输 ...

  9. linux 连接 ftp 下载文件

    需要用root权限的,用下面语句登录root: [java] view plaincopy sudo -i 登出 exit 安装ftp 简单粗暴直接运行下面命令: [java] view plainc ...

最新文章

  1. mysql设置keepalived_MySQL高可用性之Keepalived+MySQL(双主热备)
  2. windows node.js安装以及启动过程
  3. linux 0.11 内核学习 -- console.c,控制台
  4. activity 、window与view的关系 (上)
  5. SAP打印出库单需求
  6. 那些一毕业就选择华为的人,后来都怎么样了
  7. python3下操作SVN
  8. 计算机组成与结构 英语,计算机组成与结构,Computer organization and architecture,音标,读音,翻译,英文例句,英语词典...
  9. 计算机算法对程序设计的作用,【程序设计论文】高中算法与程序设计教学意义及有效性(共3796字)...
  10. java反射机制详解篇一(基础)
  11. X86 64位和32位
  12. 袋鼠云日志助力云南某金融机构日志平台建设,实现核心业务系统运维智能化...
  13. 讨好型人格,有哪些错误逻辑?
  14. HTML5七夕情人节表白网页_(唯美满天星)多功能展示(网状球状)3D相册_HTML+CSS+JS 求婚 html生日快乐祝福代码网页 520情人节告白代码 程序员表白源码 抖音3D旋转相册
  15. 动态规划2---例9.2数字金字塔
  16. 主机屋 linux,如何主机屋中发布网站?
  17. Java基础 创建一个账户Account类,该类有id:账户号码(长整数),password:账户密码,name:真实姓名
  18. 计算机考试的准考证的样子
  19. 制作多系统U盘(win10+ubuntu18+ 。。。)
  20. 盘点各国自己开发的操作系统

热门文章

  1. 【已开源】Qt 艾宾浩斯(Ebbinghaus)记忆 软件
  2. sas和python哪个更容易发胖_BEC商务英语_沙拉vs.巨无霸:哪个更容易发胖?_沪江英语...
  3. Soul新发布录音有电流 杂音 m4a文件夹 解决方法
  4. 流媒体传输协议浅析(一)
  5. mysql根据身份证查询年龄,地址,性别
  6. Python批量修改文件夹及其子文件夹下的文件内容
  7. 7-1 录入学生成绩并统计及格人数、不及格人数及平均分 (50分)----c++综合实验
  8. 世界上为什么有那么多的不幸的人
  9. 2023年城投债投资研究报告
  10. 牛客网刷题之SQL篇:非技术快速入门39T