Ftp的断点下载实现

思路:首先获取本地临时文件的大小,在通过FTp的REST命令获取远程文件的偏移,然后再RETR命令在偏移处下载。while循环对比本地文件和远程文件的字节大小,如此

不断的反复以上过程,直到远程文件字节和本地文件字节一样,退出循环,下载完成。

 1    long remote_file_size = m_ftp->getFileLength(remoteFileName.toStdString());
 2     long recvSize = 0;
 3
 4     if (remote_file_size == -1 )
 5     {
 6         return false;
 7     }
 8
 9     int conn_count = 10;
10
11     while (conn_count != 0 && local_file_size != remote_file_size)
12     {
13         recvSize = m_ftp->Get2(remoteFileName.toStdString(), tmp_save_file_name.toStdString(), local_file_size);
14         if (recvSize <= 0)
15         {
16             msleep(50);
17             if (!reConnect())
18             {
19                 break;
20             }
21             conn_count--;
22         }
23
24         local_file_size = getLocalFileSize(tmp_save_file_name);
25     }

1 FTP_API CFTP::Get2(const std::string &strRemoteFile, const std::string &strLocalFile, const int pos)
2 {
3     return downLoad2(strRemoteFile, strLocalFile, pos);
4 }

 1 FTP_API CFTP::downLoad2(const std::string &strRemoteFile, const std::string& strLocalFile, const int pos /*= 0*/, const unsigned int length /*= 0*/)
 2 {
 3     assert(length >= 0);
 4
 5     FILE *file = NULL;
 6     unsigned long nDataLen = FTP_DEFAULT_BUFFER;
 7     char strPos[MAX_PATH] = { 0 };
 8     int data_fd = socket(AF_INET, SOCK_STREAM, 0);
 9
10     assert(data_fd != -1);
11
12     if ((length != 0) && (length < nDataLen))
13     {
14         nDataLen = length;
15     }
16     char *dataBuf = new char[nDataLen];
17     if (dataBuf == NULL)
18     {
19         return -1;
20     }
21     memset(dataBuf, 0, sizeof(dataBuf));
22
23     //assert(dataBuf != NULL);
24
25     sprintf(strPos, "%d", pos);
26
27     if (createDataLink(data_fd) < 0)
28     {
29         trace("@@@@ Create Data Link error!!!\n");
30         return -1;
31     }
32
33
34     std::string strCmdLine = parseCommand(FTP_COMMAND_DOWNLOAD_POS, strPos);//param 1 为REST命令
35     if (Send(m_cmdSocket, strCmdLine) < 0)
36     {
37         return -1;
38     }
39     trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());
40
41
42     strCmdLine = parseCommand(FTP_COMMAND_DOWNLOAD_FILE, strRemoteFile);//param 1为RETR命令
43
44     if (Send(m_cmdSocket, strCmdLine) < 0)
45     {
46         return -1;
47     }
48
49     std::string strResponse = serverResponse(m_cmdSocket);
50     trace("@@@@Response: %s\n", strResponse.c_str());
51
52     file = createLocalFile2(std::string(strLocalFile));
53     assert(file != NULL);
54
55     int len = 0;
56     int nReceiveLen = 0;
57     while ((len = getData(data_fd, dataBuf, nDataLen)) > 0)
58     {
59         nReceiveLen += len;
60
61         int num = fwrite(dataBuf, 1, len, file);
62         memset(dataBuf, 0, sizeof(dataBuf));
63
64
65         trace("Num:%d, nReceiveLen:%d\n", num, nReceiveLen);
66
67     }
68
69     Close(data_fd);
70     fclose(file);
71     delete[]dataBuf;
72
73     return nReceiveLen;
74
75 }

references:

http://blog.chinaunix.net/uid-7377299-id-112977.html

时间: 2024-11-05 13:44:10

Ftp的断点下载实现的相关文章

C#实现http断点下载

我们寄希望于万能的解决方案,但是现实的情况总是很糟糕.在软件编程的世界中,技术分散的情况尤为严重,且不说各种语言拥有的优势不能融合,单就一门语言而言,就拥有众多的技术和相关技术需要学习.网络编程就是这种情况,tcp.udp.http和soap相关的协议(ftp不会玩),我们不得不在同一个应用中使用不同难以整合的技术.tcp讲究精准,udp讲究性能,http对于穿越外网有这天然的优势,soap对于讲究编程模型的人来说是福音. 其实断点续传,众多技术都可以实现,只是想难易程度而以.经过比较分析发现,

python之实现ftp上传下载代码(含错误处理)

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之实现ftp上传下载代码(含错误处理) #http://www.cnblogs.com/kaituorensheng/p/4480512.html#_label2 import ftplib import socket import os def ftpconnect(ftp_info): try: ftp = ftplib.FTP(ftp_info[0]) except (socket.er

多线程断点下载原理(java代码实例演示)

其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载,首先:你必须明白第一点,那么就是,什么是多线程下载,该知识点可以查看本博客上一篇文章,Android之多线程下载原理,断点下载呢,其实就是在这个的基础之上添加了一些东西,那么添加了什么东西了,现在来做一个详细的了解. 1.在下载的过程中,边下载,变用一个文件来记录下载的位置,也就是下载了多少的数据 1.创建文件 2.记录下载多少数据 3.存储数据 2.第二次下载的时候,就去读取文件中是否存有数据,读取上次下载的位置

断点下载的请求头设置

断点下载的时候,需要设置请求头的“Range” 表示头100个字节:Range:bytes=0-99 表示第二个100个字节:Range:bytes=100-199 表示最后100个字节:Range:bytes=-100 表示200个字节以后的所有字节:Range:bytes=200-

Java之多线程断点下载的实现

RandomAccessFile类: 此类的实例支持对随机訪问文件的读取和写入.随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组.光标或索引,称为文件指针.输入操作从文件指针開始读取字节.并随着对字节的读取而前移此文件指针. 假设随机訪问文件以读取/写入模式创建,则输出操作也可用.输出操作从文件指针開始写入字节.并随着对字节的写入而前移此文件指针.写入隐含数组的当前末尾之后的输出操作导致该数组扩展.该文件指针能够通过 getFilePointer 方法读取.

python之模块ftplib(实现ftp上传下载代码)

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块ftplib(实现ftp上传下载代码) #需求:实现ftp上传下载代码(不含错误处理) from ftplib import FTP def ftpconnect(): ftp_server='ftp.python.org' ftp=FTP() ftp.set_debuglevel(2)#打开调式级别2 ftp.connect(ftp_server,21) ftp.login('',''

Android的断点下载详细分析二

由于一篇blog写不完,这里是接着上一篇blog的. 写完了MVC中的View,写着我们需要考虑Control层了,他的任务是在后台利用多线程实现断点下载. 先看源码: public class FileDownloader { /* TAG,便于调试 */ private static final String TAG = "FileDownloader"; /* 上下文 */ private Context context; /* 用于对数据库的操作 */ private File

ios ASI 断点下载

ASI的断点下载技术非常的好用, 任何有下载功能的应用都可以试试: //1.创建请求对象 NSURL *url=[NSURL URLWithString:@"在这里输入你的下载链接"]; ASIHTTPRequest *request=[ASIHTTPRequest requestWithURL:url]; //2.设置下载文件保存的路径 NSString *cachepath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirecto

Android/java http多线程断点下载(附源码)

先看下项目结构: http多线程断点下载涉及到 数据库,多线程和http请求等几个模块,东西不是很多,想弄清楚也不是很困难,接下来我和大家分享下我的做法. 一.先看MainActivity.java 成员变量,主要是一些下载过程的变量和handler private String path = "http://192.168.1.3:8080/wanmei/yama.apk"; private String sdcardPath; private int threadNum = 5;