分享
 
 
 

wininet实现ftp客户端关于传输进度的分析

王朝vc·作者佚名  2006-01-30
窄屏简体版  字體: |||超大  

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;

}

return FALSE;

}// End IsFtpAscii

// IsFtpAscii结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:FormatFtpError

// 描述:获取系统的错误描述

// 原型:void FormatFtpError(DWORD dwError, // 错误码

// LPTSTR *lpMsg) // 描述信息

// 参数:

// [in] dwError:要查询的系统错误码

// [out] *lpMsg:获取得到的错误描述信息,在使用结束后,请调用LocalFree

// 来释放该空间

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

static void FormatFtpError( DWORD dwError, // 系统错误码

LPTSTR *lpMsg) // 错误描述

{

if(lpMsg == NULL)return;

if(dwError > INTERNET_ERROR_BASE)

{

// 对于Internet的错误,要特殊处理

DWORD dwBufLen = 0;

InternetGetLastResponseInfo(&dwError, NULL, &dwBufLen);

LPTSTR pMsg = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, dwBufLen + 1);

InternetGetLastResponseInfo(&dwError, pMsg, &dwBufLen);

*lpMsg = pMsg;

}

else

{

// 查询普通的错误

FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |

FORMAT_MESSAGE_IGNORE_INSERTS |

FORMAT_MESSAGE_FROM_SYSTEM,

NULL,

dwError,

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPSTR)lpMsg,

0,

NULL);

}

}// End FormatFtpError

// FormatFtpError结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:FtpCtrl_CallbackStatus

// 描述:文件传输过程中的状态回调函数,用于报告当前文件传输的进度等消息

// 原型:void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,// 句柄

// DWORD dwContext, // 上下文

// DWORD dwInternetStatus, // 状态

// LPVOID lpvStatusInformation,// 信息

// DWORD dwStatusInformationLength)

// 参数:

// [in] hInternet:Internet连接的句柄,从InternetOpen中得到

// [in] dwContext:自定义的上下文数据

// [in] dwInternetStatus:当前回调的状态

// [in] lpvStatusInformation:当前回调的信息,根据dwInternetStatus的不同

// 状态代表不同的意思

// [in] dwStatusInformationLength:回调信息lpvStatusInformation的长度

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,

DWORD dwContext,

DWORD dwInternetStatus,

LPVOID lpvStatusInformation,

DWORD dwStatusInformationLength)

{

// 获取上下文信息

CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(dwContext);

if(pcFtpMsg == NULL)

{

return;

}

LPDWORD pdwInformation(NULL);

TRACE("FtpCtrl_CallbackStatus's Internet Status is %d\n", dwInternetStatus);

// 查询当前文件传输状态

switch(dwInternetStatus)

{

case INTERNET_STATUS_RESOLVING_NAME: // 10

TRACE("Looking up the IP address for %s\n", (LPCTSTR)lpvStatusInformation);

break;

case INTERNET_STATUS_NAME_RESOLVED: // 11

TRACE("Name resolved %s\n", (LPCTSTR)lpvStatusInformation);

break;

case INTERNET_STATUS_CONNECTING_TO_SERVER: // 20

// lpvStatusInformation是一个SOCKADDR的指针

TRACE("Connecting to server--%s...\n", (LPCTSTR)lpvStatusInformation);

break;

case INTERNET_STATUS_CONNECTED_TO_SERVER: // 21

// lpvStatusInformation是一个SOCKADDR的指针

TRACE("Connected to server--%s\n", (LPCTSTR)lpvStatusInformation);

break;

case INTERNET_STATUS_SENDING_REQUEST: // 30

TRACE("Sending request\n");

break;

case INTERNET_STATUS_REQUEST_SENT: // 31

{

// 发送数据到服务器

if(!pcFtpMsg->GetFtpDirect())

{

// 只有当处于上传状态的时候,才处理

if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 5)

{

// 5这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议

// 所以还不知道,将来如果知道原因,可以补充上

pcFtpMsg->m_dwFtpHead ++;

}

pdwInformation = (LPDWORD)lpvStatusInformation;

if(pcFtpMsg->m_dwFtpHead == 5)

{

DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);

TRACE("本次发送的数据大小为: %d,总共数据为:%d\n", *pdwInformation,

dwCurrentSize);

if(pcFtpMsg->GetCurrentFtpWnd() != NULL)

{

// 首先的第一选择是给窗口发送消息

::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_transfer,

dwCurrentSize);

}

else if(pcFtpMsg->GetCurrentFtpThread() != 0)

{

::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_transfer,

dwCurrentSize);

}

}// End if 5,经验值

}// end if 文件上传

}

break;

case INTERNET_STATUS_RESPONSE_RECEIVED: // 41

{

// 从服务器接收到的响应

if(pcFtpMsg->GetFtpDirect())

{

// 只有当处于下载状态的时候,才处理

pdwInformation = (LPDWORD)lpvStatusInformation;

if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 6)

{

// 6这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议

// 所以还不知道,将来如果知道原因,可以补充上

pcFtpMsg->m_dwFtpHead ++;

// TRACE("在连接之后第%d次接收数据!\n", pcFtpMsg->m_dwFtpHead);

}

if(pcFtpMsg->m_dwFtpHead == 6)

{

DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);

TRACE("Response received: %d, TotalReceived is %d\n",

*pdwInformation, dwCurrentSize);

if(pcFtpMsg->GetCurrentFtpWnd() != NULL)

{

::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_transfer,

dwCurrentSize);

}

else if(pcFtpMsg->GetCurrentFtpThread() != 0)

{

::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_transfer,

dwCurrentSize);

}

}// End if 6,经验值

}// End if 文件下载

}

break;

case INTERNET_STATUS_RECEIVING_RESPONSE: // 40

// 等待服务器的响应,lpvStatusInformation = NULL

TRACE("等待服务器的响应!\n");

break;

case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: // 42

case INTERNET_STATUS_PREFETCH: // 43

case INTERNET_STATUS_CLOSING_CONNECTION: // 50

TRACE("Closing connection\n");

break;

case INTERNET_STATUS_CONNECTION_CLOSED: // 51

TRACE("Connection closed\n");

break;

case INTERNET_STATUS_HANDLE_CREATED: // 60

{

LPINTERNET_ASYNC_RESULT ptIAR =

reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);

if(hInternet == pcFtpMsg->GetCurrentConnect())

{

TRACE("Connect Handle Created!\n");

pcFtpMsg->m_dwFtpHead = 1;

}

else if(hInternet == pcFtpMsg->GetCurrentSession())

{

TRACE("Session handle created!\n");

}

}

break;

case INTERNET_STATUS_HANDLE_CLOSING: // 70

pcFtpMsg->m_dwFtpHead = 0;

TRACE("Handle closed with dif %d!\n",

pcFtpMsg->GetCurrentFtpSize() - pcFtpMsg->GetTotalFileSize());

break;

case INTERNET_STATUS_DETECTING_PROXY: // 80

TRACE("Detecting proxy\n");

break;

case INTERNET_STATUS_REQUEST_COMPLETE: // 100

// 一个异步操作已经完成,lpvStatusInformation是INTERNET_ASYNC_RESULT的指针

{

LPINTERNET_ASYNC_RESULT ptIAR =

reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);

TRACE("一个异步操作完成,错误为:%d,结果为:%d\n",

ptIAR->dwError, ptIAR->dwResult);

}

break;

case INTERNET_STATUS_REDIRECT: // 110

TRACE("HTTP request redirected to \n");

break;

case INTERNET_STATUS_INTERMEDIATE_RESPONSE: // 120

TRACE("Received intermediate status message from the server.\n");

break;

case INTERNET_STATUS_STATE_CHANGE: // 200

TRACE("'Moved between a secure and a nonsecure site\n");

{

LPDWORD pdwRead = (LPDWORD)lpvStatusInformation;

switch(*pdwRead)

{

case INTERNET_STATE_CONNECTED: // 0x00000001

TRACE("Connected state moved between secure and nonsecure site\n");

break;

case INTERNET_STATE_DISCONNECTED: // 0x00000002

TRACE("Disconnected from network\n");

break;

case INTERNET_STATE_DISCONNECTED_BY_USER: // 0x00000010

TRACE("Disconnected by user request\n");

break;

case INTERNET_STATE_IDLE: // 0x00000100

TRACE("No network requests are being made (by Wininet).\n");

break;

case INTERNET_STATE_BUSY: // 0x00000200

TRACE("Network requests are being made (by Wininet).\n");

break;

case INTERNET_STATUS_USER_INPUT_REQUIRED: // 0x00000040

TRACE("The request requires user input to complete\n");

break;

default:

break;

}

}

break;

default:

break;

}

}// End Ftp_CallbackStatus

// Ftp_CallbackStatu结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:FtpClientDnloadThread

// 描述:文件传输——下载客户端线程

// 原型:DWORD WINPAI FtpClientDnloadThread(LPVOID pParam) // 入口参数

// 参数:

// [in] pParam:下载文件的入口参数

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

DWORD WINAPI FtpClientDnloadThread(LPVOID pParam) // 入口参数

{

CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(pParam);

if(pcFtpMsg == NULL)

{

return -1;

}

// 获取文件

BOOL bRet = FtpGetFile( pcFtpMsg->GetCurrentConnect(),

pcFtpMsg->GetCurrentRemoteFile(),

pcFtpMsg->GetCurrentLocalFile(),

FALSE,

FILE_ATTRIBUTE_NORMAL,

pcFtpMsg->GetCurrentFileType() |

INTERNET_FLAG_RELOAD |

INTERNET_FLAG_RESYNCHRONIZE,

(DWORD)pcFtpMsg);

LPTSTR lpMsg = NULL;

DWORD dwErr = GetLastError();

FormatFtpError(dwErr, &lpMsg);

TRACE("FtpGetFile Error with %d--%s\n", dwErr, lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

if(pcFtpMsg->GetCurrentFtpWnd() != NULL)

{

::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_end,

dwErr);

}

else if(pcFtpMsg->GetCurrentFtpThread() != 0)

{

::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_end,

dwErr);

}

pcFtpMsg->ClearFtpSession();

TRACE("FtpGetFile Thread with id 0x%x end!\n", GetCurrentThreadId());

if(!bRet)

return -1;

return 0;

}// End FtpClientDnloadThread

// FtpClientDnloadThread结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:FtpClientUploadThread

// 描述:文件传输——上传文件线程

// 原型:DWORD WINAPI FtpClientUploadThread(LPVOID pParam) // 入口参数

// 参数:

// [in] pParam:上传文件需要的参数

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

DWORD WINAPI FtpClientUploadThread(LPVOID pParam)

{

CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(pParam);

if(pcFtpMsg == NULL)

{

return -1;

}

// 上传文件

BOOL bRet = FtpPutFile( pcFtpMsg->GetCurrentConnect(),

pcFtpMsg->GetCurrentLocalFile(),

pcFtpMsg->GetCurrentRemoteFile(),

pcFtpMsg->GetCurrentFileType() |

INTERNET_FLAG_RESYNCHRONIZE,

(DWORD)pcFtpMsg);

LPTSTR lpMsg = NULL;

DWORD dwErr = GetLastError();

FormatFtpError(dwErr, &lpMsg);

TRACE("FtpPutFile Error with %d--%s\n", dwErr, lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

if(pcFtpMsg->GetCurrentFtpWnd() != NULL)

{

::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_end,

dwErr);

}

else if(pcFtpMsg->GetCurrentFtpThread() != 0)

{

::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),

pcFtpMsg->GetRegisterMsgHandle(),

CFtpClientCtrl::ftp_end,

dwErr);

}

pcFtpMsg->ClearFtpSession();

TRACE("FtpPutFile Thread with id 0x%x end!\n", GetCurrentThreadId());

if(!bRet)

{

return -1;

}

return 0;

}// End FtpClientUploadThread

// FtpClientUploadThread结束

//////////////////////////////////////////////////////////////////////////

CFtpClientCtrl::CFtpClientCtrl()

:m_wFtpSrvPort(INTERNET_DEFAULT_FTP_PORT)

,m_hSession(NULL)

,m_hConnect(NULL)

,m_hFtpThread(NULL)

,m_dwFtpThread(0)

,m_dwCurrentFtpSize(0)

,m_hWnd(NULL)

,m_dwFileType(FTP_TRANSFER_TYPE_UNKNOWN)

,m_uMsgHandle(0)

,m_bFtpDirect(TRUE)

,m_dwFtpHead(0)

,m_bTransfering(FALSE)

{

::ZeroMemory(m_szFtpSrvIp, 24);

::ZeroMemory(m_szFtpSrvPwd, 32);

::ZeroMemory(m_szFtpSrvUser, 32);

::ZeroMemory(m_szProxyName, 64);

::ZeroMemory(m_szProxyPwd, 32);

::ZeroMemory(m_szRemote, MAX_PATH);

::ZeroMemory(m_szLocal, MAX_PATH);

}

CFtpClientCtrl::~CFtpClientCtrl()

{

InternetCloseHandle(m_hConnect);

InternetCloseHandle(m_hSession);

}

//////////////////////////////////////////////////////////////////////////

// 名称:SetServerParam

// 描述:设置文件传输的FTP服务器参数,包括服务器的地址、端口、用户和,口令等

// 原型:BOOL SetServerParam(LPCTSTR lpszIpAddr, // 服务器地址

// LPCTSTR lpszUser, // 用户

// LPCTSTR lpszPwd, // 口令

// WORD wPort, // 端口

// LPCTSTR lpszProxyName, // 代理名称

// LPCTSTR lpszProxyPwd) // 代理口令

// 参数:

// [in] lpszIpAddr:FTP服务器的地址

// [in] lpszUser:FTP服务器的用户名称

// [in] lpszPwd:FTP服务器的用户口令

// [in] wPort:FTP服务器的侦听端口

// [in] lpszProxyName:FTP服务器的代理用户

// [in] lpszProxyPwd:FTP服务器的代理对应口令

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::SetServerParam(LPCTSTR lpszIpAddr,

LPCTSTR lpszUser,

LPCTSTR lpszPwd,

WORD wPort,

LPCTSTR lpszProxyName,

LPCTSTR lpszProxyPwd)

{

if( lpszIpAddr == NULL ||

lpszUser == NULL ||

lpszPwd == NULL ||

wPort == 0)

return FALSE;

::ZeroMemory(m_szFtpSrvIp, 24);

_sntprintf(m_szFtpSrvIp, 24, _T("%s"), lpszIpAddr);

::ZeroMemory(m_szFtpSrvUser, 32);

_sntprintf(m_szFtpSrvUser, 32, _T("%s"), lpszUser);

::ZeroMemory(m_szFtpSrvPwd, 32);

_sntprintf(m_szFtpSrvPwd, 32, _T("%s"), lpszPwd);

m_wFtpSrvPort = wPort;

::ZeroMemory(m_szProxyName, 64);

_sntprintf(m_szProxyName, 64, _T("%s"), lpszProxyName);

::ZeroMemory(m_szProxyPwd, 32);

_sntprintf(m_szProxyPwd, 32, _T("%s"), lpszProxyPwd);

return TRUE;

}// End SetServerParam

// SetServerParam结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:DownloadFile

// 描述:下载文件

// 原型:BOOL DownloadFile( LPCTSTR lpszRemote, // 远程文件

// LPCTSTR lpszLocal, // 本地文件

// DWORD dwFileType) // 文件类型

// 参数:

// [in] lpszRemote:要下载的文件名称

// [in] lpszLocal:文件下载后保存到本地的路径

// [in] dwFileType:文件传输的方式

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::DownloadFile(LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

::ZeroMemory(m_szRemote, MAX_PATH);

_sntprintf(m_szRemote, MAX_PATH, _T("%s"), lpszRemote);

::ZeroMemory(m_szLocal, MAX_PATH);

_sntprintf(m_szLocal, MAX_PATH, _T("%s"), lpszLocal);

m_dwFileType = dwFileType;

m_dwFtpHead = 0;

m_bFtpDirect = TRUE;

// 设置文件传输方式

if(dwFileType == FTP_TRANSFER_TYPE_UNKNOWN)

{

LPCTSTR lpszExt = _tcsrchr(lpszRemote, '.');

if(IsFtpAscii(lpszExt))

m_dwFileType = FTP_TRANSFER_TYPE_ASCII;

else

m_dwFileType = FTP_TRANSFER_TYPE_BINARY;

}

// 获取远程文件的大小,有的时候不能成功

m_dwTotalFileSize = GetRemoteFileSize();

TRACE("Remote File size is %d\n", m_dwTotalFileSize);

m_dwCurrentFtpSize = 0;

LPTSTR lpMsg = NULL; // 错误信息

// 打开Internet连接

m_hSession = InternetOpen( _T("Ftp_Ctrl"),

INTERNET_OPEN_TYPE_DIRECT,

m_szProxyName,

m_szProxyPwd,

INTERNET_FLAG_NO_CACHE_WRITE);

if(m_hSession == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetOpen Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

return FALSE;

}

// 设置状态回调函数

if(InternetSetStatusCallback(m_hSession, FtpCtrl_CallbackStatus) ==

INTERNET_INVALID_STATUS_CALLBACK)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetSetStatusCallback Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

InternetCloseHandle(m_hSession);

return FALSE;

}

// 连接到对方

m_hConnect = InternetConnect( m_hSession,

m_szFtpSrvIp,

m_wFtpSrvPort,

m_szFtpSrvUser,

m_szFtpSrvPwd,

INTERNET_SERVICE_FTP,

INTERNET_FLAG_PASSIVE |

INTERNET_FLAG_EXISTING_CONNECT,

(DWORD)this);

if(m_hConnect == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetConnect Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

InternetCloseHandle(m_hSession);

return FALSE;

}

if(m_hWnd != NULL)

{

// 发送消息,开始下载了

::PostMessage( m_hWnd, m_uMsgHandle,

(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);

}

else if(m_dwThread != 0)

{

::PostThreadMessage(m_dwThread, m_uMsgHandle,

(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);

}

// 创建文件下载线程

m_hFtpThread = CreateThread(NULL,

0,

FtpClientDnloadThread,

this,

0,

&m_dwFtpThread);

if(m_hFtpThread == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("CreateThread Error with %s\n", lpMsg);

LocalFree(lpMsg);

InternetCloseHandle(m_hConnect);

InternetCloseHandle(m_hSession);

return FALSE;

}

m_bTransfering = TRUE;

return TRUE;

}// End DownloadFile

// DownloadFile结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:BeginDownload

// 描述:开始下载文件

// 原型:BOOL BeginDownload(HWND hWnd, // 接收消息的窗口

// LPCTSTR lpszRemote, // 远程文件

// LPCTSTR lpszLocal, // 本地文件

// DWORD dwFileType) // 文件类型

// 参数:

// [in] hWnd:用于接收文件传输状态报告的窗口句柄

// [in] lpszRemote:要下载的文件名称,保存在服务器上的

// [in] lpszLocal:文件下载后保存到本地的路径

// [in] dwFileType:文件传输的方式

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::BeginDownload(HWND hWnd,

LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

if( lpszRemote == NULL ||

lpszLocal == NULL ||

(dwFileType != FTP_TRANSFER_TYPE_BINARY &&

dwFileType != FTP_TRANSFER_TYPE_ASCII &&

dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||

hWnd == NULL)

return FALSE;

if(m_bTransfering)

return FALSE;

m_hWnd = hWnd;

return DownloadFile(lpszRemote,

lpszLocal,

dwFileType);

}// End BeginDownload

// BeginDownload结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:BeginDownload

// 描述:开始下载文件

// 原型:BOOL BeginDownload(DWORD dwThread, // 接收消息的线程

// LPCTSTR lpszRemote, // 远程文件

// LPCTSTR lpszLocal, // 本地文件

// DWORD dwFileType) // 文件类型

// 参数:

// [in] dwThread:用于接收文件传输状态报告的线程句柄

// [in] lpszRemote:要下载的文件名称,保存在服务器上的

// [in] lpszLocal:文件下载后保存到本地的路径

// [in] dwFileType:文件传输的方式

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::BeginDownload(DWORD dwThread,

LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

if( lpszRemote == NULL ||

lpszLocal == NULL ||

(dwFileType != FTP_TRANSFER_TYPE_BINARY &&

dwFileType != FTP_TRANSFER_TYPE_ASCII &&

dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||

dwThread == 0)

return FALSE;

if(m_bTransfering)

return FALSE;

m_dwThread = dwThread;

return DownloadFile(lpszRemote,

lpszLocal,

dwFileType);

}// End BeginDownload

// BeginDownload结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:UploadFile

// 描述:上传文件

// 原型:BOOL UploadFile( LPCTSTR lpszRemote, // 远程文件

// LPCTSTR lpszLocal, // 本地文件

// DWORD dwFileType) // 文件类型

// 参数:

// [in] lpszRemote:上传后保存的文件名称

// [in] lpszLocal:要上传的本地文件路径

// [in] dwFileType:文件传输的方式

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::UploadFile(LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

m_dwFtpHead = 0;

m_bFtpDirect = FALSE;

::ZeroMemory(m_szRemote, MAX_PATH);

_sntprintf(m_szRemote, MAX_PATH, _T("%s"), lpszRemote);

::ZeroMemory(m_szLocal, MAX_PATH);

_sntprintf(m_szLocal, MAX_PATH, _T("%s"), lpszLocal);

m_dwFileType = dwFileType;

// 设置文件传输的方式

if(dwFileType == FTP_TRANSFER_TYPE_UNKNOWN)

{

LPCTSTR lpszExt = _tcsrchr(lpszLocal, '.');

if(IsFtpAscii(lpszExt))

m_dwFileType = FTP_TRANSFER_TYPE_ASCII;

else

m_dwFileType = FTP_TRANSFER_TYPE_BINARY;

}

// 计算本地文件的大小,只要该文件存在,就能够得到大小

m_dwTotalFileSize = GetLocalFileSize();

if(m_dwTotalFileSize == (DWORD)-1)

{

m_dwTotalFileSize = 0;

return FALSE;

}

TRACE("Local File size is %d\n", m_dwTotalFileSize);

m_dwCurrentFtpSize = 0;

LPTSTR lpMsg = NULL; // 消息描述

// 打开Internet连接会话

m_hSession = InternetOpen( _T("Ftp_Ctrl"),

INTERNET_OPEN_TYPE_DIRECT,

m_szProxyName,

m_szProxyPwd,

INTERNET_FLAG_NO_CACHE_WRITE);

if(m_hSession == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetOpen Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

return FALSE;

}

// 设置文件传输状态回调函数

if(InternetSetStatusCallback(m_hSession, FtpCtrl_CallbackStatus) ==

INTERNET_INVALID_STATUS_CALLBACK)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetSetStatusCallback Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

InternetCloseHandle(m_hSession);

return FALSE;

}

// 开始建立文件传输的连接

m_hConnect = InternetConnect( m_hSession,

m_szFtpSrvIp,

m_wFtpSrvPort,

m_szFtpSrvUser,

m_szFtpSrvPwd,

INTERNET_SERVICE_FTP,

INTERNET_FLAG_PASSIVE |

INTERNET_FLAG_EXISTING_CONNECT,

(DWORD)this);

if(m_hConnect == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetConnect Error with %s\n", lpMsg);

LocalFree(lpMsg);

lpMsg = NULL;

InternetCloseHandle(m_hSession);

return FALSE;

}

// 发送消息,通知界面开始传输了

if(m_hWnd != NULL)

{

::PostMessage( m_hWnd, m_uMsgHandle,

(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);

}

else if(m_dwThread != 0)

{

::PostThreadMessage(m_dwThread, m_uMsgHandle,

(WPARAM)ftp_begin, (LPARAM)m_dwTotalFileSize);

}

// 创建文件上传线程

m_hFtpThread = CreateThread(NULL,

0,

FtpClientUploadThread,

this,

0,

&m_dwFtpThread);

if(m_hFtpThread == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("CreateThread Error with %s\n", lpMsg);

LocalFree(lpMsg);

InternetCloseHandle(m_hConnect);

InternetCloseHandle(m_hSession);

return FALSE;

}

m_bTransfering = TRUE;

return TRUE;

}// End UploadFile

// UploadFile结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:BeginUpload

// 描述:开始文件上传

// 原型:BOOL BeginUpload(HWND hWnd, // 用于接收消息的窗口句柄

// LPCTSTR lpszRemote, // 上传后保存的文件名称

// LPCTSTR lpszLocal, // 要上传的文件

// DWORD dwFileType) // 文件传输类型

// 参数:

// [in] hWnd:接收文件上传状态报告的窗口句柄

// [in] lpszRemote:文件上传后在服务器端保存的文件名称

// [in] lpszLocal:要上传的本地文件路径

// [in] dwFileType:文件上传的类型

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::BeginUpload(HWND hWnd,

LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

if( lpszRemote == NULL ||

lpszLocal == NULL ||

(dwFileType != FTP_TRANSFER_TYPE_BINARY &&

dwFileType != FTP_TRANSFER_TYPE_ASCII &&

dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||

hWnd == NULL)

return FALSE;

if(m_bTransfering)

return FALSE;

m_hWnd = hWnd;

return UploadFile( lpszRemote,

lpszLocal,

dwFileType);

}// End BeginUpload

// BeginUpload结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:BeginUpload

// 描述:开始文件上传

// 原型:BOOL BeginUpload(DWORD dwThread, // 用于接收消息的线程句柄

// LPCTSTR lpszRemote, // 上传后保存的文件名称

// LPCTSTR lpszLocal, // 要上传的文件

// DWORD dwFileType) // 文件传输类型

// 参数:

// [in] dwThread:接收文件上传状态报告的线程句柄

// [in] lpszRemote:文件上传后在服务器端保存的文件名称

// [in] lpszLocal:要上传的本地文件路径

// [in] dwFileType:文件上传的类型

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::BeginUpload(DWORD dwThread,

LPCTSTR lpszRemote,

LPCTSTR lpszLocal,

DWORD dwFileType)

{

if( lpszRemote == NULL ||

lpszLocal == NULL ||

(dwFileType != FTP_TRANSFER_TYPE_BINARY &&

dwFileType != FTP_TRANSFER_TYPE_ASCII &&

dwFileType != FTP_TRANSFER_TYPE_UNKNOWN) ||

dwThread == 0)

return FALSE;

if(m_bTransfering)

return FALSE;

m_dwThread = dwThread;

return UploadFile( lpszRemote,

lpszLocal,

dwFileType);

}// End BeginUpload

// BeginUpload结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:EndFtpFile

// 描述:结束文件传输进行的操作

// 原型:BOOL EndFtpFile()

// 参数:

//

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::EndFtpFile()

{

if(m_hConnect)

{

InternetCloseHandle(m_hConnect);

m_hConnect = NULL;

}

return TRUE;

}// End EndFtpFile

// EndFtpFile结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:ClearFtpSession

// 描述:清除文件传输会话资源

// 原型:void ClearFtpSession()

// 参数:

//

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

void CFtpClientCtrl::ClearFtpSession()

{

if(m_hConnect != NULL)

{

InternetCloseHandle(m_hConnect);

m_hConnect = NULL;

}

if(m_hSession != NULL)

{

InternetCloseHandle(m_hSession);

m_hSession = 0;

}

m_hWnd = NULL;

m_dwThread = 0;

m_bTransfering = FALSE;

}

//////////////////////////////////////////////////////////////////////////

// 名称:IncreaseFtpSize

// 描述:在文件传输过程中,设置实际已经传输的文件大小

// 原型:DWORD IncreaseFtpSize(DWORD dwStep) // 本地大小

// 参数:

// [in] dwStep:本次状态中传输的大小

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

DWORD CFtpClientCtrl::IncreaseFtpSize(DWORD dwStep)

{

if(m_dwCurrentFtpSize < m_dwTotalFileSize)

m_dwCurrentFtpSize += dwStep;

return m_dwCurrentFtpSize;

}// End IncreaseFtpSize

// IncreaseFtpSize结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:GetRemoteFileSize

// 描述:获取远程文件的大小

// 原型:DWORD GetRemoteFileSize()

// 参数:

//

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

DWORD CFtpClientCtrl::GetRemoteFileSize()

{

if(m_szRemote == NULL)

{

return 0;

}

LPTSTR lpMsg = NULL;

// 开始连接网络

HINTERNET hInternet = InternetOpen( _T("Ftp_Ctrl"),

INTERNET_OPEN_TYPE_DIRECT,

m_szProxyName,

m_szProxyPwd,

INTERNET_FLAG_NO_CACHE_WRITE);//INTERNET_FLAG_ASYNC

if(hInternet == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetOpen Error With %d--%s\n", GetLastError(), lpMsg);

LocalFree(lpMsg);

return 0;

}

// 连接

HINTERNET hConnect = InternetConnect( hInternet,

m_szFtpSrvIp,

m_wFtpSrvPort,

m_szFtpSrvUser,

m_szFtpSrvPwd,

INTERNET_SERVICE_FTP,

INTERNET_FLAG_PASSIVE |

INTERNET_FLAG_EXISTING_CONNECT,

0);

if(hConnect == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("InternetConnect Error With %d--%s\n", GetLastError(), lpMsg);

LocalFree(lpMsg);

InternetCloseHandle(hInternet);

return 0;

}

// 打开文件

HINTERNET hFile = FtpOpenFile( hConnect,

m_szRemote,

GENERIC_READ,

m_dwFileType |

INTERNET_FLAG_RELOAD |

INTERNET_FLAG_RESYNCHRONIZE,

0);

if(hFile == NULL)

{

FormatFtpError(GetLastError(), &lpMsg);

TRACE("FtpOpen Error With %d--%s\n", GetLastError(), lpMsg);

LocalFree(lpMsg);

InternetCloseHandle(hConnect);

InternetCloseHandle(hInternet);

return 0;

}

typedef DWORD (WINAPI *FtpGetFileSize_Proc)(HINTERNET, LPDWORD);

HINSTANCE hInst = LoadLibrary("wininet.dll");

if(hInst == NULL)

{

TRACE("Load Library failed!\n");

InternetCloseHandle(hFile);

InternetCloseHandle(hConnect);

InternetCloseHandle(hInternet);

return 0;

}

FtpGetFileSize_Proc pfnFtpGetFileSize =

(FtpGetFileSize_Proc)GetProcAddress(hInst, "FtpGetFileSize");

if(pfnFtpGetFileSize == NULL)

{

TRACE("Get Proc FtpGetFileSize Failed!\n");

InternetCloseHandle(hFile);

InternetCloseHandle(hConnect);

InternetCloseHandle(hInternet);

FreeLibrary(hInst);

return 0;

}

DWORD dwSize = pfnFtpGetFileSize(hFile, NULL);

FreeLibrary(hInst);

InternetCloseHandle(hFile);

InternetCloseHandle(hConnect);

InternetCloseHandle(hInternet);

return dwSize;

}// End GetRemoteFileSize

// GetRemoteFileSize结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:GetLocalFileSize

// 描述:获取本地文件的大小

// 原型:DWORD GetLocalFileSize()

// 参数:

//

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

DWORD CFtpClientCtrl::GetLocalFileSize()

{

HANDLE hFile = CreateFile( m_szLocal,

0,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

if(hFile == INVALID_HANDLE_VALUE)

{

return -1;

}

DWORD dwSize = GetFileSize(hFile, NULL);

CloseHandle(hFile);

return dwSize;

}// End GetLocalFileSize

// GetLocalFileSize结束

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// 名称:IsFileAscii

// 描述:判断文件的传输方式是否为ASCII

// 原型:BOOL IsFileAscii(LPCTSTR lpszFile) // 文件名称

// 参数:

// [in] lpszFile:要判断的文件名称

// 备注:

//

// 修改记录

// 日期 版本 修改人 修改内容

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 2003/09/08 V2.00 wjr 创建

//________________________________________________________________________

BOOL CFtpClientCtrl::IsFileAscii(LPCTSTR lpszFile) // 文件名称

{

if(lpszFile == NULL)

return FALSE;

LPCTSTR lpszExt = _tcsrchr(lpszFile, '.'); // 得到文件后缀

return IsFtpAscii(lpszExt);

}// End IsFileAscii

// IsFileAscii结束

//////////////////////////////////////////////////////////////////////////

使用方法:

// 注册文件传输控件必要的参数

m_cFtpCtrl.SetServerParam( szNmsIp), // 网管服务器地址

szFtpUser, // ftp服务器用户

szFtpPwd); // ftp服务器口令

m_cFtpCtrl.RegisterMsgHandle(WM_ FTP_PROGRESS);

// 设置文件传输控件的传输方向

m_cFtpCtrl.SetFtpDirect(FALSE);

if(!m_cFtpCtrl.BeginUpload( GetSafeHwnd(),

m_strRemote,

m_strLocalFile))

{

AfxMessageBox(_T("文件开始上传失败!"));

PostMessage(WM_CLOSE);

return TRUE;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有