|
作者: 来源:csdn 更新日期:2002-08-06 |
wininet提供了接口FtpGetFile实现从ftp服务器下载文件;提供了接口FtpPutFile实现把文件上传到ftp服务器上。通过这两个接口,我们能够完成基本的ftp文件传输客户端功能。但是在传输的同时,我们希望知道当前大概传输了多少,传输完整个文件大概需要多长时间,当前进度是多少,大概还有多长时间才能传输完毕。 单纯依靠这两个接口,我们无法实现这个功能。仔细翻阅msdn,发现wininet还提供了这样一个接口:InternetSetStatusCallback。该函数就是设置文件传输的回调函数,其原型如下: INTERNET_STATUS_CALLBACK InternetSetStatusCallback( HINTERNET hInternet,
INTERNET_STATUS_CALLBACK lpfnInternetCallback
); 该接口为internet会话设置一个状态回调函数:lpfnInternetCallback,该回调函数的原型声明如下: void CALLBACK InternetStatusCallback( HINTERNET hInternet,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
); 通过这个回调函数,我们可以实现对当前传输进度的控制:可以统计出到目前已经传输了多少字节,并且计算出传输速率,从而可以得知大概还剩下多少时间。 下面这个类就是实现对ftp文件传输客户端的封装:
////////////////////////////////////////////////////////////////////////// // 模块名称:文件传输状态控制 // 模块功能:实现对界面时时报告当前文件传输的进度状态,并且实现上传和下载 // 文件的客户端功能。 // 文件名称:ftpclientctrl.h //________________________________________________________________________ #ifndef _WININET_ #include <wininet.h> #endif
class CFtpClientCtrl { public: CFtpClientCtrl(); virtual ~CFtpClientCtrl(); enum { ftp_begin, // 对于该事件,wparam = ftp_begin,lparam表示要传输的文件大小 ftp_transfer, // 对于该事件,wparam = ftp_transfer,lParam表示已经传输的大小 ftp_end // 对于该事件,wparam = ftp_end,lparam表示结果,0--失败,1--成功 };
// 设置ftp服务器的连接参数 BOOL SetServerParam( LPCTSTR lpszIpAddr, // IP地址 LPCTSTR lpszUser, // 登录名称 LPCTSTR lpszPwd, // 登录口令 WORD wPort = INTERNET_DEFAULT_FTP_PORT, // FTP服务器端口 LPCTSTR lpszProxyName = NULL, // 代理名称 LPCTSTR lpszProxyPwd = NULL); // 代理口令
// 开始下载文件 BOOL BeginDownload( HWND hWnd, // 接收消息的窗口 LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 保存本地的文件 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输 BOOL BeginDownload( DWORD dwThread, // 接收消息的线程 LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 保存本地的文件 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
// 开始上传文件 BOOL BeginUpload( HWND hWnd, // 接收消息的窗口 LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 本地文件名称 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输 BOOL BeginUpload( DWORD dwThread, // 接收消息的线程 LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 本地文件名称 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输 // 结束传输文件 BOOL EndFtpFile();
// 得到当前ftp的会话句柄 HINTERNET GetCurrentSession() const{return m_hSession;} // 得到当前的连接句柄 HINTERNET GetCurrentConnect() const{return m_hConnect;} // 获取远程文件名称 LPCTSTR GetCurrentRemoteFile() const{return m_szRemote;} // 获取本地文件名称 LPCTSTR GetCurrentLocalFile() const{return m_szLocal;} // 获取当前传输的文件类型 DWORD GetCurrentFileType() const{return m_dwFileType;} // 获取当前传输接收消息窗口 HWND GetCurrentFtpWnd() const{return m_hWnd;} // 获取当前传输接收消息线程 DWORD GetCurrentFtpThread() const{return m_dwThread;} // 获取当前已经传输的大小 DWORD GetCurrentFtpSize() const{return m_dwCurrentFtpSize;} // 递增已经传输的大小 DWORD IncreaseFtpSize(DWORD dwStep); // 注册一个消息 void RegisterMsgHandle(UINT uMsgHandle){m_uMsgHandle = uMsgHandle;} // 获取已经注册的消息 UINT GetRegisterMsgHandle() const{return m_uMsgHandle;} // 获取文件总长度 DWORD GetTotalFileSize() const{return m_dwTotalFileSize;} // 清除FTP void ClearFtpSession(); // 设置FTP传输方向 void SetFtpDirect(BOOL bDownload = TRUE){m_bFtpDirect = bDownload;} // 获取FTP传输方向 BOOL GetFtpDirect() const{return m_bFtpDirect;} // 判断文件类型是否是ASCII static BOOL IsFileAscii(LPCTSTR lpszFile); protected: // 获取远程文件的大小 DWORD GetRemoteFileSize(); // 获取本地文件的大小 DWORD GetLocalFileSize(); // 下载文件 BOOL DownloadFile( LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 保存本地的文件 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输 // 上传文件 BOOL UploadFile( LPCTSTR lpszRemote, // 远程文件名称 LPCTSTR lpszLocal, // 保存本地的文件 DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
protected: HINTERNET m_hSession; // 应用于InternetOpen HINTERNET m_hConnect; // 应用于InternetConnect
TCHAR m_szFtpSrvIp[24]; // FTP服务器的ip地址 TCHAR m_szFtpSrvUser[32]; // FTP服务器的登录用户 TCHAR m_szFtpSrvPwd[32]; // FTP服务器的登录口令 TCHAR m_szProxyName[64]; // 代理的名称 TCHAR m_szProxyPwd[32]; // 代理的口令 WORD m_wFtpSrvPort; // FTP服务器的监听端口
HANDLE m_hFtpThread; // FTP传输的线程句柄 DWORD m_dwFtpThread; // FTP传输的线程编号
TCHAR m_szRemote[MAX_PATH]; // 远程文件 TCHAR m_szLocal[MAX_PATH]; // 本地文件 DWORD m_dwFileType; // 传输的文件类型
HWND m_hWnd; // 接收传输进度消息的窗口 DWORD m_dwThread; // 接收传输进度消息的线程
DWORD m_dwCurrentFtpSize; // 当前传输的大小 DWORD m_dwTotalFileSize; // 文件总大小
UINT m_uMsgHandle; // 消息句柄,由外界定义
BOOL m_bFtpDirect; // 传输方向,TRUE为下载,FALSE为上传,默认为TRUE
public: DWORD m_dwFtpHead; // FTP传输头--自从InternetConnect之后发送的次数 private: BOOL m_bTransfering; // 是否正在传输 };
////////////////////////////////////////////////////////////////////////// // 模块名称:文件传输状态控制 // 模块功能:实现对界面时时报告当前文件传输的进度状态,并且实现上传和下载 // 文件的客户端功能。 // 文件名称:ftpclientctrl.cpp //________________________________________________________________________ #include "FtpClientCtrl.h" #pragma comment(lib, "wininet.lib") #define INTERNET_STATUS_USER_INPUT_REQUIRED 0x00000040 #define INTERNET_STATUS_DETECTING_PROXY 80
#define FTP_FILE_ASCII_COUNT 12 LPCTSTR g_lpszAsciiFileFtp[FTP_FILE_ASCII_COUNT] = { _T(".txt"), _T(".ini"), _T(".c"), _T(".cpp"), _T(".h"), _T(".hpp"), _T(".bat"), _T(".html"), _T(".java"), _T(".htm"), _T(".jav"), _T(".doc") };
////////////////////////////////////////////////////////////////////////// // 名称:IsFtpAscii // 描述:经验判断一个要进行文件传输的文件是否是ASCII方式的 // 原型:BOOL IsFtpAscii(LPCTSTR lpszExt) // 文件后缀 // 参数: // [in] lpszExt:要判断的文件的后缀名称 // 备注: // // 修改记录 // 日期 版本 修改人 修改内容 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 2003/09/08 V2.00 wjr 创建 //________________________________________________________________________ BOOL IsFtpAscii(LPCTSTR lpszExt) { if(lpszExt == NULL) return FALSE; for(int nIndex = 0; nIndex < FTP_FILE_ASCII_COUNT; nIndex ++) { if(_tcsicmp(lpszExt, g_lpszAsciiFileFtp[nIndex]) == 0) return TRUE; }
|
wininet实现ftp客户端关于传输进度的分析
最新推荐文章于 2020-11-27 02:09:56 发布