Chinaunix首页 | 论坛 | 博客
  • 博客访问: 370001
  • 博文数量: 132
  • 博客积分: 3066
  • 博客等级: 中校
  • 技术积分: 781
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-14 16:19
文章分类

全部博文(132)

文章存档

2012年(1)

2010年(50)

2009年(81)

我的朋友

分类: C/C++

2009-05-31 19:35:25

前不久,做了一个小项目,用VC实现客户端FTP定时上传程序,其实是个比较简单的程序,只是刚开始根本不知道VC还自带FTP类,傻乎乎的自己写了 Soket底层通信,结果因为基础知识不是很好,半途进展不下去,太复杂了,请教了高手才知道原来VC里自带FTP类,晕!!!下面就和大家共享一下自己的成果!(做的也不是很好,但是现在运行的挺稳定的嘻嘻)
一.需求分析:
主要任务:定时上传本地机器上的特定目录下各个局的话务原始数据到服务器端特定目录下。并进行记录操作日志
1.界面:
仅有:读配置文件/退出即可。
2.定时器:(主要部分)
每天3:00到3:30某个时间定时上传文件。

a.上传时段:
03:00 - 03:30
b 上传规则:   例:局名:东方
上传至数据接口机 /u/gdpwg/SZDH/data/下
客户机上传文件名规则:D:\timsdata\210\traffic\20060418.rpt
服务器接收文件名规则:\timsdata\210\traffic\tr20060418.rpt
读取当天时间20060419则上传前一天的数据也就是20060418.rpt—〉tr20060418.rpt

定时器每隔10分钟检测一次,是否到了3:00或3:30。可以判断最后一位是否为0在判断,倒数第二位是否是0或3或者其他算法均可。总之如果到了3:00就开始上传文件。
3.上传文件:
根据配置文件中组合的地址,上传所有局的话务数据。
4.日志:
对上传成功失败记录日志;对程序启动时间记录日志。并形成文本文件在该程序所在目录下


二.具体实现:
1.配置文件:配置文件根据需求设置如下:
[path]
MAX_ROW = 9
path = D:/tims/timsdata/
subpath=/traffic/
[office]
officename1=111
officename2=222
officename3=333
officename4=444
[Server]
IP=111.111.1.1
port=21
username=***
pwd=***
path1=/******
path2=/******
officename1=SZDH
officename2=SZGR
officename3=TDIR
officename4=TDER
subpath=/spcdata
[startup]
time=15:36
[firstcreate]
flag=0
2.定时功能由VC中的SetTimer()和OnTimer()来实现:
void CFTPClientView::OnInitialUpdate()
{
CView::OnInitialUpdate();
 
SetTimer(1,600000,NULL);
 
}
void CFTPClientView::OnTimer(UINT nIDEvent)
{
  ........
    if (nHour==nTime)
  {
    if (nMinute==Minute)
    {
      if (bTimer==TRUE)
      {
        bTimer=FALSE;
        CDataTxt syslog;
        syslog.WriteLogFile("ftp上传程序启动");//写日志
        AfxBeginThread((AFX_THREADPROC)StartRun,&m_nFileStatus);


        }
    }
   
    }
    else
      bTimer = TRUE;
}
3.链接服务器:
BOOL CDataTxt::Connection()
{
  CString hostname;
  int hostport;
  CString username;
  CString password;

  //读配置文件 FTPClient.ini
  char a[255];
  CString s;
  GetPrivateProfileString("Server","IP","",a,255,"./FTPClient.ini");
  s.Format("%s",a);
  hostname = s;

  GetPrivateProfileString("Server","port","21",a,255,"./FTPClient.ini");
  s.Format("%s",a);
  hostport =atoi(s);
 
  GetPrivateProfileString("Server","username","",a,255,"./FTPClient.ini");
  s.Format("%s",a);
  username = s;

  GetPrivateProfileString("Server","pwd","",a,255,"./FTPClient.ini");
  s.Format("%s",a);
  password = s;

  // 连接 FTP server
  pInetSession=new CInternetSession(AfxGetAppName,(),1,PRE_CONFIG_INTERNET_ACCESS);
  try
  {
    pFtpConnection=pInetSession->GetFtpConnection(hostname,username,password,hostport,FALSE);
  }
  catch(CInternetException *pEx)
  {
    pEx->Delete();
    pFtpConnection=NULL;
    LogOffServer();//断开链接
    return false;
  }
  WriteLogFile("ftp登录成功成功");//写日志
  return true;
}

BOOL CDataTxt::LogOffServer()
{//断开链接
  if(pFtpConnection!=NULL)
  {
    pFtpConnection->Close();
    delete pFtpConnection;
  }
  delete pInetSession;
  WriteLogFile("断开与服务器的连接");
  return TRUE;
}
void CDataTxt::WriteLogFile(CString log)
{//写日志
  FILE *fp;
  CHAR strhead[30]="";
  SYSTEMTIME st;
  GetLocalTime(&st);
  memset(strhead, 0, sizeof(strhead));
  sprintf(strhead, "%4d-%02d-%02d %02d:%02d:%02d ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
  fp = fopen("./syslog.txt", "a+");
  if(fp!=NULL)
  {
    fwrite(strhead, sizeof(CHAR), strlen(strhead), fp);
    fwrite(log, sizeof(CHAR), strlen(log), fp);
    fwrite("\n", 1, 1, fp);
    fclose(fp);
  }
 
}
3.上传文件:
非常简单用一个函数就解决了:
pFtpConnection->PutFile(localfile,remotefile)//其中localfile是从配置文件中读取的本地文件所在目录文件名,remotefile是服务器端要创建的目录以及文件名.
//判断文件是否存在:
    CFileFind finder;
  if( !finder.FindFile(localfile) )
    {return FALSE;}
  else
    return TRUE;
//在服务器端创建文件所用函数:
pFtpConnection->CreateDirectory(s);//s为目录名,需要注意的是文件已经创建时,再创建就会返回false
阅读(1025) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~