Ftp的断点下载实现
推荐一款ftp客户端工具:iis7服务器管理工具
IIS7服务管理器,它最优秀的功能就是可以批量管理,适用于Windows系统,Linux系统和VPS服务器等,能极大的提高站长及服务器运维人员工作效率。
同时iis7服务器管理工具还是vnc客户端,服务器真正实现了一站式管理,可谓是非常方便。ftp下载工具是一个免费开源的FTP客户端软件,分为客户端版本和服务器版本,具备所有的FTP软件功能。它还可以管理各系统服务器(win系统和linux)除此之外,还可以管理vnc,可谓非常强大,关键是免费的!
在众多好用实用的功能当中,最大的亮点还是属定时上传下载的强大功能了,它可以定时备份,自动更新等,大家都在用,还等什么呢~
下载地址:iis7服务器管理工具
######################################## 以下才是正文###############################################################################################
思路:首先获取本地临时文件的大小,在通过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