從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);
      }
      //創建會話成功
      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對應也是移動這塊的)。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM