从FTP的服务上下载txt⽂件,下载不了的问题
  近期有个项⽬,要从ftp上下载txt⽂件下来,因为txt⽂件有我这边项⽬所需要的报告,但是我在本机上运⾏却能从客户的ftp上能拉取下来(我的电脑为WIN10),但是到了线上的环境却下了。
开始的时候,我是觉得路径的问题,然后把取的路径更改为  strFtpDirTmp += _T("\\*.txt");
也就是如下的代码,最后在本机(WIN10)上能拉到ftp服务器的txt⽂件,但是到了线上的环境却不⾏了。实现下载的代码如下(单独开了个线程来下载):
  static THREAD_RETURN __STDCALL ThreadGetRptFromFtp(void *arglist)
  {
    CZzxFxImpl* pThis = (CZzxFxImpl*)arglist;
    if (NULL == pThis)
    {
      return (THREAD_RETURN)0;
    }
    CAdapter::InterlockedIncrement(&pThis->m_getFtpRptThreadCnt);
    pThis->m_getRptThreadExitFlag = false;
    pThis->g_pInetSession = NULL; //会话对象
    pThis->g_pFtpConnection = NULL; //连接对象
    //新建对话
    pThis->g_pInetSession = new CInternetSession(AfxGetAppName(), 1, PRE_CONFIG_INTERNET_ACCESS);
    try
    {
      //新建连接对象
      pThis->g_pFtpConnection = pThis->g_pInetSession->GetFtpConnection(pThis->m_FtpAddr.c_str(), pThis->m_FtpUid.c_str(), pThis->m_FtpPwd.c_str());
    }
    catch (CInternetException *pEx)
    {
      TCHAR szError[1024];
      CString strError = "";
      if (pEx->GetErrorMessage(szError, 1024))
      {
        string strLogInfo = cstr::format("连接FTP服务器失败,失败原因 %s", szError);
      CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
      }
      else
      {
        string strLogInfo = cstr::format("连接FTP服务器失败,失败原因:未知异常");
        CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
      }
      pEx->Delete();
      pThis->g_pFtpConnection = NULL;
      return 0;
    }
    try
    {
      memset(pThis->m_szLocalPath, 0x0, sizeof(pThis->m_szLocalPath));
      CAdapter::GetCurrentPath(pThis->m_szLocalPath, MAX_PATH);
      strcat(pThis->m_szLocalPath, "LocalRptFile");
      if (!CAdapter::PathFileExists(pThis->m_szLocalPath))
      {
      CAdapter::CreateDirectory(pThis->m_szLocalPath, 0);
      }
      //创建会话成功
      while (!pThis->m_getRptThreadExitFlag)
      {
        //设置远程服务端状态报告获取⽬录
        BOOL bSetDir = pThis->g_pFtpConnection->SetCurrentDirectory(pThis->m_FtpRptDir.c_str());
        CFtpFileFind RemoteFinder(pThis->g_pFtpConnection); //远程查⽂件对象
        // pRemoteFinder = new CFtpFileFind(g_pFtpConnection);
        CString strFtpDirTmp = pThis->m_FtpRptDir.c_str();
        //strFtpDirTmp += "*";
        strFtpDirTmp += _T("\\*.txt");
        BOOL bFindFile = RemoteFinder.FindFile(strFtpDirTmp); //获取⽬录下所有的⽂件
        //BOOL bFindFile = RemoteFinder.FindFile(_T("*")); //获取⽬录下所有的⽂件
        int nFileCnt = 0;
        while (bFindFile)
        {
          bFindFile = RemoteFinder.FindNextFile();
          nFileCnt++;
          CString strFile = RemoteFinder.GetFileName();
          CString strLoaclFilePath = "";
          strLoaclFilePath.Format("%s\\%s", pThis->m_szLocalPath, strFile); //下载到本地⽂件夹的全路径
          CString strErrMsgTmp = "";
          BOOL bGetRlt = pThis->g_pFtpConnection->GetFile(strFile, strLoaclFilePath, FALSE,
FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY); //下载
          if (bGetRlt) //下载成功
          {
            BOOL bRemove = pThis->g_pFtpConnection->Remove(strFile); //删除
            if (!bRemove) //删除失败
            {
              string strLogInfo = cstr::format("⽂件:%s 删除失败,失败代码:%d", strFile, GetLastError());
              CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(),
CSmsTools::LOG_LEVEL_ERROR);
              break;
            }
          }
          else //下载失败
          {
            string strLogInfo = cstr::format("⽂件:%s 下载失败,失败代码:%d", strFile, GetLastError());
            CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(),
CSmsTools::LOG_LEVEL_ERROR);
            continue;
          }
          //解析本地⽂件夹中状态报告⽂件
          pThis->ParseLocalDirectoryRptFile(strLoaclFilePath);
          Sleep(100);
        }
        RemoteFinder.Close();
        Sleep(1000 * 5);
      }
    }
    catch (...) //GetErrorMessage
    {
      string strLogInfo = cstr::format("下载异常");
      CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
    }
    CAdapter::InterlockedDecrement(&pThis->m_getFtpRptThreadCnt);
    return 0;
  }
  最后到了线上再执⾏,还是从客户的FTP服务器上拉取不了txt⽂件下来,那就是把  strFtpDirTmp += "*";  改成  strFtpDirTmp +=
_T("\\*.txt");  是⽆效的了。
然后我想想了,这⾥没有⼏个函数,也都是成熟悉的东西(ftp这协议已经很久了)。最后把问题定在了线上环境的系统上,因为线上的环境是Windows  server  2012,最后了资料,把GetFtpConnection 的后⾯再加上2个参数,这样就能正常运⾏了,路径也换为
了 strFtpDirTmp += "*";    代码更改后如下:
  static THREAD_RETURN __STDCALL ThreadGetRptFromFtp(void *arglist)
  {
    CZzxFxImpl* pThis = (CZzxFxImpl*)arglist;
    if (NULL == pThis)
    {
      return (THREAD_RETURN)0;
    }
    CAdapter::InterlockedIncrement(&pThis->m_getFtpRptThreadCnt);
    pThis->m_getRptThreadExitFlag = false;
    pThis->g_pInetSession = NULL; //会话对象
    pThis->g_pFtpConnection = NULL; //连接对象
    //新建对话
    pThis->g_pInetSession = new CInternetSession(AfxGetAppName(), 1, PRE_CONFIG_INTERNET_ACCESS);
    try
    {
      //新建连接对象
      pThis->g_pFtpConnection = pThis->g_pInetSession->GetFtpConnection(pThis->m_FtpAddr.c_str(), pThis->m_FtpUid.c_str(), pThis->m_FtpPwd.c_str(),21,TRUE);
    }
    catch (CInternetException *pEx)
    {
      TCHAR szError[1024];
      CString strError = "";
      if (pEx->GetErrorMessage(szError, 1024))
      {
        string strLogInfo = cstr::format("连接FTP服务器失败,失败原因 %s", szError);
      CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
      }
      else
      {
        string strLogInfo = cstr::format("连接FTP服务器失败,失败原因:未知异常");
        CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
      }
      pEx->Delete();
      pThis->g_pFtpConnection = NULL;
      return 0;
    }
    try
    {
      memset(pThis->m_szLocalPath, 0x0, sizeof(pThis->m_szLocalPath));
      CAdapter::GetCurrentPath(pThis->m_szLocalPath, MAX_PATH);
      strcat(pThis->m_szLocalPath, "LocalRptFile");
      if (!CAdapter::PathFileExists(pThis->m_szLocalPath))
      {
      CAdapter::CreateDirectory(pThis->m_szLocalPath, 0);
      }
      //创建会话成功
session下载
      while (!pThis->m_getRptThreadExitFlag)
      {
        //设置远程服务端状态报告获取⽬录
        BOOL bSetDir = pThis->g_pFtpConnection->SetCurrentDirectory(pThis->m_FtpRptDir.c_str());
        CFtpFileFind RemoteFinder(pThis->g_pFtpConnection); //远程查⽂件对象
        // pRemoteFinder = new CFtpFileFind(g_pFtpConnection);
        CString strFtpDirTmp = pThis->m_FtpRptDir.c_str();
        strFtpDirTmp += "*";
        BOOL bFindFile = RemoteFinder.FindFile(strFtpDirTmp); //获取⽬录下所有的⽂件
        //BOOL bFindFile = RemoteFinder.FindFile(_T("*")); //获取⽬录下所有的⽂件
        int nFileCnt = 0;
        while (bFindFile)
        {
          bFindFile = RemoteFinder.FindNextFile();
          nFileCnt++;
          CString strFile = RemoteFinder.GetFileName();
          CString strLoaclFilePath = "";
          strLoaclFilePath.Format("%s\\%s", pThis->m_szLocalPath, strFile); //下载到本地⽂件夹的全路径
          CString strErrMsgTmp = "";
          BOOL bGetRlt = pThis->g_pFtpConnection->GetFile(strFile, strLoaclFilePath, FALSE,
FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY); //下载
          if (bGetRlt) //下载成功
          {
            BOOL bRemove = pThis->g_pFtpConnection->Remove(strFile); //删除
            if (!bRemove) //删除失败
            {
              string strLogInfo = cstr::format("⽂件:%s 删除失败,失败代码:%d", strFile, GetLastError());
              CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(),
CSmsTools::LOG_LEVEL_ERROR);
              break;
            }
          }
          else //下载失败
          {
            string strLogInfo = cstr::format("⽂件:%s 下载失败,失败代码:%d", strFile, GetLastError());
            CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(),
CSmsTools::LOG_LEVEL_ERROR);
            continue;
          }
          //解析本地⽂件夹中状态报告⽂件
          pThis->ParseLocalDirectoryRptFile(strLoaclFilePath);
          Sleep(100);
        }
        RemoteFinder.Close();
        Sleep(1000 * 5);
      }
    }
    catch (...) //GetErrorMessage
    {
      string strLogInfo = cstr::format("下载异常");
      CSmsTools::GetInstance().WriteLogMsg(strLogInfo.c_str(), strLogInfo.length(), CSmsTools::LOG_LEVEL_ERROR);
    }
    CAdapter::InterlockedDecrement(&pThis->m_getFtpRptThreadCnt);
    return 0;
  }
  也就是这句后⾯的2个参数起了重要作⽤
  pThis->g_pFtpConnection = pThis->g_pInetSession->GetFtpConnection(pThis->m_FtpAddr.c_str(), pThis->m_FtpUid.c_str(), pThis->m_FtpPwd.c_str(),21,TRUE);
  具体的可看下FTP的被动连接和主动连接。
  接着再把程序拿到线上跑,就能从客户的FTP服务器上拉取txt⽂件的了。
  注:最后⼀个问题,就是本机上我从ftp下载很快,但是到了线上⽣产环境很慢的话,那就是线上的⽹线的问题的了,这时候就要和客户的ftp所在的IP(也就是接⼊的运营商,移动,电信搞清楚)。因为线上的环境数据出去有⼏个运营商(移动,联通,电信),要能从客户这⾥快速下载⽂件的话,就必须把这跑的程序所在的线上机⼦出去的IP单独为运营商移动的(因为客户的IP对应也是移动这块的)。。。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。