气象数据模拟生成与FTP动态采集数据

1.项目目标

  • 1.ftp服务端生成气象模拟数据,数据生成周期为每分钟一份;数据包含:气温,气压,相对湿度,风向风速,降雨,能见度
  • 2.数据格式:
    时间:yyyy-mm-dd hh24:mi:ss
    气温:单位摄氏度,小数点后一位
    气压:0.1百帕,小数点后一位
    相对湿度:0-100之间
    风向:0-360之间
    风速:单位m/s,小数点后一位
    降雨量:mm,小数点后一位
    能见度:单温-0.1米
  • 3.数据存放的形式:以文件的形式保存生成的数据,格式如下:
    站点代码,数据时间,气温,气压,相对湿度,风向,风速,降雨量,能见度
  • 4.日志备份:将程序运行产生的打印输出信息备份到log日志中
  • 5.crontab计划任务:让程序在后台自动运行,运行周期为1min
  • 6.ftp客户端动态下载服务端产生的气象数据

2.项目前期准备

  • 准备站点数据文件
    在这里插入图片描述

3.项目流程

流程图
在这里插入图片描述

1.将站点数据拷贝到LINUX平台中

在这里插入图片描述

2.将站点参数文件加载到容器中

== 站点数据结构==在这里插入图片描述
== 代码实现==

//从站点参数文件中加到到容器中 
bool LoadSTCode(const char* stcodefilename)
{
   CFile file;
   FILE* fp;
   if(file.Open(stcodefilename,"r",true)==false)
   {
      //printf("File Open(%s) 失败\n",stcodefilename);
      logfile.Write("File Open(%s) 失败\n",stcodefilename);
      return false;
   }
   //fp=file.getFp();
   char strbuffer[101];
   CCmdStr Cmd;
   struct st_code stcode;
   while(true)
   {
      memset(&stcode,0,sizeof(stcode));
      if(file.Fgets(strbuffer,100,false)==false)
      {
        break;
      }
      //printf("strbuffer=%s",strbuffer);
      //字符串的拆分
      Cmd.SplitToCmd(strbuffer,",",true);
      Cmd.GetValue(0,stcode.province);
      Cmd.GetValue(1,stcode.obtid);
      Cmd.GetValue(2,stcode.cityname);
      Cmd.GetValue(3,&stcode.lat);
      Cmd.GetValue(4,&stcode.lon);
      Cmd.GetValue(5,&stcode.height);
      //printf("strbuffer=%s",strbuffer);
      //printf("province=%s,obtid=%s,lat=%.2lf,lon=%.2lf,height=%.2lf\n",stcode.province,\
                             stcode.obtid,stcode.lat,stcode.lon,stcode.height);
      vstcode.push_back(stcode);
    }
    return true;
}

3.设计气象数据,将生成的数据存放到容器

== 模拟的气象数据结构==
在这里插入图片描述
== 代码实现==

//创建全国气象站点观测数据,存放在vt_surfdata容器中
void CrtSurfData()
{
 srand(time(0));                                             //播随机数种子
 struct surfdata stsurfdata;
 char strLocalTime[21];
 memset(strLocalTime,0,sizeof(strLocalTime));
 LocalTime(strLocalTime,"yyyy-mm-dd hh24:mi");
 strcat(strLocalTime,":00");
 for(int i=0;i<vstcode.size();i++)
 { 
   memset(&stsurfdata,0,sizeof(stsurfdata));
   STRCPY(stsurfdata.obtid,11,vstcode[i].obtid);             //站点代码 
   //LocalTime(stsurfdata.datetime,"yyyy-mm-dd hh24:mi:ss",0);  //数据时间采用当前时间
   strncpy(stsurfdata.datetime,strLocalTime,20);                  
   stsurfdata.t=rand()%170+200;                                   //气温
   stsurfdata.p=rand()%264+10000;                             //气压
   stsurfdata.u=rand()%100+1;                                  //相对湿度
   stsurfdata.wd=rand()%360;                                  //风向,0-360
   stsurfdata.wf=rand()%150;                                  //风速:单位0.1m/s
   stsurfdata.r=rand()%16;                                    //降雨量,单位:0.1mm
   stsurfdata.vis=rand()%5000+10000;                              //能见度:0.1米
   vt_surfdata.push_back(stsurfdata);
 }
}

4.将测试数据写入到指定的文件中

bool CrtSurfFile(const char* surffilename)
{  
   CFile file;
   char strLocalTime[21];
   memset(strLocalTime,0,sizeof(strLocalTime));
   LocalTime(strLocalTime,"yyyy-mm-dd hh24:mi:ss",0);  //数据时间采用当前时间
   char strFileName[301]; 
   memset(strFileName,0,sizeof(strFileName));
   snprintf(strFileName,300,"%s/SURF_ZH_%s_%d.txt",surffilename,strLocalTime,getpid());
   if(file.Open(strFileName,"w")==false)
   {  
      //printf("File.open(%s)失败!\n",strFileName);
      logfile.Write("File.open(%s)失败!\n",strFileName);
      return false;
    }
    for(int i=0;i<vt_surfdata.size();i++)
    { 
      file.Fprintf("%s,%s,%.1f,%.1f,%d,%d,%.1f,%.1f,%.1f\n",vt_surfdata[i].obtid,vt_surfdata[i].datetime,\
                    vt_surfdata[i].t/10.0,vt_surfdata[i].p/10.0,vt_surfdata[i].u,vt_surfdata[i].wd,\
                    vt_surfdata[i].wf/10.0,vt_surfdata[i].r/10.0,vt_surfdata[i].vis/10.0);
    }
   //printf("生成数据文件(%s)成功!\n",strFileName);
   logfile.Write("生成数据文件(%s)成功!,数据时间=%s,记录数=%d\n",strFileName,vt_surfdata[1].datetime,vt_surfdata.size());
}

5.程序运行前关闭所有的信号,并设置信号处理函数

在这里插入图片描述

6.设置信号退出函数

在这里插入图片描述

7.采用crontab实现每分钟产生一份数据

  • crontab -e:编辑计划任务
    在这里插入图片描述

8.编辑Makefile文件

在这里插入图片描述

9.ftp客户端动态采集服务端数据

#include "_ftp.h"
#include "_freecplus.h"
int main(int argc,char *argv[])
{
  Cftp ftp;

  // 登录远程FTP服务器,请改为您自己服务器的ip地址。
  if (ftp.login("192.168.74.128:21","wang","1995",FTPLIB_PASSIVE) == false)
  { 
    printf("ftp.login(192.168.74.128:21(wang/1995)) failed.\n"); return -1;
  }

  // 获取服务器上/home/freecplus/*.h文件列表,保存在本地的/tmp/list/tmp.list文件中。
  // 如果/tmp/list目录不存在,就创建它。
  if (ftp.nlist("/tmp/docs/qxidc/ftp/surfdata/*.txt","/tmp/docs/qxidc/src/ftp.txt")==false)
  { printf("ftp.nlist() failed.\n"); return -1; }

  CFile File;    // 采用freecplus框架的CFile类来操作list文件。
  char strFileName[301];

  File.Open("/tmp/docs/qxidc/src/ftp.txt","r");  // 打开list文件。

  while(true)    // 获取每个文件的时间和大小。
  {
    memset(strFileName,0,sizeof(strFileName));
    if (File.Fgets(strFileName,300,true)==false) break;
    printf("get %s...",strFileName);

    if (ftp.get(strFileName,strFileName)==false)
    { printf("ftp.get(%s) failed.\n",strFileName); return -1; }
    printf("ok.\n");
  }
  File.Close();
}

4.项目运行结果

1.每分钟后台自动产生一份气象数据文件

在这里插入图片描述

2.产生的气象数据文件内容

在这里插入图片描述

3.日志文件信息

在这里插入图片描述

4.ftp客户端动态采集(下载)数据

在这里插入图片描述

5.项目技术总结

  • 1.c++的时间操作,文件、目录操作,日志打印,文件内容解析操作
  • 2.c++vector容器的遍历,存储数据
  • 3.c++类的封装,函数的封装,调用
  • 4.涉及信号signal的处理,程序在后台运行时的退出
  • 5.涉及makefile文件的编写以及gdb的调试
  • 6.涉及crontab守护进程控制系统用户的计划任务,周期性执行事件
  • 7.涉及ftp客户端动态采集服务端数据

6.完整代码展示

#include"_freecplus.h"
//黑龙江省,50136,漠河,52.97,122.52,438.5
vector<struct st_code>vstcode;//存放全国站点参数容器

bool LoadSTCode(const char* stcodefilename);//从站点参数文件中加到到容器中 

struct st_code
{
   char province[31];//省名称
   char obtid[11];  //站点代码
   char cityname[30];//城市
   double lat;      //纬度
   double lon;      //经度
   double height;   //海拔 
};

//站点代码,数据时间,气温,气压,相对湿度,风向,风速,降雨量,能见度
//时间:yyyy-mm-dd hh24:mi:ss
//气温:单位摄氏度,小数点后一位
//相对湿度:0-100之间
//风向:0-360之间
//风速:单位m/s,小数点后一位
//降雨量:mm,小数点后一位
struct surfdata
{
  char obtid[11];
  char datetime[21];
  int t;                 //气温:单位0.1摄氏度,小数点后一位  
  int p;                 //气压:0.1百帕,小数点后一位
  int u;                 //相对湿度:0-100之间的值
  int wd;                //风向,0-360
  int wf;                //风速:单位0.1m/s 
};

//创建全国气象站点观测数据,存放在vt_surfdata容器中
void CrtSurfData();


 //把容器vt_surfdata中的数据写到目标文件中 
bool CrtSurfFile(const char* surffilename);

vector<struct surfdata>vt_surfdata;//站点观测数据

CLogFile logfile;

//信号处理函数
void EXIT(int arg);
void CloseAllSignal();
int main(int argc,char* argv[])
{
 if(argc!=4)
 {
   printf("本程序用于生成全国气象站点观测的分钟数据\n");
   printf("/tmp/docs/qxidc/bin/crtsurfdata 站点参数 数据文件存放的目录 日志文件名\n");
   return -1;
 }
  //关闭所有信号
  CloseAllSignal();
  //捕获退出信号2和15
  signal(SIGINT,EXIT);
  signal(SIGTERM,EXIT);

 if(logfile.Open(argv[3])==false)
  {
    printf("打开日志(%s)文件失败\n",argv[3]);
    return -1;
  }

 if(LoadSTCode(argv[1])==false) return -1;

 //printf("加载参数文件(%s)成功!\n",argv[1]);
 logfile.Write("加载参数文件(%s)成功!\n",argv[1]);

 CrtSurfData();
 if(CrtSurfFile(argv[2])==false) return -1;
//创建全国气象站点观测数据,存放在vt_surfdata容器中
//一分钟产生一份数据
 /*while(true)
 {
   CrtSurfData();

   //把容器中的数据写到目标文件中 
   if(CrtSurfFile(argv[2])==false) return -1;
  
   sleep(60);
 }*/
   return 0;
}

//创建全国气象站点观测数据,存放在vt_surfdata容器中
{
 srand(time(0));                                             //播随机数种子
 struct surfdata stsurfdata;                                 
 char strLocalTime[21];
 memset(strLocalTime,0,sizeof(strLocalTime));
 LocalTime(strLocalTime,"yyyy-mm-dd hh24:mi");
 strcat(strLocalTime,":00");
 for(int i=0;i<vstcode.size();i++)
 { 
   memset(&stsurfdata,0,sizeof(stsurfdata));
   STRCPY(stsurfdata.obtid,11,vstcode[i].obtid);             //站点代码 
   //LocalTime(stsurfdata.datetime,"yyyy-mm-dd hh24:mi:ss",0);  //数据时间采用当前时间
   strncpy(stsurfdata.datetime,strLocalTime,20);
   stsurfdata.t=rand()%170+200;                                   //气温
   stsurfdata.p=rand()%264+10000;                             //气压
   stsurfdata.u=rand()%100+1;                                  //相对湿度
   stsurfdata.wd=rand()%360;                                  //风向,0-360
   stsurfdata.wf=rand()%150;                                  //风速:单位0.1m/s
   stsurfdata.r=rand()%16;                                    //降雨量,单位:0.1mm
   stsurfdata.vis=rand()%5000+10000;                              //能见度:0.1米
   vt_surfdata.push_back(stsurfdata);                             
 } 
}
//从站点参数文件中加到到容器中 
bool LoadSTCode(const char* stcodefilename)
{
   CFile file;
   FILE* fp;
   if(file.Open(stcodefilename,"r",true)==false)
   {
      //printf("File Open(%s) 失败\n",stcodefilename);
      logfile.Write("File Open(%s) 失败\n",stcodefilename);
      return false;
   }
   //fp=file.getFp();
   char strbuffer[101];
   CCmdStr Cmd;
   struct st_code stcode;
   while(true)
   {
      memset(&stcode,0,sizeof(stcode));
      if(file.Fgets(strbuffer,100,false)==false)
      {
        break;
      }
      //printf("strbuffer=%s",strbuffer);
      //字符串的拆分
      Cmd.SplitToCmd(strbuffer,",",true);
      Cmd.GetValue(0,stcode.province);
      Cmd.GetValue(1,stcode.obtid);
      Cmd.GetValue(2,stcode.cityname);
      Cmd.GetValue(3,&stcode.lat);
      Cmd.GetValue(4,&stcode.lon);
      Cmd.GetValue(5,&stcode.height);
      //printf("strbuffer=%s",strbuffer);
      //printf("province=%s,obtid=%s,lat=%.2lf,lon=%.2lf,height=%.2lf\n",stcode.province,\
                             stcode.obtid,stcode.lat,stcode.lon,stcode.height);
      vstcode.push_back(stcode);
    }
    return true;
}

 //把容器vt_surfdata中的数据写到目标文件中 
   CFile file;
   char strLocalTime[21];
   memset(strLocalTime,0,sizeof(strLocalTime));
   LocalTime(strLocalTime,"yyyy-mm-dd hh24:mi:ss",0);  //数据时间采用当前时间
   char strFileName[301]; 
   memset(strFileName,0,sizeof(strFileName));
   snprintf(strFileName,300,"%s/SURF_ZH_%s_%d.txt",surffilename,strLocalTime,getpid());
   if(file.Open(strFileName,"w")==false) 
   {
      //printf("File.open(%s)失败!\n",strFileName);
      logfile.Write("File.open(%s)失败!\n",strFileName);
      return false;
    } 
    for(int i=0;i<vt_surfdata.size();i++)
    {
      file.Fprintf("%s,%s,%.1f,%.1f,%d,%d,%.1f,%.1f,%.1f\n",vt_surfdata[i].obtid,vt_surfdata[i].datetime,\
                    vt_surfdata[i].t/10.0,vt_surfdata[i].p/10.0,vt_surfdata[i].u,vt_surfdata[i].wd,\
                    vt_surfdata[i].wf/10.0,vt_surfdata[i].r/10.0,vt_surfdata[i].vis/10.0); 
    }               
   //printf("生成数据文件(%s)成功!\n",strFileName);
   logfile.Write("生成数据文件(%s)成功!,数据时间=%s,记录数=%d\n",strFileName,vt_surfdata[1].datetime,vt_surfdata.size());
   return true;        
}  

//关闭所有的信号
void CloseAllSignal()
{
  for(int i=0;i<100;i++)
  {
      signal(i,SIG_IGN);
      close(i);
  }
}
void EXIT(int arg)
{
   logfile.Write("程序退出,sig=%d\n",arg);
   //程序退出
   exit(0);
}

客户端采集数据代码

#include "_ftp.h"
#include "_freecplus.h"
int main(int argc,char *argv[])
{
  Cftp ftp;

  // 登录远程FTP服务器,请改为您自己服务器的ip地址。
  if (ftp.login("192.168.74.128:21","wang","1995",FTPLIB_PASSIVE) == false)
  { 
    printf("ftp.login(192.168.74.128:21(wang/1995)) failed.\n"); return -1;
  }

  // 获取服务器上/home/freecplus/*.h文件列表,保存在本地的/tmp/list/tmp.list文件中。
  // 如果/tmp/list目录不存在,就创建它。
  if (ftp.nlist("/tmp/docs/qxidc/ftp/surfdata/*.txt","/tmp/docs/qxidc/src/ftp.txt")==false)
  { printf("ftp.nlist() failed.\n"); return -1; }

  CFile File;    // 采用freecplus框架的CFile类来操作list文件。
  char strFileName[301];

  File.Open("/tmp/docs/qxidc/src/ftp.txt","r");  // 打开list文件。

  while(true)    // 获取每个文件的时间和大小。
  {
    memset(strFileName,0,sizeof(strFileName));
    if (File.Fgets(strFileName,300,true)==false) break;
    printf("get %s...",strFileName);

    if (ftp.get(strFileName,strFileName)==false)
    { printf("ftp.get(%s) failed.\n",strFileName); return -1; }
    printf("ok.\n");
  }
  File.Close();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex1_Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值