需要下载一个FTP上的文件,需要得知下载进度.如果不自己使用SOCKET封装FTP协议,那用什么比较好? 如题!我看到一些例子都是使用了wininet.dll里的函数来进行下载的.但wininet.dll里并不提供返回下载进度.所以很是苦恼.自己用socket封装ftp协议嘛,一来时间不够,二来我对结构设计很烂.写出来的代码保证是乱七八糟的.大家有什么好的现成的ftp类的话,还请给小弟一份.要能有进度的.或者告诉我inet怎么可视进度 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这是一个开源项目的FTP客户端代码,倒是有进度条,不过代码太多了,没仔细看-_-bhttp://www.vckbase.com/code/network/internet/FileZilla_2_2_4b_src.rar 进度当然是需要自己计算了,其实ftp的接口已经提供了这个类似的功能,它有一个回调函数,该回调函数会返回本次传输的数量,这样就可以计算当前一共下载了多少了 呵呵,你要有进度的话就必须得知道接收到的字节数,所以必须用socket来recv我倒是有一个socket写的ftp类,没有进度,不过只要你在下载文件函数里保存下接收字节数就可以自己做进度条了,要的留邮箱! to:flyelf(空谷回音)能否给出简短的示例代码?to:Caps77(二两指针)[email protected]thanks! 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ΪÉÏ´«£¬Ä¬ÈÏΪTRUEpublic: DWORD m_dwFtpHead; // FTP´«ÊäÍ·--×Ô´ÓInternetConnectÖ®ºó·¢Ë͵ĴÎÊýprivate: BOOL m_bTransfering; // ÊÇ·ñÕýÔÚ´«Êä}; 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为上传,默认为TRUEpublic: DWORD m_dwFtpHead; // FTP传输头--自从InternetConnect之后发送的次数private: BOOL m_bTransfering; // 是否正在传输}; //////////////////////////////////////////////////////////////////////////// 名称: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结束////////////////////////////////////////////////////////////////////////// 给我也发个如何?本人也正在做这个,谢谢了[email protected] 晕.那就帮忙发到 [email protected]非常感谢!!! 关于异步I/O方式读取文件内容 新手实时画曲线求助 在sdk creating thread 页中的文档,看不懂 怎样改变对话框标题栏文字的颜色? 程序如何去掉 右键点击图标弹出的 系统菜单(最小化 最大化 还原)? CSocket一Accpet就报错 MessageBox(),确定和取消的功能请教! 高分求助!EDIT控件的不规则形状(如椭圆形),以及背景颜色绘制 撞车,散分,顺便提问。 一个SQL查询问题 大师们win2003 ddk 哪里能找到? 能用CArray<xxx,xxx>xxx方式声明的类的拷贝构造和赋值运算如何写Y?
我倒是有一个socket写的ftp类,没有进度,不过只要你在下载文件函数里保存下接收字节数就可以自己做进度条了,要的留邮箱!
to:Caps77(二两指针)[email protected]
thanks!
{
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ΪÉÏ´«£¬Ä¬ÈÏΪTRUEpublic:
DWORD m_dwFtpHead; // FTP´«ÊäÍ·--×Ô´ÓInternetConnectÖ®ºó·¢Ë͵ĴÎÊý
private:
BOOL m_bTransfering; // ÊÇ·ñÕýÔÚ´«Êä
};
{
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();
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为上传,默认为TRUEpublic:
DWORD m_dwFtpHead; // FTP传输头--自从InternetConnect之后发送的次数
private:
BOOL m_bTransfering; // 是否正在传输
};
// 名称: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结束
//////////////////////////////////////////////////////////////////////////
[email protected]