二、ftp采集数据模块

  在前面的步骤中,已经模拟生成了气象站点的气象观测数据,这个就相当于模拟了服务端的数据源(产生气象观测数据)。

  接下来要完成的就是,从服务端那里将观测数据采集回来,用的方法就是利用ftp从服务端下载数据。现在就是要设计一个ftp采集模块,从服务端采集数据。

一、ftp 下载服务器数据的流程

  在设计 ftp 采集模块之前,先来回顾一下利用ftp从服务端下载数据的大致过程。

  (1)登录 ftp 服务器,用户名和密码

  (2)选择主动模式或者被动模式,一般是被动模式

  (3)找到要下载数据的路径,也就是要切换服务器的工作目录

  (4)切换了工作目录,如果有多种数据类型,匹配自己要找的数据类型,比如说我要下载 .txt 类型,就匹配 .txt 类型文件

  (5)执行下载命令下载自己想要的数据

  (6)指定存放数据的本地目的

  (7)检查是否下载成功

二、设计 ftp 采集数据模块

1.设计采集模块的参数

  只要是使用ftp协议从服务器获取数据,上面的流程是肯定要执行的,现在就来设计这个模块。

  综上,这个模块的参数应该有:

  (1)程序运行要记录日志文件
  我们可能要利用 ftp 采集模块采集多种数据,现在是采集气象观测数据,所以命名为:

  /oracle/qxidc/log/ftpgetfile_surfdata.log

  (2)服务器的IP、端口、用户名、密码(要登录ftp服务器)

  登录 ftp 服务器要知道 IP地址指定端口,现在把 IP地址和端口(被动模式一般选择21端口)放在一起作为一个参数:
   参数名为:host

  用户名参数为:username
  密码参数为:password

  (3)传输模式,pasv和port,可选字段,缺省采用pasv模式。(一般选择被动模式)

  传输模式参数名为:mode,传输模式有主被动模式,定义了两个宏,主动模式为 2,被动模式为 1.

  (4)本地文件存放的目录。(采集回来的文件放在哪里)

  采集回来气象数据放在 /oracle/qxidc/data/surfdata 中,参数名为 :localpath。

  (5)远程服务器存放文件的目录。(要采集的文件放在服务器的什么位置)
  参数名为:remotepath。数据源是自拟的,之前把模拟生成气象观测数据放在 /oracle/qxidc/data/ftp/surfdata 下,现在去那个目录获取数据即可。

  (6)文件采集成功后,远程服务器文件的处理方式:1-什么也不做;2-删除;3-备份,如果为3,还要指定备份的目录。

  备份目录是在服务端的,参数名为:remotepathbak,现在设置为:/oracle/qxidc/data/ftp/surdatabak

  (7)实现文件的增量采集。已经取过的文件不用再取。缓解网络的压力。
  要实现增量采集,要知道哪些文件要采集,哪些文件已经采集回来了。所以在本地还要有这两个文件。

  要采集的文件名放在本地的 /oracle/qxidc/list 目录,文件名为:ftpgetfile_surfdata.list 。参数名为:listfilename

  已经采集的文件的文件名放在本地的 /oracle/qxidc/list/ftpgetfile_surfdata.xml。参数名为 okfilename

  (8)待采集文件匹配的文件名,不匹配的文件不会被采集,本字段尽可能设置精确,不允许用* 匹配全部的文件。(筛选文件)

  当服务器中有多种文件时,要能获取指定的文件类型,这个参数名为:matchname

2.处理采集模块的参数

  虽然设计了上面的参数,但是会出现一个问题就是参数很多,在调试程序的时候,或者程序中要使用这些参数 argv[i],里面的i的取值就很多,不方便程序的使用。

  现在采用将一些参数合并成一个 XML参数(如下图所示),这样总体上减少了模块的参数数量,总体上看只有3个参数。

  所以以后遇到参数多的程序,可以采用这种方法。

  将一些参数合并了之后,只要利用XML解析函数将这些参数解析出来,就能很方便地使用。

3.设计模块的函数

3.1 模块名称

  这个模块是 利用 ftp 从服务器获取文件,所以这个模块就叫做 ftpgetfile

3.2 提示程序

  一般程序的提示信息是放在 main 函数中,但是这个模块的提示信息太长了,把它在 main 函数中,会让 main 显得冗长,所以现在把提示信息分离出去。

  提示信息一般包括程序所要的参数,如何使用。

  函数名为:_help

  参数:这个程序是提示使用者如何使用这个的,所以会使用到模块的(上文说的)那些参数。所以 _help 函数的参数为,模块的参数的地址。

  返回值:这个函数的作用是用来提示的,可以不用返回值 void

4.设计XML参数解析函数

  因为把ftp文件传输的参数合并成一个XML的字符串,要使用里面的参数,需要将参数解析出来

4.1 函数的参数

4.1.1 设计函数

  要解析XML字符串参数,要将XML 字符串给解析函数,所以解析函数的参数就是来接收XML字符串。

  返回值:bool

  函数名:_xmltoarg ,xml解析到参数

bool _xmltoarg(char *strxmlbuffer);
4.1.2 具体实现

  (1)因为把ftp文件传输的参数合并成一个XML的字符串,要使用里面的参数,要将参数解析出来。解析出来了放在一个ftp参数结构体中,声明一个结构体,这个结构体的成员变量有可能有多个子程序要使用,所以结构体声明成全局变量

struct st_arg
{
   
        char host[51];
        int  mode;
        char username[31];
        char password[31];
        char localpath[301];
        char remotepath[301];
        char matchname[301];
        int  ptype;
        char remotepathbak[301];
        char listfilename[301];
        char okfilename[301];
} starg;

(2)函数代码

bool _xmltoarg(char *strxmlbuffer)
{
   
        // (1)初始化存放解析出来的参数结构体
        memset(&starg,0,sizeof(struct st_arg));

        // (2)将 xml 解析出来,并且存放到starg 结构体
        GetXMLBuffer(strxmlbuffer,"host",starg.host);

        GetXMLBuffer(strxmlbuffer,"mode",&starg.mode);
        if ( ( starg.mode != 1 ) && ( starg.mode != 2 ) ) starg.mode = 1;

        GetXMLBuffer(strxmlbuffer,"username",starg.username);
        GetXMLBuffer(strxmlbuffer,"password",starg.password);
        GetXMLBuffer(strxmlbuffer,"localpath",starg.localpath);
        GetXMLBuffer(strxmlbuffer,"remotepath",starg.remotepath);
         GetXMLBuffer(strxmlbuffer,"listfilename",starg.listfilename);
        GetXMLBuffer(strxmlbuffer,"okfilename",starg.okfilename);

        return true;

}
                                                                   

4.2 函数解析效果

  用gdb调试,在断点设置在解析函数,将结构体的成员变量显示,解析正确。
在这里插入图片描述

5.设计模块的业务流程主程序

  上面的步骤把所需的参数都解析出来了,接下就是使用这些参数去完成 ftp 文件传输。ftp 文件传输的大致步骤已经在上面陈述过,会发现有很多步骤的。如果每一个步骤设计一个函数去处理,把他们都放在main函数中,就会显得不简洁。

  所以可以把 ftp文件传输所涉及的一些步骤函数,放在一个业务流程主函数里面,由业务流程主函数去调用步骤函数,再由main 函数调用业务流程主函数,这样就会很简洁。

  现在就来设计这个业务流程主函数:

  (1)函数名:
  _ftpgetfile——ftp获取文件

  (2)函数的参数:
  这个函数就是文件传输的过程,要使用的变量就是 参数结构体里面的参数,由于之前是把参数结构体定义为全局变量,所以目前这个函数不用传参。

  (3)函数返回值:
  bool,成功或失败

5.1 登录ftp 服务器


        //3.1 ftp 文件传输的第一步登录,ftp服务器
        // 登录ftp 服务器需要的参数:IP地址和端口号,用户名和密码,指定模式
        int mode;
        if ( starg.mode == 1 ) mode = FTPLIB_PASSIVE;   // 被动模式
        if ( starg.mode == 2 ) mode = FTPLIB_PORT;      // 主动模式

        if ( ftp.login(starg.host,starg.username,starg.password,mode) == false )
        {
   
                logfile.Write("ftp.login(%s,%s,%s,%d)failed.\n",starg.host,starg.username,\
                                starg.password,mode);
                return false;
        }
        logfile.Write("ftp.login 成功。\n");

5.2 切换工作目录

  登录了服务器之后,要获取文件,先切换到要获取的文件所在目录

if ( ftp.chdir(starg.remotepath) == false )
        {
   
                logfile.Write("ftp.chd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值