FTPDownFile.cpp.svn-base
上传用户:szjkjd
上传日期:2022-06-27
资源大小:8968k
文件大小:23k
源码类别:

浏览器

开发平台:

Visual C++

  1. /*! @ftpdownfile.cpp
  2. ********************************************************************************
  3. <PRE>
  4. 模块名         : FTP下载功能实现文件
  5. 文件名         : ftpdownfile.cpp
  6. 相关文件       : ftpdownfile.h
  7. 文件实现功能   : 实现文件在后头提供过FTP协议下载
  8. 作者           : 刘俊
  9. 版本           : 1.0
  10. --------------------------------------------------------------------------------
  11. 备注           : -
  12. --------------------------------------------------------------------------------
  13. 修改记录 : 
  14. 日  期          版本            修改人          修改内容 
  15. 2010/02/08      1.0             刘俊            创建
  16. </PRE>
  17. ********************************************************************************
  18. * 版权所有(c) 2010, 17JAGO, 保留所有权利
  19. *******************************************************************************/
  20. #include "StdAfx.h"
  21. #include ".ftpdownfile.h"
  22. using namespace std;
  23. // 引入winsock lib文件
  24. #pragma comment(lib,"ws2_32.lib")
  25. // 构造函数
  26. CFTPDownFile::CFTPDownFile(void)
  27. {
  28. }
  29. // 析构函数
  30. CFTPDownFile::~CFTPDownFile(void)
  31. {
  32. // 释放资源
  33. ::WSACleanup();
  34. }
  35. /*! @SetFTPinfo
  36. ********************************************************************************
  37. <PRE>
  38. 函数名   : SetFTPinfo
  39. 功能     : FTP网络信息初始化设定,包括IP,端口,用户名,密码
  40. 参数     : [IN]  pFTP_SERVER_IP : 端点服务器的IP地址
  41.    [IN]  usPort : 端点服务器FTP端口
  42.    [IN]  pUsername : 端点服务器FTP用户名
  43.    [IN]  pPwd : 端点服务器FTP密码
  44. 返回值   : 设置成功返回TRUE,失败返回FALSE
  45. 抛出异常 : -
  46. --------------------------------------------------------------------------------
  47. 备注     : 如果pUsername和pPwd都为NULL,则分别设置为匿名用户和空密码
  48. 典型用法 : -
  49. --------------------------------------------------------------------------------
  50. 作者     : 刘俊
  51. </PRE>
  52. *******************************************************************************/
  53. bool CFTPDownFile::SetFTPinfo(const char *pFTP_SERVER_IP, USHORT usPort, const char *pUsername, const char *pPwd)
  54. {
  55. // 参数检查
  56. if ((pFTP_SERVER_IP == NULL) || (0 == usPort)) 
  57. {
  58. return false;
  59. }
  60. // 删除原来的信息
  61. ZeroMemory(this->m_chFTPIP, sizeof(this->m_chFTPIP));
  62. ZeroMemory(this->m_chUserName,sizeof(this->m_chUserName));
  63. ZeroMemory(this->m_chFTPPwd, sizeof(this->m_chFTPPwd));
  64. // 写入新值
  65. strcpy(this->m_chFTPIP, pFTP_SERVER_IP);
  66. this->m_usPort = usPort;
  67. // 用户名设置
  68. if (pUsername) 
  69. {
  70. strcpy(this->m_chUserName, pUsername);
  71. }
  72. else
  73. {
  74. strcpy(this->m_chUserName, "Anonymous");
  75. }
  76. // 密码设置
  77. if (pUsername) 
  78. {
  79. strcpy(this->m_chFTPPwd, pPwd);
  80. }
  81. else
  82. {
  83. strcpy(this->m_chFTPPwd, "");
  84. }
  85. // 填充命令sockaddr_in结构
  86. this->m_sinCommand.sin_family = AF_INET;
  87. // 设定端口
  88. this->m_sinCommand.sin_port = htons(this->m_usPort);
  89. // 设定IP
  90. this->m_sinCommand.sin_addr.S_un.S_addr = inet_addr(this->m_chFTPIP);
  91. // 返回
  92. return true;
  93. }
  94. /*! @SOCKETINIT
  95. ********************************************************************************
  96. <PRE>
  97. 函数名   : SOCKETINIT
  98. 功能     : FTP网络类SOCKET版本检查初始化工作
  99. 参数     : -
  100. 返回值   : 初始化成功返回TRUE,失败返回FALSE
  101. 抛出异常 : -
  102. --------------------------------------------------------------------------------
  103. 备注     : -
  104. 典型用法 : -
  105. --------------------------------------------------------------------------------
  106. 作者     : 刘俊
  107. </PRE>
  108. *******************************************************************************/
  109. bool CFTPDownFile::SOCKETINIT()
  110. {
  111. // 定义版本号
  112. WORD wVersionRequested;
  113. // 定义WSADATA结构
  114. WSADATA wsaData;
  115. int nErr;
  116. wVersionRequested = MAKEWORD( 1, 1 );
  117. // WINSOCK初始化
  118. nErr = WSAStartup( wVersionRequested, &wsaData );
  119. if ( nErr != 0 )
  120. {
  121. return false;
  122. }
  123. // 检查版本号
  124. if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1)
  125. {
  126. return false;
  127. }
  128. //返回
  129. return true;
  130. }
  131. /*! @ConectFTPCOMMAND
  132. ********************************************************************************
  133. <PRE>
  134. 函数名   : ConectFTPCOMMAND
  135. 功能     : FTP连接命令通道
  136. 参数     : -
  137. 返回值   : 连接成功,返回TRUE,否则返回FALSE
  138. 抛出异常 : -
  139. --------------------------------------------------------------------------------
  140. 备注     : -
  141. 典型用法 : -
  142. --------------------------------------------------------------------------------
  143. 作者     : 刘俊
  144. </PRE>
  145. *******************************************************************************/
  146. bool CFTPDownFile::ConectFTPCOMMAND()
  147. {
  148. // 命令SOCKET初始化
  149. this->m_sockCOMMAND = ::socket(AF_INET, SOCK_STREAM, 0);
  150. if (this->m_sockCOMMAND == INVALID_SOCKET) 
  151. {
  152. return false;
  153. }
  154. // 进行连接
  155. if (connect(this->m_sockCOMMAND, (sockaddr*)&this->m_sinCommand, sizeof(this->m_sinCommand)) == SOCKET_ERROR) 
  156. {
  157. return false;
  158. }
  159. // 初始化接受信息BUFF
  160. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  161. // 接受FTP服务器返回的信息
  162. if (recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0) < 1)
  163. {
  164. return false;
  165. }
  166. return true;
  167. }
  168. /*! @CloseCommandConect
  169. ********************************************************************************
  170. <PRE>
  171. 函数名   : CloseCommandConect
  172. 功能     : FTP命令通道关闭
  173. 参数     : -
  174. 返回值   : -
  175. 抛出异常 : -
  176. --------------------------------------------------------------------------------
  177. 备注     : -
  178. 典型用法 : -
  179. --------------------------------------------------------------------------------
  180. 作者     : 刘俊
  181. </PRE>
  182. *******************************************************************************/
  183. void CFTPDownFile::CloseCommandConect()
  184. {
  185. // 关闭命令通道SOCKET连接
  186. closesocket(this->m_sockCOMMAND);
  187. }
  188. /*! @GetFTPRecvMsg
  189. ********************************************************************************
  190. <PRE>
  191. 函数名   : GetFTPRecvMsg
  192. 功能     : 取得FTP返回的信息
  193. 参数     : -
  194. 返回值   : -FTP返回信息字符串BUF地址
  195. 抛出异常 : -
  196. --------------------------------------------------------------------------------
  197. 备注     : -
  198. 典型用法 : -
  199. --------------------------------------------------------------------------------
  200. 作者     : 刘俊
  201. </PRE>
  202. *******************************************************************************/
  203. char* CFTPDownFile::GetFTPRecvMsg()
  204. {
  205. return this->m_chRecvFTPmessage;
  206. }
  207. /*! @SendUsername
  208. ********************************************************************************
  209. <PRE>
  210. 函数名   : SendUsername
  211. 功能     : FTP命令链接发送FTP用户名
  212. 参数     : -
  213. 返回值   : 发送成功返回 >0的整数,失败返回值 =0;
  214. 抛出异常 : -
  215. --------------------------------------------------------------------------------
  216. 备注     : -
  217. 典型用法 : -
  218. --------------------------------------------------------------------------------
  219. 作者     : 刘俊
  220. </PRE>
  221. *******************************************************************************/
  222. int CFTPDownFile::SendUsername()
  223. {
  224. //存放命令的字符串
  225. char chCommand[200] = {0};
  226. int iRes = 0;
  227. // 发送FTP用户名
  228. memset(chCommand, 0, sizeof(chCommand));
  229. strcpy(chCommand, "USER ");
  230. strcat(chCommand, this->m_chUserName);
  231. strcat(chCommand, "rn");
  232. // 发送
  233. iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  234. // 接受返回信息
  235. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  236. if (recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0) < 1)
  237. {
  238. return 0;
  239. }
  240. return iRes;
  241. }
  242. /*! @SendPWD
  243. ********************************************************************************
  244. <PRE>
  245. 函数名   : SendPWD
  246. 功能     : FTP命令链接发送FTP用户密码
  247. 参数     : -
  248. 返回值   : 发送成功返回 >0的整数,失败返回值 =0;
  249. 抛出异常 : -
  250. --------------------------------------------------------------------------------
  251. 备注     : -
  252. 典型用法 : -
  253. --------------------------------------------------------------------------------
  254. 作者     : 刘俊
  255. </PRE>
  256. *******************************************************************************/
  257. int CFTPDownFile::SendPWD()
  258. {
  259. //存放命令的字符串
  260. char chCommand[200] = {0};
  261. int iRes = 0;
  262. // 发送密码
  263. memset(chCommand, 0, sizeof(chCommand));
  264. strcpy(chCommand, "PASS ");
  265. strcat(chCommand, this->m_chFTPPwd);
  266. strcat(chCommand, "rn");
  267. // 发送
  268. iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  269. // 接受返回信息
  270. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  271. if (recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0) < 1)
  272. {
  273. return 0;
  274. }
  275. return iRes;
  276. }
  277. /*! @GetFTPfilesize
  278. ********************************************************************************
  279. <PRE>
  280. 函数名   : GetFTPfilesize
  281. 功能     : 取得所要下载的文件的大小
  282. 参数     : -
  283. 返回值   : 成功返回TRUE,否则返回FALSE
  284. 抛出异常 : -
  285. --------------------------------------------------------------------------------
  286. 备注     : -
  287. 典型用法 : -
  288. --------------------------------------------------------------------------------
  289. 作者     : 刘俊
  290. </PRE>
  291. *******************************************************************************/
  292. bool CFTPDownFile::GetFTPfilesize()
  293. {
  294. //存放命令的字符串
  295. char chCommand[200] = {0};
  296. // 设置按位下载
  297. memset(chCommand, 0, sizeof(chCommand));
  298. sprintf(chCommand,"TYPE Irn");
  299. send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  300. // 接受返回信息
  301. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  302. recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0);
  303. // 发送获取大小命令
  304. memset(chCommand, 0, sizeof(chCommand));
  305. strcpy(chCommand, "SIZE ");
  306. strcat(chCommand, this->m_chFTPfilename);
  307. strcat(chCommand, "rn");
  308. // 发送
  309. int iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  310. // 接受返回信息
  311. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  312. if (recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0) < 1)
  313. {
  314. return false;
  315. }
  316. char *pchSize = NULL;
  317. pchSize = strchr(this->m_chRecvFTPmessage, ' ');
  318. pchSize++;
  319. this->m_dFTPfilesize = strtod(pchSize, NULL);
  320. // 验证取得大小是否大于0
  321. if (fabs(this->m_dFTPfilesize) < 1) 
  322. {
  323. return false;
  324. }
  325. return true;
  326. }
  327. /*! @SetFTPdownfilename
  328. ********************************************************************************
  329. <PRE>
  330. 函数名   : SetFTPdownfilename
  331. 功能     : 设置下载文件名和下载到本地的文件名,包含路径
  332. 参数     : [IN]  pchFTPfilename : 端点服务器的FTP文件路径和文件名
  333.    [IN]  pchLocalfilename : 下载到本地后的文件名,包含本地文件路径
  334. 返回值   : -
  335. 抛出异常 : -
  336. --------------------------------------------------------------------------------
  337. 备注     : pchFTPfilename是相对于FTP根目录的路径及文件名不用报还FTP:\192.168.1.100这样的地址
  338. 典型用法 : SetFTPdownfilename("test.txt", "c:\test\test.txt");
  339. --------------------------------------------------------------------------------
  340. 作者     : 刘俊
  341. </PRE>
  342. *******************************************************************************/
  343. void CFTPDownFile::SetFTPdownfilename(const char *pchFTPfilename, const char *pchLocalfilename)
  344. {
  345. // 设置FTP文件名
  346. if(!pchFTPfilename)
  347. {
  348. return;
  349. }
  350. ZeroMemory(this->m_chFTPfilename, sizeof(this->m_chFTPfilename));
  351. strcpy(this->m_chFTPfilename, pchFTPfilename);
  352. // 设置本地文件名
  353. if(!pchLocalfilename)
  354. {
  355. return;
  356. }
  357. ZeroMemory(this->m_chLocalfilename, sizeof(this->m_chLocalfilename));
  358. strcpy(this->m_chLocalfilename, pchLocalfilename);
  359. }
  360. /*! @WriteLOG
  361. ********************************************************************************
  362. <PRE>
  363. 函数名   : WriteLOG
  364. 功能     : 在程序目录生成一个log.txt,记录LOG信息
  365. 参数     : [IN]  pLog : 要打印的LOG内容
  366. 返回值   : -
  367. 抛出异常 : -
  368. --------------------------------------------------------------------------------
  369. 备注     : 
  370. 典型用法 : 
  371. --------------------------------------------------------------------------------
  372. 作者     : 刘俊
  373. </PRE>
  374. *******************************************************************************/
  375. void CFTPDownFile::WriteLOG(const char *pLog)
  376. {
  377. // 取系统当前时间
  378. CString strTime = CTime::GetCurrentTime().Format("%Y-%m-%d %H:%M:%S");
  379. // 取系统当前日期
  380. CString strDate = CTime::GetCurrentTime().Format("%Y-%m-%d");
  381. CString strLog = CString(pLog);
  382. // 记录路径用
  383. char *pchPath = new char[1024];
  384. // 取得当前路径
  385. GetCurrentDirectory(1024,pchPath);
  386. CString strPath;
  387. strPath=pchPath;
  388. strPath=strPath + "\log.txt";
  389. // 打开或创建文件
  390. CStdioFile fLog(strPath, CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate);
  391. // 文件移到最后
  392. fLog.SeekToEnd();
  393. CString str;
  394. str += "n";
  395. str = strTime + " " + strLog + str;
  396. // 写入文件
  397. fLog.WriteString(str);
  398. // 关闭文件
  399. fLog.Close();
  400. // 释放资源
  401. strTime="";
  402. strDate="";
  403. delete [] pchPath;
  404. pchPath = NULL;
  405. strPath.Empty();
  406. strLog.Empty();
  407. }
  408. /*! @Startdown
  409. ********************************************************************************
  410. <PRE>
  411. 函数名   : Startdown
  412. 功能     : 开始下载指定的文件
  413. 参数     : [IN]  pchFTPfilename : 端点服务器的FTP文件路径和文件名
  414.    [IN]  pchLocalfilename : 下载到本地后的文件名,包含本地文件路径
  415.    [IN]  bRestart : 指定是否需要重新下载或者端点续传,TURE表示重新下载,FALSE表示断点续传
  416. 返回值   : 下载失败返回0,顺利完成下载返回1,文件已存在返回2
  417. 抛出异常 : -
  418. --------------------------------------------------------------------------------
  419. 备注     : pchFTPfilename是相对于FTP根目录的路径及文件名不用报还FTP:\192.168.1.100这样的地址
  420. 典型用法 : Startdown("test.txt", "c:\test\test.txt", false);
  421. --------------------------------------------------------------------------------
  422. 作者     : 刘俊
  423. </PRE>
  424. *******************************************************************************/
  425. short CFTPDownFile::Startdown(const char *pchFTPfilename, const char *pchLocalfilename, bool bRestart)
  426. {
  427. // 本地文件的大小
  428. double dLocalfilesize = 0.0;
  429. ULONGLONG ullLocalfilesize = 0;
  430. CFileException e;
  431. // 参数检查
  432. if(!pchFTPfilename)
  433. {
  434. return -1;
  435. }
  436. if(!pchLocalfilename)
  437. {
  438. return -1;
  439. }
  440. // 设置文件名
  441. this->SetFTPdownfilename(pchFTPfilename, pchLocalfilename);
  442. // 取得要下载文件的大小
  443. if (!this->GetFTPfilesize()) 
  444. {
  445. return 0;
  446. }
  447. // 判断文件路径是否存在,不存在的话则创建
  448. CString strLocalfilename = CString(pchLocalfilename);
  449. strLocalfilename.Replace("/", "\");
  450. this->CreatePath(strLocalfilename);
  451. // 如果重新下载
  452. if (bRestart) 
  453. {
  454. this->m_fLocalfile.Open(pchLocalfilename, CFile::modeCreate | CFile::modeWrite, &e);
  455. }
  456. // 断点续传
  457. else
  458. {
  459. this->m_fLocalfile.Open(pchLocalfilename, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite, &e);
  460. // 获得当地文件的大小
  461. dLocalfilesize = this->m_fLocalfile.SeekToEnd();
  462. // 如果不重新下载,且文件大小已经和服务器上医院大,则返回
  463. if (fabs(this->m_dFTPfilesize - dLocalfilesize) < 0.1) 
  464. {
  465. this->m_fLocalfile.Close();
  466. return 2;
  467. }
  468. // 如果文件大小超过FTP上的文件,则视为错误文件,重新下载
  469. else if (this->m_dFTPfilesize < dLocalfilesize) 
  470. {
  471. this->m_fLocalfile.Close();
  472. this->m_fLocalfile.Open(pchLocalfilename, CFile::modeCreate | CFile::modeWrite, &e);
  473. dLocalfilesize = 0;
  474. }
  475. else
  476. {
  477. ullLocalfilesize = dLocalfilesize;
  478. }
  479. }
  480. // 让FTP服务器进入监听状态
  481. this->SendFTPListenCommand();
  482. // 如果本地文件已有大小,且是断点续传
  483. if (1 < fabs(dLocalfilesize) && dLocalfilesize < this->m_dFTPfilesize) 
  484. {
  485. if (!bRestart) 
  486. {
  487. // 发送文件偏移指令
  488. this->SendFTPFileSeek(ullLocalfilesize);
  489. }
  490. }
  491. // 发送开始接收文件命令
  492. this->SendFTPstartsendfile();
  493. // 接收FTP文件,写入本地硬盘
  494. CWinThread *pThread = AfxBeginThread((AFX_THREADPROC)this->RevandWritefile, LPVOID(this));
  495. // 等待线程结束
  496. bool bQuit = false;
  497. while (!bQuit) 
  498. {
  499. MSG msg;
  500. int rc;
  501. // 等待下载线程结束
  502. rc = MsgWaitForMultipleObjects(1, &pThread->m_hThread, FALSE, INFINITE, QS_ALLINPUT); 
  503. if (rc == (WAIT_OBJECT_0)) 
  504. {
  505. // 下载完成,则退出
  506. break;
  507. }
  508. PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
  509. if (msg.message == WM_QUIT) 
  510. {
  511. // 停止下载
  512. this->m_bDown = false;
  513. }
  514. TranslateMessage(&msg);
  515. DispatchMessage(&msg);
  516. }
  517. // 关闭打开的文件
  518. if (this->m_fLocalfile.GetFileName() != "") 
  519. {
  520. this->m_fLocalfile.Close();
  521. }
  522. // 关闭SOCKET
  523. closesocket(this->m_sockDATA);
  524. closesocket(this->m_sockCOMMAND);
  525. return 1;
  526. }
  527. /*! @SendFTPListenCommand
  528. ********************************************************************************
  529. <PRE>
  530. 函数名   : SendFTPListenCommand
  531. 功能     : 发送FTP命令,让FTP服务器进入监听模式
  532. 参数     : -
  533. 返回值   : -
  534. 抛出异常 : -
  535. --------------------------------------------------------------------------------
  536. 备注     : 
  537. 典型用法 : 
  538. --------------------------------------------------------------------------------
  539. 作者     : 刘俊
  540. </PRE>
  541. *******************************************************************************/
  542. void CFTPDownFile::SendFTPListenCommand()
  543. {
  544. // 存放命令的字符串
  545. char chCommand[200] = {0};
  546. // 发送获取大小命令
  547. memset(chCommand, 0, sizeof(chCommand));
  548. strcpy(chCommand, "PASVrn");
  549. // 发送
  550. int iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  551. // 接受返回信息
  552. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  553. recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0);
  554. const char * pdir;
  555. pdir=strchr(this->m_chRecvFTPmessage,'(');
  556. pdir++;
  557. // 获取FTP服务器IP地址用
  558. union
  559. {
  560. unsigned char b[4];
  561. unsigned __int32 ui;
  562. }uip;
  563. union
  564. {
  565. unsigned char b[2];
  566. unsigned __int16 hi;
  567. }uport;
  568. unsigned __int32 u32[6];
  569. sscanf(pdir,"%u,%u,%u,%u,%u,%u",&u32[0],&u32[1],&u32[2],&u32[3],&u32[4],&u32[5],&u32[6]);
  570. uip.b[3]=(unsigned char)u32[0];
  571. uip.b[2]=(unsigned char)u32[1];
  572. uip.b[1]=(unsigned char)u32[2];
  573. uip.b[0]=(unsigned char)u32[3];
  574. uport.b[1]=(unsigned char)u32[4];
  575. uport.b[0]=(unsigned char)u32[5];
  576. // 初始化数据传输SOCKET
  577. this->m_sockDATA = socket(AF_INET,SOCK_STREAM,0);
  578. sockaddr_in myaddr;
  579. memset(&myaddr,0,sizeof(sockaddr_in));
  580. myaddr.sin_family = AF_INET;
  581. myaddr.sin_addr.S_un.S_addr = htonl(uip.ui);
  582. myaddr.sin_port = htons(uport.hi);
  583. //连接服务端
  584. iRes = 0;
  585. iRes = connect(this->m_sockDATA,(LPSOCKADDR)&myaddr,(int)sizeof(sockaddr_in));
  586. if (iRes == SOCKET_ERROR)
  587. {
  588. AfxMessageBox("建立接收数据链接失败");
  589. }
  590. }
  591. /*! @SendFTPFileSeek
  592. ********************************************************************************
  593. <PRE>
  594. 函数名   : SendFTPFileSeek
  595. 功能     : 发送文件偏移命令
  596. 参数     : [IN]  ullFilesize : 端点服务器的FTP文件偏移大小
  597. 返回值   : -
  598. 抛出异常 : -
  599. --------------------------------------------------------------------------------
  600. 备注     : -
  601. 典型用法 : -
  602. --------------------------------------------------------------------------------
  603. 作者     : 刘俊
  604. </PRE>
  605. *******************************************************************************/
  606. void CFTPDownFile::SendFTPFileSeek(ULONGLONG ullFilesize)
  607. {
  608. // 存放命令的字符串
  609. char chCommand[200] = {0};
  610. char chFilesize[100] = {0};
  611. _i64toa(ullFilesize, chFilesize, 10);
  612. // 发送获取大小命令
  613. memset(chCommand, 0, sizeof(chCommand));
  614. strcpy(chCommand, "REST ");
  615. strcat(chCommand, chFilesize);
  616. strcat(chCommand, "rn");
  617. // 发送
  618. int iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  619. // 接受返回信息
  620. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  621. recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0);
  622. }
  623. /*! @SendFTPstartsendfile
  624. ********************************************************************************
  625. <PRE>
  626. 函数名   : SendFTPstartsendfile
  627. 功能     : 发送开始接收文件命令
  628. 参数     : -
  629. 返回值   : -
  630. 抛出异常 : -
  631. --------------------------------------------------------------------------------
  632. 备注     : -
  633. 典型用法 : -
  634. --------------------------------------------------------------------------------
  635. 作者     : 刘俊
  636. </PRE>
  637. *******************************************************************************/
  638. void CFTPDownFile::SendFTPstartsendfile()
  639. {
  640. // 存放命令的字符串
  641. char chCommand[200] = {0};
  642. char chFilesize[100] = {0};
  643. // 发送获取大小命令
  644. memset(chCommand, 0, sizeof(chCommand));
  645. strcpy(chCommand, "RETR ");
  646. strcat(chCommand, this->m_chFTPfilename);
  647. strcat(chCommand, "rn");
  648. // 发送
  649. int iRes = send(this->m_sockCOMMAND, chCommand, strlen(chCommand), 0);
  650. // 接受返回信息
  651. ZeroMemory(this->m_chRecvFTPmessage, INTRECVMSGSIZE);
  652. recv(this->m_sockCOMMAND, this->m_chRecvFTPmessage, INTRECVMSGSIZE, 0);
  653. }
  654. /*! @RevandWritefile
  655. ********************************************************************************
  656. <PRE>
  657. 函数名   : RevandWritefile
  658. 功能     : 接收FTP文件,写入本地硬盘
  659. 参数     : [IN]  pParam : 该类的this指针
  660. 返回值   : -
  661. 抛出异常 : -
  662. --------------------------------------------------------------------------------
  663. 备注     : -
  664. 典型用法 : -
  665. --------------------------------------------------------------------------------
  666. 作者     : 刘俊
  667. </PRE>
  668. *******************************************************************************/
  669. UINT CFTPDownFile::RevandWritefile(LPVOID pParam)
  670. {
  671. // 还原this指针
  672. CFTPDownFile *pointer;  
  673. pointer   =   (CFTPDownFile*)pParam;
  674. // 设定下载缓冲区大小
  675. const int BUFFSIZE = 8*1024;
  676. char revbuf[BUFFSIZE] = {0};
  677. // 接收返回值
  678. int iresult = 0;
  679. // 设置接收状态
  680. pointer->m_bDown = true;
  681. // 接收大小初始化
  682. pointer->m_dRecv = 0;
  683. // 开始接收数据
  684. while(true)
  685. {
  686. // 重置BUFF区
  687. memset(revbuf,0,BUFFSIZE);
  688. // 重置接收返回值
  689. iresult = 0;
  690. // 接收
  691. iresult = recv(pointer->m_sockDATA , revbuf, BUFFSIZE, 0);
  692. //累加记录下载了多少字节
  693.         pointer->m_dRecv = pointer->m_dRecv + iresult;
  694. // 如果接收完毕,停止接收
  695. if(iresult == 0)
  696. {
  697. break;
  698. }
  699. // 写入文件
  700. pointer->m_fLocalfile.Write(revbuf, iresult);
  701. // 如果用户停止下载
  702. if (!pointer->m_bDown) 
  703. {
  704. // 关闭资源
  705. pointer->m_fLocalfile.Close();
  706. closesocket(pointer->m_sockDATA);
  707. closesocket(pointer->m_sockCOMMAND);
  708. break;
  709. }
  710. }
  711. return 0;
  712. }
  713. /*! @Stopdown
  714. ********************************************************************************
  715. <PRE>
  716. 函数名   : Stopdown
  717. 功能     : 停止下载
  718. 参数     : -
  719. 返回值   : -
  720. 抛出异常 : -
  721. --------------------------------------------------------------------------------
  722. 备注     : -
  723. 典型用法 : -
  724. --------------------------------------------------------------------------------
  725. 作者     : 刘俊
  726. </PRE>
  727. *******************************************************************************/
  728. void CFTPDownFile::Stopdown()
  729. {
  730. // 修改下载状态
  731. this->m_bDown = false;
  732. }
  733. // 检查文件路径是否存在,不存在的话则创建
  734. /*! @CreatePath
  735. ********************************************************************************
  736. <PRE>
  737. 函数名   : CreatePath
  738. 功能     : 检查文件路径是否存在,不存在的话则创建
  739. 参数     : [IN]  strPath : 要检查的路径
  740. 返回值   : -
  741. 抛出异常 : -
  742. --------------------------------------------------------------------------------
  743. 备注     : -
  744. 典型用法 : -
  745. --------------------------------------------------------------------------------
  746. 作者     : 刘俊
  747. </PRE>
  748. *******************************************************************************/
  749. void CFTPDownFile::CreatePath(CString strPath)
  750. {
  751. // 要检查的目录路径,从最顶级开始
  752. CString strTemp;
  753. int nPos = 1;
  754. while (nPos < strPath.GetLength()) 
  755. {
  756. nPos++;
  757. nPos = strPath.Find("\", nPos);
  758. if (-1 == nPos) 
  759. {
  760. return;
  761. }
  762. // 逐级取得路径
  763. CString strTemp = strPath.Left(nPos);
  764. // 检查是否存在该路径
  765. if (!PathFileExists(strTemp)) 
  766. {
  767. // 创建目录
  768. CreateDirectory(strTemp, NULL);
  769. }
  770. }
  771. }