2023年6月22日发(作者:)
FTP⽂件上传demo该demo主要是封装了MS的,⽅便FTP⽂件上传,解决了在XP系统下⾯InternetConnect()接⼝在FTP服务器不可⽤,连接超时严重,且不可控的问题。该demo在WIN7 64 和XP 32 ⾃测通过。完整⼯程源码下载地址:------------------------------------------------------------------------------------------主要代码如下:ftp.h82936373839464748495051#pragma once#pragma warning(disable:4995)
#include
#include
#ifdef _UNICODE#define tstring wstring#else#define tstring string#endif
// FTP配置参数typedef struct tagFtpParam{ int iFtpEnable; // 1开启FTP上传,0是关闭FTP上传 TCHAR szFtpServerIp[32]; // FTP服务器IP TCHAR szFtpUser[20]; // FTP登陆账号 TCHAR szFtpPass[30]; // FTP登陆密码 int iFtpPort; // FTP服务端⼝, 默认为21 int iFtpIsPassive; // 1表⽰FTP为被动模式,0表⽰FTP为主动模式 TCHAR szFtpUploadDir[30]; // FTP上传⽬录,如 /test
tagFtpParam() { iFtpEnable = 0; ZeroMemory(szFtpServerIp, sizeof(szFtpServerIp)); ZeroMemory(szFtpUser, sizeof(szFtpUser)); ZeroMemory(szFtpPass, sizeof(szFtpPass)); iFtpPort = 21; iFtpIsPassive = 1; ZeroMemory(szFtpUploadDir, sizeof(szFtpUploadDir)); StringCbCopy(szFtpUploadDir, sizeof(szFtpUploadDir), _T("/test")); }
}FtpParam;
class CFtp{public:
CFtp(void);5575859666768697677787986878889969798995116 CFtp(void);
~CFtp(void);
/** @name UploadDiskFile @brief 往FTP上传磁盘⽂件 @param[in] LPCTSTR pszFilePath, 磁盘⽂件路径 @param[in] LPCTSTR pszUploadDir, 上传到的FTP⽬录,以斜杠/开头,如 /test @return 成功true,失败false */ bool UploadDiskFile(LPCTSTR pszFilePath, LPCTSTR pszUploadDir);
/** @name UploadMemoryFile @brief 往FTP上传内存⽂件 @param[in] PBYTE pbFile, 内存⽂件缓冲区指针 @param[in] int iFileLen, 内存⽂件长度 @param[in] LPCTSTR pszFileName, 保存⽂件名称 @param[in] LPCTSTR pszUploadDir, 上传到的FTP⽬录,以斜杠开头,如/test @return bool */ bool UploadMemoryFile(PBYTE pbFile, int iFileLen, LPCTSTR pszFileName, LPCTSTR pszUploadDir);
/** @name IsFileExists @brief 判断⽂件是否存在
@param[in]: LPCTSTR pszFilePath ⽂件路径 @return ⽂件存在返回true, 否则返回false */ bool IsFileExists(LPCTSTR pszFilePath);
public:
FtpParam m_ftpParam; // ftp配置参数
private:
/** @name ConnFtpServer @brief 连接FTP服务器 @param[in] void @return 成功true,失败false */ bool ConnFtpServer(void);
// 连接FTP线程代理 static unsigned int _stdcall ThreadConnFtpProxy(PVOID pParam) { CFtp *pThis = (CFtp*)pParam; if (pThis != NULL) { pThis->ThreadConnFtp(); } return 0; }
/** @name ThreadConnFtp @brief 连接FTP线程 @param[in] void4125 @return bool */ bool ThreadConnFtp(void);
private: HINTERNET m_hInetOpen; // ⽹络打开句柄 HINTERNET m_hInetConn; // ⽹络连接句柄 HANDLE m_hConnThread; // 连接线程句柄};
829363738394647484950#include "StdAfx.h"#include "Ftp.h"
CFtp::CFtp(void){ m_hInetOpen = NULL; m_hInetConn = NULL; m_hConnThread = NULL;}
CFtp::~CFtp(void){ if (m_hInetOpen != NULL) { InternetCloseHandle(m_hInetOpen); m_hInetOpen = NULL; } if (m_hInetConn != NULL) { InternetCloseHandle(m_hInetConn); m_hInetConn = NULL; }
if (m_hConnThread != NULL) { WaitForSingleObject (m_hConnThread, 1000*30); CloseHandle(m_hConnThread); m_hConnThread = NULL; }}
/** @name ConnFtpServer @brief 连接FTP服务器 @param[in] void @return 成功true,失败false */bool CFtp::ConnFtpServer(void){
WaitForSingleObject(m_hConnThread, 1000*60); m_hConnThread = (HANDLE)_beginthreadex(NULL, 0, ThreadConnFtpProxy, this, 0, NULL); DWORD dwTimeout = 1000*3; // 连接FTP超时时间 if (WaitForSingleObject (m_hConnThread, dwTimeout ) == WAIT_TIMEOUT) { TerminateThread(m_hConnThread, -1); if (m_hConnThread != NULL) { CloseHandle(m_hConnThread); m_hConnThread = NULL;56575859666768697677787986878889969798995 m_hConnThread = NULL; } return false; }
if (m_hConnThread != NULL) { CloseHandle(m_hConnThread); m_hConnThread = NULL; } return true;}
/** @name UploadDiskFile @brief 往FTP上传磁盘⽂件 @param[in] LPCTSTR pszFilePath, 磁盘⽂件路径 @param[in] LPCTSTR pszUploadDir, 上传到的FTP⽬录,以斜杠/开头,如 /test @return 成功true,失败false */bool CFtp::UploadDiskFile(LPCTSTR pszFilePath, LPCTSTR pszUploadDir){ if (pszFilePath == NULL || m_able == 0) { return false; } if (!IsFileExists(pszFilePath)) { return false; } if (!ConnFtpServer()) { return false; }
// 解析上传⽬录 tstring strUploadDir; if (_tcslen(pszUploadDir) > 0) { strUploadDir = pszUploadDir; } else
{ strUploadDir = m_ploadDir; // 默认上传⽬录 } if (() <= 0) { strUploadDir = _T("/result/"); } strUploadDir[0] = _T('/'); // 确保以斜杠/开头 if (strUploadDir[() - 1] != _T('/')) { strUploadDir += _T('/'); // 确保以斜杠/结尾 }
// 确保上传⽬录存在 strUploadDir = /test tstring strCurDir = _T("/"); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); tstring strTmpDir = strUploadDir; bool bRet = true; while((_T('/')) != tstring::npos && bRet) { size_t iStart = (_T('/')); (iStart, 1); size_t iEnd = (_T('/'));8648648648179180 size_t iEnd = (_T('/')); tstring strDir = (iStart, iEnd - iStart); bRet = FtpCreateDirectory(m_hInetConn, strDir.c_str()) > 0 ? true : false; strCurDir += strDir; strCurDir += _T('/'); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); if (iEnd == () - 1) { break; } } FtpSetCurrentDirectory(m_hInetConn, strUploadDir.c_str());
// 解析上传磁盘⽂件名称,如 D: tstring strDiskFilePath = pszFilePath; tstring strDiskFileName; size_t iIndex = (''); if (iIndex != tstring::npos && iIndex >= 0) { strDiskFileName = (iIndex+1, () - 1); }
// 上传磁盘⽂件 tstring strTmpFile = strUploadDir; strTmpFile += strDiskFileName; bRet = FtpPutFile(m_hInetConn, pszFilePath, strTmpFile.c_str(), FTP_TRANSFER_TYPE_BINARY, NULL) > 0 ? true : false;
// 获取错误信息 if (!bRet) { DWORD iErrorCode = GetLastError(); TCHAR szErr[1024] = {0}; DWORD dwLen = 1024; InternetGetLastResponseInfo(&iErrorCode, szErr, &dwLen); OutputDebugString(szErr); }
return bRet;}
/** @name UploadMemoryFile @brief 往FTP上传内存⽂件 @param[in] PBYTE pbFile, 内存⽂件缓冲区指针 @param[in] int iFileLen, 内存⽂件长度 @param[in] LPCTSTR pszFileName, 保存⽂件名称 @param[in] LPCTSTR pszUploadDir, 上传到的FTP⽬录,以斜杠开头,如/test @return bool */bool CFtp::UploadMemoryFile(PBYTE pbFile, int iFileLen, LPCTSTR pszFileName, LPCTSTR pszUploadDir){ if (pbFile == NULL || iFileLen < 1 || m_able == 0) { return false; } if (pszFileName == NULL) { return false; } if (!ConnFtpServer()) { return false; }
// 解析上传⽬录75922224225226227228229234235236237238239244245 // 解析上传⽬录 tstring strUploadDir; if (_tcslen(pszUploadDir) > 0) { strUploadDir = pszUploadDir; } else
{ strUploadDir = m_ploadDir; // 默认上传⽬录 } if (() <= 0) { strUploadDir = _T("/result/"); } strUploadDir[0] = _T('/'); // 确保以斜杠/开头 if (strUploadDir[() - 1] != _T('/')) { strUploadDir += _T('/'); // 确保以斜杠/结尾 }
// 确保上传⽬录存在 strUploadDir = /test
tstring strCurDir = _T("/"); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); tstring strTmpDir = strUploadDir; bool bRet = true; while((_T('/')) != tstring::npos && bRet) { size_t iStart = (_T('/')); (iStart, 1); size_t iEnd = (_T('/')); tstring strDir = (iStart, iEnd - iStart); bRet = FtpCreateDirectory(m_hInetConn, strDir.c_str()) > 0 ? true : false; strCurDir += strDir; strCurDir += _T('/'); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); if (iEnd == () - 1) { break; } } FtpSetCurrentDirectory(m_hInetConn, strUploadDir.c_str());
// 解析上传内存⽂件名称 tstring strMemoryFileName = pszFileName;
// 上传内存⽂件 HINTERNET hFtpFile = NULL; tstring strTmpFile = strUploadDir; strTmpFile += strMemoryFileName; hFtpFile = FtpOpenFile(m_hInetConn, strTmpFile.c_str(), GENERIC_WRITE, INTERNET_FLAG_TRANSFER_BINARY, NULL); if (hFtpFile != NULL) { DWORD dwWrite = 0; bRet = InternetWriteFile(hFtpFile, pbFile, iFileLen, &dwWrite) > 0 ? true : false; }
// 获取错误信息 if (!bRet) { DWORD iErrorCode = GetLastError(); TCHAR szErr[1024] = {0}; DWORD dwLen = 1024; InternetGetLastResponseInfo(&iErrorCode, szErr, &dwLen); OutputDebugString(szErr); } 245246247248249254255256257258259264265266267268269274275276277278279284285286287288289294295296297298299308309310
// 释放内存 if (hFtpFile != NULL) { InternetCloseHandle(hFtpFile); hFtpFile = NULL; }
return bRet;}
/** @name IsFileExists @brief 判断⽂件是否存在
@param[in]: LPCTSTR pszFilePath ⽂件路径 @return ⽂件存在返回true, 否则返回false */bool CFtp::IsFileExists(LPCTSTR pszFilePath){ if (pszFilePath == NULL) { return false; } HANDLE hRet = CreateFile(pszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); bool bRet = false; if (hRet != INVALID_HANDLE_VALUE ) // ⽂件存在
{ bRet = true; } CloseHandle(hRet); return bRet;}
/** @name ThreadConnFtp @brief 连接FTP线程 @param[in] void @return bool */bool CFtp::ThreadConnFtp(void){ if (m_hInetOpen != NULL) { InternetCloseHandle(m_hInetOpen); m_hInetOpen = NULL; } if (m_hInetConn != NULL) { InternetCloseHandle(m_hInetConn); m_hInetConn = NULL; }
// 连接FTP 服务器 //HINTERNET hInetOpen = InternetOpen(_T("CN"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC); // 异步 m_hInetOpen = InternetOpen(_T("CN"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); // 同步
if (m_hInetOpen == NULL) { return false; }
DWORD dwFlags = 0; if(m_Passive == 1) { dwFlags = INTERNET_FLAG_PASSIVE; }33326327 } //DWORD dwTimeOut = 1000*3; // 超时值,经测试在WIN7有效,在XP⽆效,现已改成由线程控制 //InternetSetOption(m_hInetOpen, INTERNET_OPTION_CONNECT_TIMEOUT, &dwTimeOut, sizeof(dwTimeOut)); m_hInetConn = InternetConnect(m_hInetOpen,
m_erverIp,
m_rt, m_ser, m_ass, INTERNET_SERVICE_FTP, dwFlags, NULL);
if (m_hInetConn == NULL) { return false; } return true;}
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687429734a9390.html
评论列表(0条)